1 /*
2 * SDIO driver for XRadio drivers
3 *
4 * Copyright (c) 2013
5 * Xradio Technology Co., Ltd. <www.xradiotech.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12 #include <generated/uapi/linux/version.h>
13 #include <linux/module.h>
14 #include <linux/wait.h>
15 #include <linux/gpio.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/delay.h>
18 #include <linux/mmc/host.h>
19 #include <linux/mmc/sdio_func.h>
20 #include <linux/mmc/card.h>
21 #include <linux/mmc/sdio.h>
22 #include <linux/spinlock.h>
23 #include <net/mac80211.h>
24
25 #include "platform.h"
26 #include "xradio.h"
27 #include "sbus.h"
28
29 /* sdio vendor id and device id*/
30 #define SDIO_VENDOR_ID_XRADIO 0x0020
31 #define SDIO_DEVICE_ID_XRADIO 0x2281
32 #define SDIO_VENDOR_ID_XR829 0x0A9E
33 #define SDIO_DEVICE_ID_XR829 0x2282
34
35 static const struct sdio_device_id xradio_sdio_ids[] = {
36 {SDIO_DEVICE(SDIO_VENDOR_ID_XRADIO, SDIO_DEVICE_ID_XRADIO)},
37 {SDIO_DEVICE(SDIO_VENDOR_ID_XR829, SDIO_DEVICE_ID_XR829)},
38 /*{ SDIO_DEVICE(SDIO_ANY_ID, SDIO_ANY_ID) }, */
39 { /* end: all zeroes */ },
40 };
41
42 /* sbus_ops implemetation */
sdio_data_read(struct sbus_priv * self,unsigned int addr,void * dst,int count)43 static int sdio_data_read(struct sbus_priv *self, unsigned int addr,
44 void *dst, int count)
45 {
46 return sdio_memcpy_fromio(self->func, dst, addr, count);
47 }
48
sdio_data_write(struct sbus_priv * self,unsigned int addr,const void * src,int count)49 static int sdio_data_write(struct sbus_priv *self, unsigned int addr,
50 const void *src, int count)
51 {
52 return sdio_memcpy_toio(self->func, addr, (void *)src, count);
53 }
54
sdio_lock(struct sbus_priv * self)55 static void sdio_lock(struct sbus_priv *self)
56 {
57 sdio_claim_host(self->func);
58 }
59
sdio_unlock(struct sbus_priv * self)60 static void sdio_unlock(struct sbus_priv *self)
61 {
62 sdio_release_host(self->func);
63 }
64
sdio_align_len(struct sbus_priv * self,size_t size)65 static size_t sdio_align_len(struct sbus_priv *self, size_t size)
66 {
67 return sdio_align_size(self->func, size);
68 }
69
sdio_set_blk_size(struct sbus_priv * self,size_t size)70 static int sdio_set_blk_size(struct sbus_priv *self, size_t size)
71 {
72 sbus_printk(XRADIO_DBG_NIY, "set blocksize=%zu\n", size);
73 return sdio_set_block_size(self->func, size);
74 }
75
sdio_cur_blk_size(struct sbus_priv * self)76 static size_t sdio_cur_blk_size(struct sbus_priv *self)
77 {
78 return (size_t)self->func->cur_blksize;
79 }
80
81 #ifndef CONFIG_XRADIO_USE_GPIO_IRQ
sdio_irq_handler(struct sdio_func * func)82 static void sdio_irq_handler(struct sdio_func *func)
83 {
84 struct sbus_priv *self = sdio_get_drvdata(func);
85 unsigned long flags;
86 sbus_printk(XRADIO_DBG_TRC, "%s\n", __func__);
87
88 SYS_BUG(!self);
89 spin_lock_irqsave(&self->lock, flags);
90 if (self->irq_handler)
91 self->irq_handler(self->irq_priv);
92 spin_unlock_irqrestore(&self->lock, flags);
93 }
94 #endif
95
sdio_irq_subscribe(struct sbus_priv * self,sbus_irq_handler handler,void * priv)96 static int sdio_irq_subscribe(struct sbus_priv *self,
97 sbus_irq_handler handler,
98 void *priv)
99 {
100 int ret = 0;
101 unsigned long flags;
102
103
104 if (!handler)
105 return -EINVAL;
106 sbus_printk(XRADIO_DBG_TRC, "%s\n", __func__);
107
108 spin_lock_irqsave(&self->lock, flags);
109 self->irq_priv = priv;
110 self->irq_handler = handler;
111 spin_unlock_irqrestore(&self->lock, flags);
112
113 sdio_claim_host(self->func);
114 #ifndef CONFIG_XRADIO_USE_GPIO_IRQ
115 ret = sdio_claim_irq(self->func, sdio_irq_handler);
116 if (ret) {
117 sbus_printk(XRADIO_DBG_ERROR, "%s:sdio_claim_irq failed(%d).\n",
118 __func__, ret);
119
120 } else {
121 sbus_printk(XRADIO_DBG_NIY, "%s:sdio_claim_irq success.\n", __func__);
122 }
123 #else
124 ret = xradio_request_gpio_irq(&(self->func->dev), self);
125 if (!ret) {
126 /* Hack to access Fuction-0 */
127 u8 cccr;
128 int func_num = self->func->num;
129 sbus_printk(XRADIO_DBG_NIY, "%s:xradio_request_gpio_irq success.\n",
130 __func__);
131
132 self->func->num = 0;
133 cccr = sdio_readb(self->func, SDIO_CCCR_IENx, &ret);
134 cccr |= BIT(0); /* Master interrupt enable ... */
135 cccr |= BIT(func_num); /* ... for our function */
136 sdio_writeb(self->func, cccr, SDIO_CCCR_IENx, &ret);
137 if (ret) {
138 xradio_free_gpio_irq(&(self->func->dev), self);
139 if (MCI_CHECK_READY(self->func->card->host, 1000) != 0)
140 sbus_printk(XRADIO_DBG_ERROR,
141 "%s:MCI_CHECK_READY timeout\n", __func__);
142 }
143 /* Restore the WLAN function number */
144 self->func->num = func_num;
145 } else {
146 sbus_printk(XRADIO_DBG_ERROR, "%s:xradio_request_gpio_irq failed(%d).\n",
147 __func__, ret);
148 }
149 #endif
150 sdio_release_host(self->func);
151
152 return ret;
153 }
154
sdio_irq_unsubscribe(struct sbus_priv * self)155 static int sdio_irq_unsubscribe(struct sbus_priv *self)
156 {
157 int ret = 0;
158 unsigned long flags;
159
160 sbus_printk(XRADIO_DBG_TRC, "%s\n", __func__);
161
162 if (!self->irq_handler) {
163 sbus_printk(XRADIO_DBG_ERROR, "%s:irq_handler is NULL!\n", __func__);
164 return 0;
165 }
166
167 #ifndef CONFIG_XRADIO_USE_GPIO_IRQ
168 sdio_claim_host(self->func);
169 ret = sdio_release_irq(self->func);
170 sdio_release_host(self->func);
171 #else
172 xradio_free_gpio_irq(&(self->func->dev), self);
173 #endif /*CONFIG_XRADIO_USE_GPIO_IRQ*/
174
175 spin_lock_irqsave(&self->lock, flags);
176 self->irq_priv = NULL;
177 self->irq_handler = NULL;
178 spin_unlock_irqrestore(&self->lock, flags);
179
180 return ret;
181 }
182
sdio_pm(struct sbus_priv * self,bool suspend)183 static int sdio_pm(struct sbus_priv *self, bool suspend)
184 {
185 int ret = 0;
186 if (suspend) {
187 /* Notify SDIO that XRADIO will remain powered during suspend */
188 ret = sdio_set_host_pm_flags(self->func, MMC_PM_KEEP_POWER);
189 if (ret)
190 sbus_printk(XRADIO_DBG_ERROR,
191 "Error setting SDIO pm flags: %i\n", ret);
192 }
193
194 return ret;
195 }
196
sdio_reset(struct sbus_priv * self)197 static int sdio_reset(struct sbus_priv *self)
198 {
199 return 0;
200 }
201
202 static struct sbus_ops sdio_sbus_ops = {
203 .sbus_data_read = sdio_data_read,
204 .sbus_data_write = sdio_data_write,
205 .lock = sdio_lock,
206 .unlock = sdio_unlock,
207 .align_size = sdio_align_len,
208 .set_block_size = sdio_set_blk_size,
209 .get_block_size = sdio_cur_blk_size,
210 .irq_subscribe = sdio_irq_subscribe,
211 .irq_unsubscribe = sdio_irq_unsubscribe,
212 .power_mgmt = sdio_pm,
213 .reset = sdio_reset,
214 };
215 static struct sbus_priv sdio_self;
216
217 #if (defined(CONFIG_XRADIO_DEBUGFS))
218 u32 dbg_sdio_clk;
sdio_set_clk(struct sdio_func * func,u32 clk)219 static int sdio_set_clk(struct sdio_func *func, u32 clk)
220 {
221 if (func) {
222 /* set min to 1M */
223 if (func->card->host->ops->set_ios && clk >= 1000000) {
224 sdio_claim_host(func);
225 func->card->host->ios.clock = (clk < 50000000) ? clk : 50000000;
226 func->card->host->ops->set_ios(func->card->host,
227 &func->card->host->ios);
228 sdio_release_host(func);
229 sbus_printk(XRADIO_DBG_ALWY, "%s:change mmc clk=%d\n", __func__,
230 func->card->host->ios.clock);
231 } else {
232 sbus_printk(XRADIO_DBG_ALWY, "%s:fail change mmc clk=%d\n",
233 __func__, clk);
234 }
235 }
236 return 0;
237 sbus_printk(XRADIO_DBG_TRC, "%s\n", __func__);
238 }
239 #endif
240
241 /* Probe Function to be called by SDIO stack when device is discovered */
sdio_probe(struct sdio_func * func,const struct sdio_device_id * id)242 static int sdio_probe(struct sdio_func *func,
243 const struct sdio_device_id *id)
244 {
245 sbus_printk(XRADIO_DBG_ALWY, "XRadio Device:sdio clk=%d\n",
246 func->card->host->ios.clock);
247 sbus_printk(XRADIO_DBG_NIY, "sdio func->class=%x\n", func->class);
248 sbus_printk(XRADIO_DBG_NIY, "sdio_vendor: 0x%04x\n", func->vendor);
249 sbus_printk(XRADIO_DBG_NIY, "sdio_device: 0x%04x\n", func->device);
250 sbus_printk(XRADIO_DBG_NIY, "Function#: 0x%04x\n", func->num);
251 sbus_printk(XRADIO_DBG_NIY, "max_blksize:%u\n", func->max_blksize);
252 sbus_printk(XRADIO_DBG_NIY, "cur_blksize:%u\n", func->cur_blksize);
253
254 #if (defined(CONFIG_XRADIO_DEBUGFS))
255 if (dbg_sdio_clk)
256 sdio_set_clk(func, dbg_sdio_clk);
257 #endif
258
259 #if 0 /*for odly and sdly debug.*/
260
261 #ifdef __io_address
262 #undef __io_address
263 #endif
264
265 #define __io_address(_n) (0xf0000000+(_n))
266
267 {
268 u32 sdio_param = 0;
269 u32 s_dly = 7;
270
271 u32 smc_no = 0x1;
272
273 sdio_param = readl(__io_address(0x01c20088 + 0x4 * smc_no));
274
275 sbus_printk(XRADIO_DBG_ALWY, "%s[read ]: 0x01c20088=0x%08x\n",
276 __func__, sdio_param);
277
278 sdio_param &= ~(0xf << 8);
279 sdio_param |= 3 << 8;
280 sdio_param &= ~(0xf << 20);
281 sdio_param |= s_dly << 20;
282
283 writel(sdio_param, __io_address(0x01c20088 + 0x4 * smc_no));
284 sbus_printk(XRADIO_DBG_ALWY, "%s[write]: 0x01c20088=0x%08x\n",
285 __func__, sdio_param);
286
287 sdio_param = readl(__io_address(0x01c20088 + 0x4 * smc_no));
288
289 sbus_printk(XRADIO_DBG_ALWY, "%s[read2]: 0x01c20088=0x%08x\n",
290 __func__, sdio_param);
291
292 }
293
294 #endif
295
296 sdio_self.func = func;
297 sdio_self.func->card->quirks |= MMC_QUIRK_BROKEN_BYTE_MODE_512;
298 sdio_set_drvdata(func, &sdio_self);
299 sdio_claim_host(func);
300 sdio_enable_func(func);
301 sdio_release_host(func);
302
303 sdio_self.load_state = SDIO_LOAD;
304 wake_up(&sdio_self.init_wq);
305
306 return 0;
307 }
308
309 /* Disconnect Function to be called by SDIO stack when
310 * device is disconnected */
sdio_remove(struct sdio_func * func)311 static void sdio_remove(struct sdio_func *func)
312 {
313 struct sbus_priv *self = sdio_get_drvdata(func);
314 sbus_printk(XRADIO_DBG_NIY, "%s\n", __func__);
315 sdio_claim_host(func);
316 sdio_disable_func(func);
317 sdio_release_host(func);
318 sdio_set_drvdata(func, NULL);
319 if (self) {
320 self->func = NULL;
321 self->load_state = SDIO_UNLOAD;
322 wake_up(&sdio_self.init_wq);
323 }
324 }
325
326 #if 0
327 static int sdio_suspend(struct device *dev)
328 {
329 int ret = 0;
330 sbus_printk(XRADIO_DBG_NIY, "%s\n", __func__);
331 #ifdef CONFIG_XRADIO_ETF
332 ret = xradio_etf_suspend();
333 if (ret) {
334 sbus_printk(XRADIO_DBG_ERROR,
335 "xradio_etf_suspend failed(%d)\n", ret);
336 }
337 #endif
338 return ret;
339 }
340 #endif
341
342 /*
343 * wifi device need to use sdio while working, so sdio should not suspend before wifi device.
344 * However, sdio may suspend before wifi device, which is controlled by system.so we need to
345 * keep sdio working.The better way is register sdio device as the father device of wifi device,
346 * so it will suspend wifi device first
347 */
348 extern struct xradio_common *g_hw_priv;
sdio_suspend(struct device * dev)349 static int sdio_suspend(struct device *dev)
350 {
351 int ret = 0;
352 sbus_printk(XRADIO_DBG_NIY, "%s\n", __func__);
353
354 if (g_hw_priv && (g_hw_priv->exit_sync == true)) {
355 sbus_printk(XRADIO_DBG_WARN, "Don't suspend because xradio is exiting\n");
356 return -EBUSY;
357 }
358
359 #ifdef CONFIG_XRADIO_ETF
360 ret = xradio_etf_suspend();
361 if (!ret) {
362 struct sdio_func *func = dev_to_sdio_func(dev);
363 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
364 if (ret) {
365 xradio_etf_resume();
366 sbus_printk(XRADIO_DBG_ERROR, "set MMC_PM_KEEP_POWER error\n");
367 }
368 } else {
369 sbus_printk(XRADIO_DBG_ERROR, "xradio_etf_suspend failed\n");
370 }
371 #else
372 struct sdio_func *func = dev_to_sdio_func(dev);
373 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
374 if (ret) {
375 sbus_printk(XRADIO_DBG_ERROR, "set MMC_PM_KEEP_POWER error\n");
376 }
377 #endif
378
379 return ret;
380 }
381
sdio_resume(struct device * dev)382 static int sdio_resume(struct device *dev)
383 {
384 sbus_printk(XRADIO_DBG_NIY, "%s\n", __func__);
385 #ifdef CONFIG_XRADIO_ETF
386 xradio_etf_resume();
387 #endif
388 return 0;
389 }
390
391 static const struct dev_pm_ops sdio_pm_ops = {
392 .suspend = sdio_suspend,
393 .resume = sdio_resume,
394 };
395
396 static struct sdio_driver sdio_driver = {
397 .name = "xradio_wlan",
398 .id_table = xradio_sdio_ids,
399 .probe = sdio_probe,
400 .remove = sdio_remove,
401 .drv = {
402 .pm = &sdio_pm_ops,
403 }
404 };
405
406 /* Init Module function -> Called by insmod */
sbus_sdio_init(struct sbus_ops ** sdio_ops,struct sbus_priv ** sdio_priv)407 struct device *sbus_sdio_init(struct sbus_ops **sdio_ops,
408 struct sbus_priv **sdio_priv)
409 {
410 int ret = 0;
411 struct device *sdio_dev = NULL;
412 sbus_printk(XRADIO_DBG_TRC, "%s\n", __func__);
413
414 /*initialize sbus_priv.*/
415 if (sdio_self.load_state == SDIO_UNLOAD) {
416 spin_lock_init(&sdio_self.lock);
417 init_waitqueue_head(&sdio_self.init_wq);
418
419 /*module power up.*/
420 xradio_wlan_power(1);
421 mdelay(100);
422 /*detect sdio card.*/
423 xradio_sdio_detect(1);
424
425 /*setup sdio driver.*/
426 ret = sdio_register_driver(&sdio_driver);
427 if (ret) {
428 sbus_printk(XRADIO_DBG_ERROR, "sdio_register_driver failed!\n");
429 return NULL;
430 }
431
432 if (wait_event_timeout(sdio_self.init_wq,
433 sdio_self.load_state == SDIO_LOAD, 2*HZ) <= 0) {
434 sdio_unregister_driver(&sdio_driver);
435 sdio_self.load_state = SDIO_UNLOAD;
436
437 xradio_wlan_power(0); /*power down.*/
438 xradio_sdio_detect(0);
439 sbus_printk(XRADIO_DBG_ERROR, "sdio probe timeout!\n");
440 return NULL;
441 }
442 }
443
444 sdio_self.val32_r = (u32 *)kmalloc(sizeof(u32), GFP_KERNEL);
445 sdio_self.val32_w = (u32 *)kmalloc(sizeof(u32), GFP_KERNEL);
446 if (!sdio_self.val32_r || !sdio_self.val32_w) {
447 xradio_dbg(XRADIO_DBG_ERROR,
448 "%s, val32: kmalloc error!\n",
449 __func__);
450 return NULL;
451 }
452
453 /*register sbus.*/
454 sdio_dev = &(sdio_self.func->dev);
455 *sdio_ops = &sdio_sbus_ops;
456 *sdio_priv = &sdio_self;
457
458 return sdio_dev;
459 }
460
461 /* SDIO Driver Unloading */
sbus_sdio_deinit(void)462 void sbus_sdio_deinit(void)
463 {
464 int retrycnt = 0;
465 sbus_printk(XRADIO_DBG_TRC, "%s\n", __func__);
466 if (sdio_self.load_state != SDIO_UNLOAD) {
467 xradio_wlan_power(0); /*power down.*/
468
469 retry: xradio_sdio_detect(0);
470 if (wait_event_interruptible_timeout(sdio_self.init_wq,
471 sdio_self.load_state == SDIO_UNLOAD, 2*HZ) <= 0) {
472 sbus_printk(XRADIO_DBG_ERROR, "%s remove timeout!\n", __func__);
473
474 if (++retrycnt <= 2)
475 goto retry;
476 }
477 sdio_unregister_driver(&sdio_driver);
478 kfree(sdio_self.val32_r);
479 kfree(sdio_self.val32_w);
480 memset(&sdio_self, 0, sizeof(sdio_self));
481 msleep(5);
482 } else {
483 sbus_printk(XRADIO_DBG_ERROR, "%s sdio did not init!\n", __func__);
484 }
485 }
486