4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <linux/kernel.h>
35 #include <linux/module.h>
36 #include <linux/version.h>
37 #include <linux/moduleparam.h>
38 #include <linux/delay.h>
39 #include <linux/interrupt.h>
40 #include <linux/slab.h>
41 #include <linux/types.h>
42 #include <linux/dma-mapping.h>
43 #include <linux/platform_device.h>
44 #include <linux/i2c/twl4030.h>
45 #include <linux/errno.h>
46 #include <linux/clk.h>
47 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
48 #include <plat/hardware.h>
49 #include <plat/board.h>
50 #include <plat/clock.h>
53 #include <plat/resource.h>
54 #define IO_ADDRESS(pa) OMAP2_L4_IO_ADDRESS(pa)
56 #include <mach/hardware.h>
57 #include <mach/board.h>
58 #include <mach/clock.h>
61 #include <mach/resource.h>
63 typedef void *TI_HANDLE;
64 #include "host_platform.h"
65 #include "SdioDrvDbg.h"
68 /* #define TI_SDIO_DEBUG */
70 #ifndef CONFIG_MMC_EMBEDDED_SDIO
72 #define SDIOWQ_NAME "sdio_wq"
75 * HSMMC Address and DMA Settings
77 static unsigned long TIWLAN_MMC_CONTROLLER = 2; /* MMC3 */
78 static unsigned long TIWLAN_MMC_CONTROLLER_BASE_ADDR = OMAP_HSMMC3_BASE;
79 #define TIWLAN_MMC_CONTROLLER_BASE_SIZE 512
80 #define TIWLAN_MMC_MAX_DMA 8192
81 static unsigned long TIWLAN_MMC_DMA_TX = OMAP34XX_DMA_MMC3_TX;
82 static unsigned long TIWLAN_MMC_DMA_RX = OMAP34XX_DMA_MMC3_RX;
83 static unsigned long OMAP_MMC_IRQ = INT_MMC3_IRQ;
85 #define OMAP_MMC_MASTER_CLOCK 96000000
87 * HSMMC Host Controller Registers
89 #define OMAP_HSMMC_SYSCONFIG 0x0010
90 #define OMAP_HSMMC_SYSSTATUS 0x0014
91 #define OMAP_HSMMC_CSRE 0x0024
92 #define OMAP_HSMMC_SYSTEST 0x0028
93 #define OMAP_HSMMC_CON 0x002C
94 #define OMAP_HSMMC_BLK 0x0104
95 #define OMAP_HSMMC_ARG 0x0108
96 #define OMAP_HSMMC_CMD 0x010C
97 #define OMAP_HSMMC_RSP10 0x0110
98 #define OMAP_HSMMC_RSP32 0x0114
99 #define OMAP_HSMMC_RSP54 0x0118
100 #define OMAP_HSMMC_RSP76 0x011C
101 #define OMAP_HSMMC_DATA 0x0120
102 #define OMAP_HSMMC_PSTATE 0x0124
103 #define OMAP_HSMMC_HCTL 0x0128
104 #define OMAP_HSMMC_SYSCTL 0x012C
105 #define OMAP_HSMMC_STAT 0x0130
106 #define OMAP_HSMMC_IE 0x0134
107 #define OMAP_HSMMC_ISE 0x0138
108 #define OMAP_HSMMC_AC12 0x013C
109 #define OMAP_HSMMC_CAPA 0x0140
110 #define OMAP_HSMMC_CUR_CAPA 0x0148
111 #define OMAP_HSMMC_REV 0x01FC
113 #define VS18 (1 << 26)
114 #define VS30 (1 << 25)
115 #define SRA (1 << 24)
116 #define SDVS18 (0x5 << 9)
117 #define SDVS30 (0x6 << 9)
118 #define SDVSCLR 0xFFFFF1FF
119 #define SDVSDET 0x00000400
120 #define SIDLE_MODE (0x2 << 3)
122 #define SDBP (1 << 8)
127 #define CLKD_MASK 0x0000FFC0
128 #define IE_EN_MASK 0x317F0137
129 #define INIT_STREAM (1 << 1)
130 #define DP_SELECT (1 << 21)
131 #define DDIR (1 << 4)
133 #define MSBS (1 << 5)
135 #define ONE_BIT (~(0x2))
136 #define EIGHT_BIT (~(0x20))
142 #define BRE (1 << 11)
143 #define BWE (1 << 10)
144 #define SBGR (1 << 16)
146 #define SDIO_READ (1 << 31)
147 #define SDIO_BLKMODE (1 << 27)
148 #define OMAP_HSMMC_ERR (1 << 15) /* Any error */
149 #define OMAP_HSMMC_CMD_TIMEOUT (1 << 16) /* Com mand response time-out */
150 #define OMAP_HSMMC_DATA_TIMEOUT (1 << 20) /* Data response time-out */
151 #define OMAP_HSMMC_CMD_CRC (1 << 17) /* Command CRC error */
152 #define OMAP_HSMMC_DATA_CRC (1 << 21) /* Date CRC error */
153 #define OMAP_HSMMC_CARD_ERR (1 << 28) /* Card ERR */
154 #define OMAP_HSMMC_STAT_CLEAR 0xFFFFFFFF
155 #define INIT_STREAM_CMD 0x00000000
156 #define INT_CLEAR 0x00000000
157 #define BLK_CLEAR 0x00000000
159 /* SCM CONTROL_DEVCONF1 MMC1 overwrite but */
161 #define MMC1_ACTIVE_OVERWRITE (1 << 31)
163 #define sdio_blkmode_regaddr 0x2000
164 #define sdio_blkmode_mask 0xFF00
166 #define IO_RW_DIRECT_MASK 0xF000FF00
167 #define IO_RW_DIRECT_ARG_MASK 0x80001A00
169 #define RMASK (MMC_RSP_MASK | MMC_RSP_CRC)
170 #define MMC_TIMEOUT_MS 100 /*on the new 2430 it was 20, i changed back to 100*//* obc */
173 #define VMMC1_DEV_GRP 0x27
174 #define P1_DEV_GRP 0x20
175 #define VMMC1_DEDICATED 0x2A
177 #define VSEL_18V 0x00
178 #define PBIAS_3V 0x03
179 #define PBIAS_18V 0x02
180 #define PBIAS_LITE 0x04A0
181 #define PBIAS_CLR 0x00
183 #define OMAP_MMC_REGS_BASE IO_ADDRESS(TIWLAN_MMC_CONTROLLER_BASE_ADDR)
186 * MMC Host controller read/write API's.
188 #define OMAP_HSMMC_READ_OFFSET(offset) (__raw_readl((OMAP_MMC_REGS_BASE) + (offset)))
189 #define OMAP_HSMMC_READ(reg) (__raw_readl((OMAP_MMC_REGS_BASE) + OMAP_HSMMC_##reg))
190 #define OMAP_HSMMC_WRITE(reg, val) (__raw_writel((val), (OMAP_MMC_REGS_BASE) + OMAP_HSMMC_##reg))
192 #define OMAP_HSMMC_SEND_COMMAND(cmd, arg) do \
194 OMAP_HSMMC_WRITE(ARG, arg); \
195 OMAP_HSMMC_WRITE(CMD, cmd); \
198 #define OMAP_HSMMC_CMD52_WRITE ((SD_IO_RW_DIRECT << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16))
199 #define OMAP_HSMMC_CMD52_READ (((SD_IO_RW_DIRECT << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DDIR)
200 #define OMAP_HSMMC_CMD53_WRITE (((SD_IO_RW_EXTENDED << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DP_SELECT)
201 #define OMAP_HSMMC_CMD53_READ (((SD_IO_RW_EXTENDED << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DP_SELECT | DDIR)
202 #define OMAP_HSMMC_CMD53_READ_DMA (OMAP_HSMMC_CMD53_READ | DMA_EN)
203 #define OMAP_HSMMC_CMD53_WRITE_DMA (OMAP_HSMMC_CMD53_WRITE | DMA_EN)
205 /* Macros to build commands 52 and 53 in format according to SDIO spec */
206 #define SDIO_CMD52_READ(v1,v2,v3,v4) (SDIO_RWFLAG(v1)|SDIO_FUNCN(v2)|SDIO_RAWFLAG(v3)| SDIO_ADDRREG(v4))
207 #define SDIO_CMD52_WRITE(v1,v2,v3,v4,v5) (SDIO_RWFLAG(v1)|SDIO_FUNCN(v2)|SDIO_RAWFLAG(v3)| SDIO_ADDRREG(v4)|(v5))
208 #define SDIO_CMD53_READ(v1,v2,v3,v4,v5,v6) (SDIO_RWFLAG(v1)|SDIO_FUNCN(v2)|SDIO_BLKM(v3)| SDIO_OPCODE(v4)|SDIO_ADDRREG(v5)|(v6&0x1ff))
209 #define SDIO_CMD53_WRITE(v1,v2,v3,v4,v5,v6) (SDIO_RWFLAG(v1)|SDIO_FUNCN(v2)|SDIO_BLKM(v3)| SDIO_OPCODE(v4)|SDIO_ADDRREG(v5)|(v6&0x1ff))
211 #define SDIODRV_MAX_LOOPS 50000
213 #define VMMC2_DEV_GRP 0x2B
214 #define VMMC2_DEDICATED 0x2E
215 #define VSEL_S2_18V 0x05
217 #define VSEL_S2_CLR 0x40
218 #define GPIO_0_BIT_POS 1 << 0
219 #define GPIO_1_BIT_POS 1 << 1
220 #define VSIM_DEV_GRP 0x37
221 #define VSIM_DEDICATED 0x3A
222 #define TWL4030_MODULE_PM_RECIEVER 0x13
224 typedef struct OMAP3430_sdiodrv
226 struct clk *fclk, *iclk, *dbclk;
232 void (*BusTxnCB)(void* BusTxnHandle, int status);
234 unsigned int uBlkSize;
235 unsigned int uBlkSizeShift;
237 int (*wlanDrvIf_pm_resume)(void);
238 int (*wlanDrvIf_pm_suspend)(void);
240 dma_addr_t dma_read_addr;
241 size_t dma_read_size;
242 dma_addr_t dma_write_addr;
243 size_t dma_write_size;
244 struct workqueue_struct *sdio_wq; /* Work Queue */
245 struct work_struct sdiodrv_work;
246 } OMAP3430_sdiodrv_t;
248 struct omap_hsmmc_regs {
257 static struct omap_hsmmc_regs hsmmc_ctx;
259 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
260 static struct platform_device dummy_pdev = {
262 .bus = &platform_bus_type,
267 #define SDIO_DRIVER_NAME "TIWLAN_SDIO"
269 module_param(g_sdio_debug_level, int, 0644);
270 MODULE_PARM_DESC(g_sdio_debug_level, "debug level");
271 int g_sdio_debug_level = SDIO_DEBUGLEVEL_ERR;
272 EXPORT_SYMBOL(g_sdio_debug_level);
274 OMAP3430_sdiodrv_t g_drv;
276 static int sdiodrv_irq_requested = 0;
277 static int sdiodrv_iclk_got = 0;
278 static int sdiodrv_fclk_got = 0;
280 static void sdioDrv_hsmmc_save_ctx(void);
281 static void sdioDrv_hsmmc_restore_ctx(void);
282 static void sdiodrv_dma_shutdown(void);
284 #ifndef TI_SDIO_STANDALONE
285 void sdio_init( int sdcnum )
289 TIWLAN_MMC_CONTROLLER = sdcnum - 1;
291 TIWLAN_MMC_CONTROLLER_BASE_ADDR = OMAP_HSMMC2_BASE;
292 TIWLAN_MMC_DMA_TX = OMAP24XX_DMA_MMC2_TX;
293 TIWLAN_MMC_DMA_RX = OMAP24XX_DMA_MMC2_RX;
294 OMAP_MMC_IRQ = INT_MMC2_IRQ;
296 else if( sdcnum == 3 ) {
297 TIWLAN_MMC_CONTROLLER_BASE_ADDR = OMAP_HSMMC3_BASE;
298 TIWLAN_MMC_DMA_TX = OMAP34XX_DMA_MMC3_TX;
299 TIWLAN_MMC_DMA_RX = OMAP34XX_DMA_MMC3_RX;
300 OMAP_MMC_IRQ = INT_MMC3_IRQ;
305 static void sdioDrv_hsmmc_save_ctx(void)
307 /* MMC : context save */
308 hsmmc_ctx.hctl = OMAP_HSMMC_READ(HCTL);
309 hsmmc_ctx.capa = OMAP_HSMMC_READ(CAPA);
310 hsmmc_ctx.sysconfig = OMAP_HSMMC_READ(SYSCONFIG);
311 hsmmc_ctx.ise = OMAP_HSMMC_READ(ISE);
312 hsmmc_ctx.ie = OMAP_HSMMC_READ(IE);
313 hsmmc_ctx.con = OMAP_HSMMC_READ(CON);
314 hsmmc_ctx.sysctl = OMAP_HSMMC_READ(SYSCTL);
315 OMAP_HSMMC_WRITE(ISE, 0);
316 OMAP_HSMMC_WRITE(IE, 0);
319 static void sdioDrv_hsmmc_restore_ctx(void)
321 /* MMC : context restore */
322 OMAP_HSMMC_WRITE(HCTL, hsmmc_ctx.hctl);
323 OMAP_HSMMC_WRITE(CAPA, hsmmc_ctx.capa);
324 OMAP_HSMMC_WRITE(SYSCONFIG, hsmmc_ctx.sysconfig);
325 OMAP_HSMMC_WRITE(CON, hsmmc_ctx.con);
326 OMAP_HSMMC_WRITE(ISE, hsmmc_ctx.ise);
327 OMAP_HSMMC_WRITE(IE, hsmmc_ctx.ie);
328 OMAP_HSMMC_WRITE(SYSCTL, hsmmc_ctx.sysctl);
329 OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | SDBP);
332 void sdiodrv_task(struct work_struct *unused)
334 PDEBUG("sdiodrv_tasklet()\n");
336 if (g_drv.dma_read_addr != 0) {
337 dma_unmap_single(g_drv.dev, g_drv.dma_read_addr, g_drv.dma_read_size, DMA_FROM_DEVICE);
338 g_drv.dma_read_addr = 0;
339 g_drv.dma_read_size = 0;
342 if (g_drv.dma_write_addr != 0) {
343 dma_unmap_single(g_drv.dev, g_drv.dma_write_addr, g_drv.dma_write_size, DMA_TO_DEVICE);
344 g_drv.dma_write_addr = 0;
345 g_drv.dma_write_size = 0;
348 if (g_drv.BusTxnCB != NULL) {
349 g_drv.BusTxnCB(g_drv.BusTxnHandle, g_drv.async_status);
353 irqreturn_t sdiodrv_irq(int irq, void *drv)
357 PDEBUG("sdiodrv_irq()\n");
359 status = OMAP_HSMMC_READ(STAT);
360 OMAP_HSMMC_WRITE(ISE, 0);
361 g_drv.async_status = status & (OMAP_HSMMC_ERR);
362 if (g_drv.async_status) {
363 PERR("sdiodrv_irq: ERROR in STAT = 0x%x\n", status);
365 queue_work(g_drv.sdio_wq, &g_drv.sdiodrv_work);
369 void sdiodrv_dma_read_cb(int lch, u16 ch_status, void *data)
371 PDEBUG("sdiodrv_dma_read_cb() channel=%d status=0x%x\n", lch, (int)ch_status);
373 g_drv.async_status = ch_status & (1 << 7);
375 queue_work(g_drv.sdio_wq, &g_drv.sdiodrv_work);
376 sdiodrv_dma_shutdown();
379 void sdiodrv_dma_write_cb(int lch, u16 ch_status, void *data)
381 sdiodrv_dma_shutdown();
384 int sdiodrv_dma_init(void)
388 rc = omap_request_dma(TIWLAN_MMC_DMA_TX, "SDIO WRITE", sdiodrv_dma_write_cb, &g_drv, &g_drv.dma_tx_channel);
390 PERR("sdiodrv_dma_init() omap_request_dma(TIWLAN_MMC_DMA_TX) FAILED\n");
394 rc = omap_request_dma(TIWLAN_MMC_DMA_RX, "SDIO READ", sdiodrv_dma_read_cb, &g_drv, &g_drv.dma_rx_channel);
396 PERR("sdiodrv_dma_init() omap_request_dma(TIWLAN_MMC_DMA_RX) FAILED\n");
400 omap_set_dma_src_params(g_drv.dma_rx_channel,
401 0, // src_port is only for OMAP1
402 OMAP_DMA_AMODE_CONSTANT,
403 (TIWLAN_MMC_CONTROLLER_BASE_ADDR) + OMAP_HSMMC_DATA, 0, 0);
405 omap_set_dma_dest_params(g_drv.dma_tx_channel,
406 0, // dest_port is only for OMAP1
407 OMAP_DMA_AMODE_CONSTANT,
408 (TIWLAN_MMC_CONTROLLER_BASE_ADDR) + OMAP_HSMMC_DATA, 0, 0);
413 omap_free_dma(g_drv.dma_tx_channel);
418 static void sdiodrv_dma_shutdown(void)
420 omap_free_dma(g_drv.dma_tx_channel);
421 omap_free_dma(g_drv.dma_rx_channel);
422 } /* sdiodrv_dma_shutdown() */
424 static u32 sdiodrv_poll_status(u32 reg_offset, u32 stat, unsigned int msecs)
426 u32 status=0, loops=0;
430 status = OMAP_HSMMC_READ_OFFSET(reg_offset);
435 } while (loops++ < SDIODRV_MAX_LOOPS);
438 } /* sdiodrv_poll_status */
442 printk(KERN_ERR "\n MMCHS_SYSCONFIG for mmc3 = %x ", omap_readl( 0x480AD010 ));
443 printk(KERN_ERR "\n MMCHS_SYSSTATUS for mmc3 = %x ", omap_readl( 0x480AD014 ));
444 printk(KERN_ERR "\n MMCHS_CSRE for mmc3 = %x ", omap_readl( 0x480AD024 ));
445 printk(KERN_ERR "\n MMCHS_SYSTEST for mmc3 = %x ", omap_readl( 0x480AD028 ));
446 printk(KERN_ERR "\n MMCHS_CON for mmc3 = %x ", omap_readl( 0x480AD02C ));
447 printk(KERN_ERR "\n MMCHS_PWCNT for mmc3 = %x ", omap_readl( 0x480AD030 ));
448 printk(KERN_ERR "\n MMCHS_BLK for mmc3 = %x ", omap_readl( 0x480AD104 ));
449 printk(KERN_ERR "\n MMCHS_ARG for mmc3 = %x ", omap_readl( 0x480AD108 ));
450 printk(KERN_ERR "\n MMCHS_CMD for mmc3 = %x ", omap_readl( 0x480AD10C ));
451 printk(KERN_ERR "\n MMCHS_RSP10 for mmc3 = %x ", omap_readl( 0x480AD110 ));
452 printk(KERN_ERR "\n MMCHS_RSP32 for mmc3 = %x ", omap_readl( 0x480AD114 ));
453 printk(KERN_ERR "\n MMCHS_RSP54 for mmc3 = %x ", omap_readl( 0x480AD118 ));
454 printk(KERN_ERR "\n MMCHS_RSP76 for mmc3 = %x ", omap_readl( 0x480AD11C ));
455 printk(KERN_ERR "\n MMCHS_DATA for mmc3 = %x ", omap_readl( 0x480AD120 ));
456 printk(KERN_ERR "\n MMCHS_PSTATE for mmc3 = %x ", omap_readl( 0x480AD124 ));
457 printk(KERN_ERR "\n MMCHS_HCTL for mmc3 = %x ", omap_readl( 0x480AD128 ));
458 printk(KERN_ERR "\n MMCHS_SYSCTL for mmc3 = %x ", omap_readl( 0x480AD12C ));
459 printk(KERN_ERR "\n MMCHS_STAT for mmc3 = %x ", omap_readl( 0x480AD130 ));
460 printk(KERN_ERR "\n MMCHS_IE for mmc3 = %x ", omap_readl( 0x480AD134 ));
461 printk(KERN_ERR "\n MMCHS_ISE for mmc3 = %x ", omap_readl( 0x480AD138 ));
462 printk(KERN_ERR "\n MMCHS_AC12 for mmc3 = %x ", omap_readl( 0x480AD13C ));
463 printk(KERN_ERR "\n MMCHS_CAPA for mmc3 = %x ", omap_readl( 0x480AD140 ));
464 printk(KERN_ERR "\n MMCHS_CUR_CAPA for mmc3 = %x ", omap_readl( 0x480AD148 ));
467 //cmd flow p. 3609 obc
468 static int sdiodrv_send_command(u32 cmdreg, u32 cmdarg)
470 OMAP_HSMMC_WRITE(STAT, OMAP_HSMMC_STAT_CLEAR);
471 OMAP_HSMMC_SEND_COMMAND(cmdreg, cmdarg);
473 return sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS);
474 } /* sdiodrv_send_command() */
477 * Disable clock to the card
479 static void OMAP3430_mmc_stop_clock(void)
481 OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) & ~CEN);
482 if ((OMAP_HSMMC_READ(SYSCTL) & CEN) != 0x0)
484 PERR("MMC clock not stoped, clock freq can not be altered\n");
486 } /* OMAP3430_mmc_stop_clock */
489 * Reset the SD system
491 int OMAP3430_mmc_reset(void)
494 //p. 3598 - need to set SOFTRESET to 0x1 0bc
495 OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | SRA);
496 while ((status = OMAP_HSMMC_READ(SYSCTL) & SRA) && loops++ < SDIODRV_MAX_LOOPS);
499 PERR("OMAP3430_mmc_reset() MMC reset FAILED!! status=0x%x\n",status);
504 } /* OMAP3430_mmc_reset */
507 static void OMAP3430_mmc_set_clock(unsigned int clock, OMAP3430_sdiodrv_t *host)
510 unsigned long regVal;
513 PDEBUG("OMAP3430_mmc_set_clock(%d)\n",clock);
515 /* Enable MMC_SD_CLK */
516 dsor = OMAP_MMC_MASTER_CLOCK / clock;
520 if (OMAP_MMC_MASTER_CLOCK / dsor > clock) {
527 OMAP3430_mmc_stop_clock();
528 regVal = OMAP_HSMMC_READ(SYSCTL);
529 regVal = regVal & ~(CLKD_MASK);//p. 3652
530 regVal = regVal | (dsor << 6);
531 regVal = regVal | (DTO << 16);//data timeout
532 OMAP_HSMMC_WRITE(SYSCTL, regVal);
533 OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | ICE);//internal clock enable. obc not mentioned in the spec
535 * wait till the the clock is stable (ICS) bit is set
537 status = sdiodrv_poll_status(OMAP_HSMMC_SYSCTL, ICS, MMC_TIMEOUT_MS);
538 if(!(status & ICS)) {
539 PERR("OMAP3430_mmc_set_clock() clock not stable!! status=0x%x\n",status);
542 * Enable clock to the card
544 OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | CEN);
546 } /* OMAP3430_mmc_set_clock() */
548 static void sdiodrv_free_resources(void)
550 if(g_drv.ifclks_enabled) {
551 sdioDrv_clk_disable();
554 if (sdiodrv_fclk_got) {
556 sdiodrv_fclk_got = 0;
559 if (sdiodrv_iclk_got) {
561 sdiodrv_iclk_got = 0;
564 if (sdiodrv_irq_requested) {
565 free_irq(OMAP_MMC_IRQ, &g_drv);
566 sdiodrv_irq_requested = 0;
570 int sdioDrv_InitHw(void)
573 } /* sdioDrv_InitHw */
575 void sdiodrv_shutdown(void)
577 PDEBUG("entering %s()\n" , __FUNCTION__ );
579 sdiodrv_free_resources();
581 PDEBUG("exiting %s\n", __FUNCTION__);
582 } /* sdiodrv_shutdown() */
584 static int sdiodrv_send_data_xfer_commad(u32 cmd, u32 cmdarg, int length, u32 buffer_enable_status, unsigned int bBlkMode)
588 PDEBUG("%s() writing CMD 0x%x ARG 0x%x\n",__FUNCTION__, cmd, cmdarg);
593 * Bits 31:16 of BLK reg: NBLK Blocks count for current transfer.
594 * in case of Block MOde the lenght is treated here as number of blocks
595 * (and not as a length).
596 * Bits 11:0 of BLK reg: BLEN Transfer Block Size. in case of block mode set that field to block size.
598 OMAP_HSMMC_WRITE(BLK, (length << 16) | (g_drv.uBlkSize << 0));
602 * BCE: Block Count Enable
603 * MSBS: Multi/Single block select
607 OMAP_HSMMC_WRITE(BLK, length);
610 status = sdiodrv_send_command(cmd, cmdarg);
612 PERR("sdiodrv_send_data_xfer_commad() SDIO Command error! STAT = 0x%x\n", status);
615 PDEBUG("%s() length = %d(%dw) BLK = 0x%x\n",
616 __FUNCTION__, length,((length + 3) >> 2), OMAP_HSMMC_READ(BLK));
618 return sdiodrv_poll_status(OMAP_HSMMC_PSTATE, buffer_enable_status, MMC_TIMEOUT_MS);
620 } /* sdiodrv_send_data_xfer_commad() */
622 int sdiodrv_data_xfer_sync(u32 cmd, u32 cmdarg, void *data, int length, u32 buffer_enable_status)
624 u32 buf_start, buf_end, data32;
627 status = sdiodrv_send_data_xfer_commad(cmd, cmdarg, length, buffer_enable_status, 0);
628 if(!(status & buffer_enable_status))
630 PERR("sdiodrv_data_xfer_sync() buffer disabled! length = %d BLK = 0x%x PSTATE = 0x%x\n",
631 length, OMAP_HSMMC_READ(BLK), status);
634 buf_end = (u32)data+(u32)length;
636 //obc need to check BRE/BWE every time, see p. 3605
640 if (buffer_enable_status == BRE)
642 if (((u32)data & 3) == 0) /* 4 bytes aligned */
644 for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
646 *((unsigned long*)(data)) = OMAP_HSMMC_READ(DATA);
649 else /* 2 bytes aligned */
651 for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
653 data32 = OMAP_HSMMC_READ(DATA);
654 *((unsigned short *)data) = (unsigned short)data32;
655 *((unsigned short *)data + 1) = (unsigned short)(data32 >> 16);
664 if (((u32)data & 3) == 0) /* 4 bytes aligned */
666 for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
668 OMAP_HSMMC_WRITE(DATA,*((unsigned long*)(data)));
671 else /* 2 bytes aligned */
673 for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
675 OMAP_HSMMC_WRITE(DATA,*((unsigned short*)data) | *((unsigned short*)data+1) << 16 );
680 status = sdiodrv_poll_status(OMAP_HSMMC_STAT, TC, MMC_TIMEOUT_MS);
683 PERR("sdiodrv_data_xfer_sync() transfer error! STAT = 0x%x\n", status);
689 } /* sdiodrv_data_xfer_sync() */
691 int sdioDrv_ConnectBus (void * fCbFunc,
693 unsigned int uBlkSizeShift,
694 unsigned int uSdioThreadPriority)
696 g_drv.BusTxnCB = fCbFunc;
697 g_drv.BusTxnHandle = hCbArg;
698 g_drv.uBlkSizeShift = uBlkSizeShift;
699 g_drv.uBlkSize = 1 << uBlkSizeShift;
701 INIT_WORK(&g_drv.sdiodrv_work, sdiodrv_task);
703 return sdioDrv_InitHw ();
706 /*--------------------------------------------------------------------------------------*/
708 int sdioDrv_DisconnectBus (void)
710 /* Disable clocks to handle driver stop command */
711 sdioDrv_clk_disable();
716 int sdioDrv_ExecuteCmd (unsigned int uCmd,
718 unsigned int uRespType,
722 unsigned int uCmdReg = 0;
723 unsigned int uStatus = 0;
724 unsigned int uResponse = 0;
726 PDEBUG("sdioDrv_ExecuteCmd() starting cmd %02x arg %08x\n", (int)uCmd, (int)uArg);
728 sdioDrv_clk_enable(); /* To make sure we have clocks enable */
730 uCmdReg = (uCmd << 24) | (uRespType << 16) ;
732 uStatus = sdiodrv_send_command(uCmdReg, uArg);
736 PERR("sdioDrv_ExecuteCmd() SDIO Command error status = 0x%x\n", uStatus);
739 if ((uLen > 0) && (uLen <= 4))/*obc - Len > 4 ? shouldn't read anything ? */
741 uResponse = OMAP_HSMMC_READ(RSP10);
742 memcpy (pResponse, (char *)&uResponse, uLen);
743 PDEBUG("sdioDrv_ExecuteCmd() response = 0x%x\n", uResponse);
748 /*--------------------------------------------------------------------------------------*/
750 int sdioDrv_ReadSync (unsigned int uFunc,
751 unsigned int uHwAddr,
754 unsigned int bIncAddr,
757 unsigned int uCmdArg;
760 // printk(KERN_INFO "in sdioDrv_ReadSync\n");
761 uCmdArg = SDIO_CMD53_READ(0, uFunc, 0, bIncAddr, uHwAddr, uLen);
763 iStatus = sdiodrv_data_xfer_sync(OMAP_HSMMC_CMD53_READ, uCmdArg, pData, uLen, BRE);
765 PERR("sdioDrv_ReadSync() FAILED!!\n");
769 printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(char *)pData));
771 printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(short *)pData));
773 printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(long *)pData));
775 printk(KERN_INFO "R53: [0x%x](%u)\n", uHwAddr, uLen);
780 /*--------------------------------------------------------------------------------------*/
781 int sdioDrv_ReadAsync (unsigned int uFunc,
782 unsigned int uHwAddr,
785 unsigned int bBlkMode,
786 unsigned int bIncAddr,
790 unsigned int uCmdArg;
791 unsigned int uNumBlks;
792 unsigned int uDmaBlockCount;
793 unsigned int uNumOfElem;
794 dma_addr_t dma_bus_address;
797 printk(KERN_INFO "R53: [0x%x](%u) F[%d]\n", uHwAddr, uLen, uFunc);
800 //printk(KERN_INFO "in sdioDrv_ReadAsync\n");
804 /* For block mode use number of blocks instead of length in bytes */
805 uNumBlks = uLen >> g_drv.uBlkSizeShift;
806 uDmaBlockCount = uNumBlks;
807 /* due to the DMA config to 32Bit per element (OMAP_DMA_DATA_TYPE_S32) the division is by 4 */
808 uNumOfElem = g_drv.uBlkSize >> 2;
814 uNumOfElem = (uLen + 3) >> 2;
817 uCmdArg = SDIO_CMD53_READ(0, uFunc, bBlkMode, bIncAddr, uHwAddr, uNumBlks);
819 iStatus = sdiodrv_send_data_xfer_commad(OMAP_HSMMC_CMD53_READ_DMA, uCmdArg, uNumBlks, BRE, bBlkMode);
821 if (!(iStatus & BRE))
823 PERR("sdioDrv_ReadAsync() buffer disabled! length = %d BLK = 0x%x PSTATE = 0x%x, BlkMode = %d\n",
824 uLen, OMAP_HSMMC_READ(BLK), iStatus, bBlkMode);
830 PDEBUG("sdiodrv_read_async() dma_ch=%d \n",g_drv.dma_rx_channel);
832 dma_bus_address = dma_map_single(g_drv.dev, pData, uLen, DMA_FROM_DEVICE);
833 if (!dma_bus_address) {
834 PERR("sdioDrv_ReadAsync: dma_map_single failed\n");
838 if (g_drv.dma_read_addr != 0) {
839 printk(KERN_ERR "sdioDrv_ReadAsync: previous DMA op is not finished!\n");
843 g_drv.dma_read_addr = dma_bus_address;
844 g_drv.dma_read_size = uLen;
846 omap_set_dma_dest_params (g_drv.dma_rx_channel,
847 0, // dest_port is only for OMAP1
848 OMAP_DMA_AMODE_POST_INC,
852 omap_set_dma_transfer_params(g_drv.dma_rx_channel, OMAP_DMA_DATA_TYPE_S32, uNumOfElem , uDmaBlockCount , OMAP_DMA_SYNC_FRAME, TIWLAN_MMC_DMA_RX, OMAP_DMA_SRC_SYNC);
854 omap_start_dma(g_drv.dma_rx_channel);
856 /* Continued at sdiodrv_irq() after DMA transfer is finished */
858 printk(KERN_INFO "R53: [0x%x](%u) (A)\n", uHwAddr, uLen);
867 /*--------------------------------------------------------------------------------------*/
869 int sdioDrv_WriteSync (unsigned int uFunc,
870 unsigned int uHwAddr,
873 unsigned int bIncAddr,
876 unsigned int uCmdArg;
879 // printk(KERN_INFO "in sdioDrv_WriteSync\n");
881 uCmdArg = SDIO_CMD53_WRITE(1, uFunc, 0, bIncAddr, uHwAddr, uLen);
883 iStatus = sdiodrv_data_xfer_sync(OMAP_HSMMC_CMD53_WRITE, uCmdArg, pData, uLen, BWE);
886 PERR("sdioDrv_WriteSync() FAILED!!\n");
890 printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(char *)pData));
892 printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(short *)pData));
894 printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(long *)pData));
896 printk(KERN_INFO "W53: [0x%x](%u)\n", uHwAddr, uLen);
901 /*--------------------------------------------------------------------------------------*/
902 int sdioDrv_WriteAsync (unsigned int uFunc,
903 unsigned int uHwAddr,
906 unsigned int bBlkMode,
907 unsigned int bIncAddr,
911 unsigned int uCmdArg;
912 unsigned int uNumBlks;
913 unsigned int uDmaBlockCount;
914 unsigned int uNumOfElem;
915 dma_addr_t dma_bus_address;
918 printk(KERN_INFO "W53: [0x%x](%u) F[%d] B[%d] I[%d]\n", uHwAddr, uLen, uFunc, bBlkMode, bIncAddr);
921 // printk(KERN_INFO "in sdioDrv_WriteAsync\n");
924 /* For block mode use number of blocks instead of length in bytes */
925 uNumBlks = uLen >> g_drv.uBlkSizeShift;
926 uDmaBlockCount = uNumBlks;
927 /* due to the DMA config to 32Bit per element (OMAP_DMA_DATA_TYPE_S32) the division is by 4 */
928 uNumOfElem = g_drv.uBlkSize >> 2;
934 uNumOfElem = (uLen + 3) >> 2;
937 uCmdArg = SDIO_CMD53_WRITE(1, uFunc, bBlkMode, bIncAddr, uHwAddr, uNumBlks);
939 iStatus = sdiodrv_send_data_xfer_commad(OMAP_HSMMC_CMD53_WRITE_DMA, uCmdArg, uNumBlks, BWE, bBlkMode);
940 if (!(iStatus & BWE))
942 PERR("sdioDrv_WriteAsync() buffer disabled! length = %d, BLK = 0x%x, Status = 0x%x\n",
943 uLen, OMAP_HSMMC_READ(BLK), iStatus);
947 OMAP_HSMMC_WRITE(ISE, TC);
951 dma_bus_address = dma_map_single(g_drv.dev, pData, uLen, DMA_TO_DEVICE);
952 if (!dma_bus_address) {
953 PERR("sdioDrv_WriteAsync: dma_map_single failed\n");
957 if (g_drv.dma_write_addr != 0) {
958 PERR("sdioDrv_WriteAsync: previous DMA op is not finished!\n");
962 g_drv.dma_write_addr = dma_bus_address;
963 g_drv.dma_write_size = uLen;
965 omap_set_dma_src_params (g_drv.dma_tx_channel,
966 0, // src_port is only for OMAP1
967 OMAP_DMA_AMODE_POST_INC,
971 omap_set_dma_transfer_params(g_drv.dma_tx_channel, OMAP_DMA_DATA_TYPE_S32, uNumOfElem, uDmaBlockCount, OMAP_DMA_SYNC_FRAME, TIWLAN_MMC_DMA_TX, OMAP_DMA_DST_SYNC);
973 omap_start_dma(g_drv.dma_tx_channel);
975 /* Continued at sdiodrv_irq() after DMA transfer is finished */
981 /*--------------------------------------------------------------------------------------*/
983 int sdioDrv_ReadSyncBytes (unsigned int uFunc,
984 unsigned int uHwAddr,
985 unsigned char *pData,
989 unsigned int uCmdArg;
993 for (i = 0; i < uLen; i++) {
994 uCmdArg = SDIO_CMD52_READ(0, uFunc, 0, uHwAddr);
996 iStatus = sdiodrv_send_command(OMAP_HSMMC_CMD52_READ, uCmdArg);
998 if (!(iStatus & CC)) {
999 PERR("sdioDrv_ReadSyncBytes() SDIO Command error status = 0x%x\n", iStatus);
1003 *pData = (unsigned char)(OMAP_HSMMC_READ(RSP10));
1005 #ifdef TI_SDIO_DEBUG
1006 printk(KERN_INFO "R52: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)*pData);
1015 /*--------------------------------------------------------------------------------------*/
1017 int sdioDrv_WriteSyncBytes (unsigned int uFunc,
1018 unsigned int uHwAddr,
1019 unsigned char *pData,
1023 unsigned int uCmdArg;
1027 for (i = 0; i < uLen; i++) {
1028 #ifdef TI_SDIO_DEBUG
1029 printk(KERN_INFO "W52: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)*pData);
1031 uCmdArg = SDIO_CMD52_WRITE(1, uFunc, 0, uHwAddr, *pData);
1033 iStatus = sdiodrv_send_command(OMAP_HSMMC_CMD52_WRITE, uCmdArg);
1034 if (!(iStatus & CC)) {
1035 PERR("sdioDrv_WriteSyncBytes() SDIO Command error status = 0x%x\n", iStatus);
1045 static int sdioDrv_probe(struct platform_device *pdev)
1049 #ifdef SDIO_1_BIT /* see also in SdioAdapter.c */
1050 unsigned long clock_rate = 6000000;
1052 unsigned long clock_rate = 24000000;
1055 printk(KERN_INFO "TIWLAN SDIO probe: initializing mmc%d device\n", pdev->id + 1);
1057 /* remember device struct for future DMA operations */
1058 g_drv.dev = &pdev->dev;
1059 g_drv.irq = platform_get_irq(pdev, 0);
1063 rc= request_irq(OMAP_MMC_IRQ, sdiodrv_irq, 0, SDIO_DRIVER_NAME, &g_drv);
1065 PERR("sdioDrv_InitHw() - request_irq FAILED!!\n");
1068 sdiodrv_irq_requested = 1;
1070 spin_lock_init(&g_drv.clk_lock);
1072 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
1073 dummy_pdev.id = TIWLAN_MMC_CONTROLLER;
1074 dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%lu", TIWLAN_MMC_CONTROLLER);
1075 g_drv.fclk = clk_get(&dummy_pdev.dev, "fck");
1077 g_drv.fclk = clk_get(&pdev->dev, "mmchs_fck");
1079 if (IS_ERR(g_drv.fclk)) {
1080 rc = PTR_ERR(g_drv.fclk);
1081 PERR("clk_get(fclk) FAILED !!!\n");
1084 sdiodrv_fclk_got = 1;
1086 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
1087 g_drv.iclk = clk_get(&dummy_pdev.dev, "ick");
1089 g_drv.iclk = clk_get(&pdev->dev, "mmchs_ick");
1091 if (IS_ERR(g_drv.iclk)) {
1092 rc = PTR_ERR(g_drv.iclk);
1093 PERR("clk_get(iclk) FAILED !!!\n");
1096 sdiodrv_iclk_got = 1;
1098 rc = sdioDrv_clk_enable();
1100 PERR("sdioDrv_probe : clk_enable FAILED !!!\n");
1104 OMAP3430_mmc_reset();
1106 //obc - init sequence p. 3600,3617
1108 OMAP_HSMMC_WRITE(CAPA, OMAP_HSMMC_READ(CAPA) | VS18);
1109 OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | SDVS18);//SDVS fits p. 3650
1111 OMAP_HSMMC_WRITE(SYSCONFIG, OMAP_HSMMC_READ(SYSCONFIG) | AUTOIDLE);
1114 OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | SDBP);//SDBP fits p. 3650
1116 OMAP_HSMMC_WRITE(ISE, 0);
1117 OMAP_HSMMC_WRITE(IE, IE_EN_MASK);
1119 //p. 3601 suggests moving to the end
1120 OMAP3430_mmc_set_clock(clock_rate, &g_drv);
1121 printk(KERN_INFO "SDIO clock Configuration is now set to %dMhz\n",(int)clock_rate/1000000);
1124 #ifdef SDIO_1_BIT /* see also in SdioAdapter.c */
1125 PDEBUG("%s() setting %d data lines\n",__FUNCTION__, 1);
1126 OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) & (ONE_BIT));
1128 PDEBUG("%s() setting %d data lines\n",__FUNCTION__, 4);
1129 OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | (1 << 1));//DTW 4 bits - p. 3650
1132 /* send the init sequence. 80 clocks of synchronization in the SDIO */
1133 //doesn't match p. 3601,3617 - obc
1134 OMAP_HSMMC_WRITE( CON, OMAP_HSMMC_READ(CON) | INIT_STREAM);
1135 OMAP_HSMMC_SEND_COMMAND( 0, 0);
1136 status = sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS);
1137 if (!(status & CC)) {
1138 PERR("sdioDrv_InitHw() SDIO Command error status = 0x%x\n", status);
1142 OMAP_HSMMC_WRITE(CON, OMAP_HSMMC_READ(CON) & ~INIT_STREAM);
1144 /* Disabling clocks for now */
1145 sdioDrv_clk_disable();
1149 sdiodrv_free_resources();
1153 static int sdioDrv_remove(struct platform_device *pdev)
1155 printk(KERN_INFO "sdioDrv_remove: calling sdiodrv_shutdown\n");
1163 static int sdioDrv_suspend(struct platform_device *pdev, pm_message_t state)
1165 printk(KERN_INFO "TISDIO: sdioDrv is suspending\n");
1169 /* Routine to resume the MMC device */
1170 static int sdioDrv_resume(struct platform_device *pdev)
1172 printk(KERN_INFO "TISDIO: sdioDrv is resuming\n");
1176 #define sdioDrv_suspend NULL
1177 #define sdioDrv_resume NULL
1180 static struct platform_driver sdioDrv_struct = {
1181 .probe = sdioDrv_probe,
1182 .remove = sdioDrv_remove,
1183 .suspend = sdioDrv_suspend,
1184 .resume = sdioDrv_resume,
1186 .name = SDIO_DRIVER_NAME,
1190 void sdioDrv_register_pm(int (*wlanDrvIf_Start)(void),
1191 int (*wlanDrvIf_Stop)(void))
1193 g_drv.wlanDrvIf_pm_resume = wlanDrvIf_Start;
1194 g_drv.wlanDrvIf_pm_suspend = wlanDrvIf_Stop;
1197 int sdioDrv_clk_enable(void)
1199 unsigned long flags;
1202 spin_lock_irqsave(&g_drv.clk_lock, flags);
1203 if (g_drv.ifclks_enabled)
1206 ret = clk_enable(g_drv.iclk);
1210 ret = clk_enable(g_drv.fclk);
1213 g_drv.ifclks_enabled = 1;
1215 sdioDrv_hsmmc_restore_ctx();
1218 spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1222 clk_disable(g_drv.iclk);
1224 spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1228 void sdioDrv_clk_disable(void)
1230 unsigned long flags;
1232 spin_lock_irqsave(&g_drv.clk_lock, flags);
1233 if (!g_drv.ifclks_enabled)
1236 sdioDrv_hsmmc_save_ctx();
1238 clk_disable(g_drv.fclk);
1239 clk_disable(g_drv.iclk);
1240 g_drv.ifclks_enabled = 0;
1242 spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1245 #ifdef TI_SDIO_STANDALONE
1246 static int __init sdioDrv_init(void)
1248 int __init sdioDrv_init(int sdcnum)
1251 memset(&g_drv, 0, sizeof(g_drv));
1252 memset(&hsmmc_ctx, 0, sizeof(hsmmc_ctx));
1254 printk(KERN_INFO "TIWLAN SDIO init\n");
1255 #ifndef TI_SDIO_STANDALONE
1256 sdio_init( sdcnum );
1258 g_drv.sdio_wq = create_freezeable_workqueue(SDIOWQ_NAME);
1259 if (!g_drv.sdio_wq) {
1260 printk("TISDIO: Fail to create SDIO WQ\n");
1263 /* Register the sdio driver */
1264 return platform_driver_register(&sdioDrv_struct);
1267 #ifdef TI_SDIO_STANDALONE
1270 void __exit sdioDrv_exit(void)
1272 /* Unregister sdio driver */
1273 platform_driver_unregister(&sdioDrv_struct);
1275 destroy_workqueue(g_drv.sdio_wq);
1278 #ifdef TI_SDIO_STANDALONE
1279 module_init(sdioDrv_init);
1280 module_exit(sdioDrv_exit);
1283 EXPORT_SYMBOL(sdioDrv_ConnectBus);
1284 EXPORT_SYMBOL(sdioDrv_DisconnectBus);
1285 EXPORT_SYMBOL(sdioDrv_ExecuteCmd);
1286 EXPORT_SYMBOL(sdioDrv_ReadSync);
1287 EXPORT_SYMBOL(sdioDrv_WriteSync);
1288 EXPORT_SYMBOL(sdioDrv_ReadAsync);
1289 EXPORT_SYMBOL(sdioDrv_WriteAsync);
1290 EXPORT_SYMBOL(sdioDrv_ReadSyncBytes);
1291 EXPORT_SYMBOL(sdioDrv_WriteSyncBytes);
1292 EXPORT_SYMBOL(sdioDrv_register_pm);
1293 MODULE_DESCRIPTION("TI WLAN SDIO driver");
1294 MODULE_LICENSE("GPL");
1295 MODULE_ALIAS(SDIO_DRIVER_NAME);
1296 MODULE_AUTHOR("Texas Instruments Inc");