• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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