OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / hardware / ti / wlan / wl1271 / external_drivers / sdio / linux / SdioDrv.c
1 /*
2  * SdioDrv.c
3  *
4  * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
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
16  *    distribution.
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.
20  *
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.
32  */
33
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>
51 #include <plat/dma.h>
52 #include <plat/io.h>
53 #include <plat/resource.h>
54 #define IO_ADDRESS(pa)  OMAP2_L4_IO_ADDRESS(pa)
55 #else
56 #include <mach/hardware.h>
57 #include <mach/board.h>
58 #include <mach/clock.h>
59 #include <mach/dma.h>
60 #include <mach/io.h>
61 #include <mach/resource.h>
62 #endif
63 typedef void *TI_HANDLE;
64 #include "host_platform.h"
65 #include "SdioDrvDbg.h"
66 #include "SdioDrv.h"
67
68 /* #define TI_SDIO_DEBUG */
69
70 #ifndef CONFIG_MMC_EMBEDDED_SDIO
71
72 #define SDIOWQ_NAME                     "sdio_wq"
73
74 /*
75  * HSMMC Address and DMA Settings
76  */
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;
84
85 #define OMAP_MMC_MASTER_CLOCK          96000000
86 /*
87  *  HSMMC Host Controller Registers
88  */
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
112
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)
121 #define AUTOIDLE                       0x1
122 #define SDBP                           (1 << 8)
123 #define DTO                            0xE
124 #define ICE                            0x1
125 #define ICS                            0x2
126 #define CEN                            (1 << 2)
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)
132 #define DMA_EN                         0x1
133 #define MSBS                           (1 << 5)
134 #define BCE                            (1 << 1)
135 #define ONE_BIT                        (~(0x2))
136 #define EIGHT_BIT                      (~(0x20))
137 #define CC                             0x1
138 #define TC                             0x02
139 #define OD                             0x1
140 #define BRW                            0x400
141 #define BRR                            0x800
142 #define BRE                            (1 << 11)
143 #define BWE                            (1 << 10)
144 #define SBGR                           (1 << 16)
145 #define CT                             (1 << 17)
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
158
159 /* SCM CONTROL_DEVCONF1 MMC1 overwrite but */
160
161 #define MMC1_ACTIVE_OVERWRITE          (1 << 31)
162
163 #define sdio_blkmode_regaddr           0x2000
164 #define sdio_blkmode_mask              0xFF00
165
166 #define IO_RW_DIRECT_MASK              0xF000FF00
167 #define IO_RW_DIRECT_ARG_MASK          0x80001A00
168
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 */
171 #define MMCA_VSN_4                     4
172
173 #define VMMC1_DEV_GRP                  0x27
174 #define P1_DEV_GRP                     0x20
175 #define VMMC1_DEDICATED                0x2A
176 #define VSEL_3V                        0x02
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
182
183 #define OMAP_MMC_REGS_BASE             IO_ADDRESS(TIWLAN_MMC_CONTROLLER_BASE_ADDR)
184
185 /*
186  * MMC Host controller read/write API's.
187  */
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))
191
192 #define OMAP_HSMMC_SEND_COMMAND(cmd, arg) do \
193 { \
194         OMAP_HSMMC_WRITE(ARG, arg); \
195         OMAP_HSMMC_WRITE(CMD, cmd); \
196 } while (0)
197
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)
204
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))
210
211 #define SDIODRV_MAX_LOOPS       50000
212
213 #define VMMC2_DEV_GRP           0x2B
214 #define VMMC2_DEDICATED         0x2E
215 #define VSEL_S2_18V             0x05
216 #define LDO_CLR                 0x00
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
223
224 typedef struct OMAP3430_sdiodrv
225 {
226         struct clk    *fclk, *iclk, *dbclk;
227         int           ifclks_enabled;
228         spinlock_t    clk_lock; 
229         int           dma_tx_channel;
230         int           dma_rx_channel;
231         int           irq;
232         void          (*BusTxnCB)(void* BusTxnHandle, int status);
233         void*         BusTxnHandle;
234         unsigned int  uBlkSize;
235         unsigned int  uBlkSizeShift;
236         int           async_status;
237         int (*wlanDrvIf_pm_resume)(void);
238         int (*wlanDrvIf_pm_suspend)(void);
239         struct device *dev;
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;
247
248 struct omap_hsmmc_regs {
249         u32 hctl;
250         u32 capa;
251         u32 sysconfig;
252         u32 ise;
253         u32 ie;
254         u32 con;
255         u32 sysctl;
256 };
257 static struct omap_hsmmc_regs hsmmc_ctx;
258
259 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
260 static struct platform_device dummy_pdev = {
261         .dev = {
262                 .bus = &platform_bus_type,
263         },
264 };
265 #endif
266
267 #define SDIO_DRIVER_NAME                        "TIWLAN_SDIO"
268
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);
273
274 OMAP3430_sdiodrv_t g_drv;
275
276 static int sdiodrv_irq_requested = 0;
277 static int sdiodrv_iclk_got = 0;
278 static int sdiodrv_fclk_got = 0;
279
280 static void sdioDrv_hsmmc_save_ctx(void);
281 static void sdioDrv_hsmmc_restore_ctx(void);
282 static void sdiodrv_dma_shutdown(void);
283
284 #ifndef TI_SDIO_STANDALONE
285 void sdio_init( int sdcnum )
286 {
287         if( sdcnum <= 0 )
288                 return;
289         TIWLAN_MMC_CONTROLLER = sdcnum - 1;
290         if( sdcnum == 2 ) {
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;
295         }
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;
301         }
302 }
303 #endif
304
305 static void sdioDrv_hsmmc_save_ctx(void)
306 {
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);
317 }
318
319 static void sdioDrv_hsmmc_restore_ctx(void)
320 {
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);
330 }
331
332 void sdiodrv_task(struct work_struct *unused)
333 {
334         PDEBUG("sdiodrv_tasklet()\n");
335
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;
340         }
341         
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;
346         }
347
348         if (g_drv.BusTxnCB != NULL) {
349                 g_drv.BusTxnCB(g_drv.BusTxnHandle, g_drv.async_status);
350         }
351 }
352
353 irqreturn_t sdiodrv_irq(int irq, void *drv)
354 {
355         int status;
356
357         PDEBUG("sdiodrv_irq()\n");
358
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);
364         }
365         queue_work(g_drv.sdio_wq, &g_drv.sdiodrv_work);
366         return IRQ_HANDLED;
367 }
368
369 void sdiodrv_dma_read_cb(int lch, u16 ch_status, void *data)
370 {
371         PDEBUG("sdiodrv_dma_read_cb() channel=%d status=0x%x\n", lch, (int)ch_status);
372
373         g_drv.async_status = ch_status & (1 << 7);
374
375         queue_work(g_drv.sdio_wq, &g_drv.sdiodrv_work);
376         sdiodrv_dma_shutdown();
377 }
378
379 void sdiodrv_dma_write_cb(int lch, u16 ch_status, void *data)
380 {
381         sdiodrv_dma_shutdown();
382 }
383
384 int sdiodrv_dma_init(void)
385 {
386         int rc;
387
388         rc = omap_request_dma(TIWLAN_MMC_DMA_TX, "SDIO WRITE", sdiodrv_dma_write_cb, &g_drv, &g_drv.dma_tx_channel);
389         if (rc != 0) {
390                 PERR("sdiodrv_dma_init() omap_request_dma(TIWLAN_MMC_DMA_TX) FAILED\n");
391                 goto out;
392         }
393
394         rc = omap_request_dma(TIWLAN_MMC_DMA_RX, "SDIO READ", sdiodrv_dma_read_cb, &g_drv, &g_drv.dma_rx_channel);
395         if (rc != 0) {
396                 PERR("sdiodrv_dma_init() omap_request_dma(TIWLAN_MMC_DMA_RX) FAILED\n");
397                 goto freetx;
398         }
399
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);
404   
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);
409
410         return 0;
411
412 freetx:
413         omap_free_dma(g_drv.dma_tx_channel);
414 out:
415         return rc;
416 }
417
418 static void sdiodrv_dma_shutdown(void)
419 {
420         omap_free_dma(g_drv.dma_tx_channel);
421         omap_free_dma(g_drv.dma_rx_channel);
422 } /* sdiodrv_dma_shutdown() */
423
424 static u32 sdiodrv_poll_status(u32 reg_offset, u32 stat, unsigned int msecs)
425 {
426         u32 status=0, loops=0;
427
428         do
429         {
430                 status = OMAP_HSMMC_READ_OFFSET(reg_offset);
431                 if(( status & stat))
432                 {
433                         break;
434                 }
435         } while (loops++ < SDIODRV_MAX_LOOPS);
436
437         return status;
438 } /* sdiodrv_poll_status */
439
440 void dumpreg(void)
441 {
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 ));
465 }
466
467 //cmd flow p. 3609 obc
468 static int sdiodrv_send_command(u32 cmdreg, u32 cmdarg)
469 {
470         OMAP_HSMMC_WRITE(STAT, OMAP_HSMMC_STAT_CLEAR);
471         OMAP_HSMMC_SEND_COMMAND(cmdreg, cmdarg);
472
473         return sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS);
474 } /* sdiodrv_send_command() */
475
476 /*
477  *  Disable clock to the card
478  */
479 static void OMAP3430_mmc_stop_clock(void)
480 {
481         OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) & ~CEN);
482         if ((OMAP_HSMMC_READ(SYSCTL) & CEN) != 0x0)
483     {
484                 PERR("MMC clock not stoped, clock freq can not be altered\n");
485     }
486 } /* OMAP3430_mmc_stop_clock */
487
488 /*
489  *  Reset the SD system
490  */
491 int OMAP3430_mmc_reset(void)
492 {
493         int status, loops=0;
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);
497         if (status & SRA)
498         {
499             PERR("OMAP3430_mmc_reset() MMC reset FAILED!! status=0x%x\n",status);
500         }
501
502         return status;
503
504 } /* OMAP3430_mmc_reset */
505
506 //p. 3611
507 static void OMAP3430_mmc_set_clock(unsigned int clock, OMAP3430_sdiodrv_t *host)
508 {
509         u16           dsor = 0;
510         unsigned long regVal;
511         int           status;
512
513         PDEBUG("OMAP3430_mmc_set_clock(%d)\n",clock);
514         if (clock) {
515                 /* Enable MMC_SD_CLK */
516                 dsor = OMAP_MMC_MASTER_CLOCK / clock;
517                 if (dsor < 1) {
518                         dsor = 1;
519                 }
520                 if (OMAP_MMC_MASTER_CLOCK / dsor > clock) {
521                         dsor++;
522                 }
523                 if (dsor > 250) {
524                         dsor = 250;
525                 }
526         }
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
534         /* 
535      * wait till the the clock is stable (ICS) bit is set
536          */
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);
540         }
541         /* 
542          * Enable clock to the card
543          */
544         OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | CEN);
545
546 } /* OMAP3430_mmc_set_clock() */
547
548 static void sdiodrv_free_resources(void)
549 {
550         if(g_drv.ifclks_enabled) {
551                 sdioDrv_clk_disable();
552         }
553
554         if (sdiodrv_fclk_got) {
555                 clk_put(g_drv.fclk);
556                 sdiodrv_fclk_got = 0;
557         }
558
559         if (sdiodrv_iclk_got) {
560                 clk_put(g_drv.iclk);
561                 sdiodrv_iclk_got = 0;
562         }
563
564         if (sdiodrv_irq_requested) {
565                 free_irq(OMAP_MMC_IRQ, &g_drv);
566                 sdiodrv_irq_requested = 0;
567         }
568 }
569
570 int sdioDrv_InitHw(void)
571 {
572         return 0;
573 } /* sdioDrv_InitHw */
574
575 void sdiodrv_shutdown(void)
576 {
577         PDEBUG("entering %s()\n" , __FUNCTION__ );
578
579         sdiodrv_free_resources();
580
581         PDEBUG("exiting %s\n", __FUNCTION__);
582 } /* sdiodrv_shutdown() */
583
584 static int sdiodrv_send_data_xfer_commad(u32 cmd, u32 cmdarg, int length, u32 buffer_enable_status, unsigned int bBlkMode)
585 {
586     int status;
587
588         PDEBUG("%s() writing CMD 0x%x ARG 0x%x\n",__FUNCTION__, cmd, cmdarg);
589
590     /* block mode */
591         if(bBlkMode) {
592         /* 
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. 
597          */
598         OMAP_HSMMC_WRITE(BLK, (length << 16) | (g_drv.uBlkSize << 0));
599
600         /*
601          * In CMD reg:
602          * BCE: Block Count Enable
603          * MSBS: Multi/Single block select
604          */
605         cmd |= MSBS | BCE ;
606         } else {
607         OMAP_HSMMC_WRITE(BLK, length);
608     }
609
610     status = sdiodrv_send_command(cmd, cmdarg);
611         if(!(status & CC)) {
612             PERR("sdiodrv_send_data_xfer_commad() SDIO Command error! STAT = 0x%x\n", status);
613             return 0;
614         }
615         PDEBUG("%s() length = %d(%dw) BLK = 0x%x\n",
616                    __FUNCTION__, length,((length + 3) >> 2), OMAP_HSMMC_READ(BLK));
617
618     return sdiodrv_poll_status(OMAP_HSMMC_PSTATE, buffer_enable_status, MMC_TIMEOUT_MS);
619
620 } /* sdiodrv_send_data_xfer_commad() */
621
622 int sdiodrv_data_xfer_sync(u32 cmd, u32 cmdarg, void *data, int length, u32 buffer_enable_status)
623 {
624     u32 buf_start, buf_end, data32;
625         int status;
626
627     status = sdiodrv_send_data_xfer_commad(cmd, cmdarg, length, buffer_enable_status, 0);
628         if(!(status & buffer_enable_status)) 
629     {
630             PERR("sdiodrv_data_xfer_sync() buffer disabled! length = %d BLK = 0x%x PSTATE = 0x%x\n", 
631                            length, OMAP_HSMMC_READ(BLK), status);
632             return -1;
633         }
634         buf_end = (u32)data+(u32)length;
635
636         //obc need to check BRE/BWE every time, see p. 3605
637         /*
638          * Read loop 
639          */
640         if (buffer_enable_status == BRE)
641         {
642           if (((u32)data & 3) == 0) /* 4 bytes aligned */
643           {
644                 for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
645                 {
646                   *((unsigned long*)(data)) = OMAP_HSMMC_READ(DATA);
647                 }
648           }
649           else                      /* 2 bytes aligned */
650           {
651                 for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
652                 {
653                   data32 = OMAP_HSMMC_READ(DATA);
654                   *((unsigned short *)data)     = (unsigned short)data32;
655                   *((unsigned short *)data + 1) = (unsigned short)(data32 >> 16);
656                 }
657           }
658         }
659         /*
660          * Write loop 
661          */
662         else
663         {
664           if (((u32)data & 3) == 0) /* 4 bytes aligned */
665           {
666                 for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
667                 {
668                   OMAP_HSMMC_WRITE(DATA,*((unsigned long*)(data)));
669                 }
670           }
671           else                      /* 2 bytes aligned */
672           {
673                 for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
674                 {
675                   OMAP_HSMMC_WRITE(DATA,*((unsigned short*)data) | *((unsigned short*)data+1) << 16 );
676                 }
677
678           }
679         }
680         status  = sdiodrv_poll_status(OMAP_HSMMC_STAT, TC, MMC_TIMEOUT_MS);
681         if(!(status & TC)) 
682         {
683             PERR("sdiodrv_data_xfer_sync() transfer error! STAT = 0x%x\n", status);
684             return -1;
685         }
686
687         return 0;
688
689 } /* sdiodrv_data_xfer_sync() */
690
691 int sdioDrv_ConnectBus (void *       fCbFunc,
692                         void *       hCbArg,
693                         unsigned int uBlkSizeShift,
694                         unsigned int  uSdioThreadPriority)
695 {
696         g_drv.BusTxnCB      = fCbFunc;
697         g_drv.BusTxnHandle  = hCbArg;
698         g_drv.uBlkSizeShift = uBlkSizeShift;  
699         g_drv.uBlkSize      = 1 << uBlkSizeShift;
700
701         INIT_WORK(&g_drv.sdiodrv_work, sdiodrv_task);
702
703         return sdioDrv_InitHw ();
704 }
705
706 /*--------------------------------------------------------------------------------------*/
707
708 int sdioDrv_DisconnectBus (void)
709 {
710         /* Disable clocks to handle driver stop command */
711         sdioDrv_clk_disable();
712         return 0;
713 }
714
715 //p.3609 cmd flow
716 int sdioDrv_ExecuteCmd (unsigned int uCmd, 
717                         unsigned int uArg, 
718                         unsigned int uRespType, 
719                         void *       pResponse, 
720                         unsigned int uLen)
721 {
722         unsigned int uCmdReg   = 0;
723         unsigned int uStatus   = 0;
724         unsigned int uResponse = 0;
725
726         PDEBUG("sdioDrv_ExecuteCmd() starting cmd %02x arg %08x\n", (int)uCmd, (int)uArg);
727
728         sdioDrv_clk_enable(); /* To make sure we have clocks enable */
729
730         uCmdReg = (uCmd << 24) | (uRespType << 16) ;
731
732         uStatus = sdiodrv_send_command(uCmdReg, uArg);
733
734         if (!(uStatus & CC)) 
735         {
736             PERR("sdioDrv_ExecuteCmd() SDIO Command error status = 0x%x\n", uStatus);
737             return -1;
738         }
739         if ((uLen > 0) && (uLen <= 4))/*obc - Len > 4 ? shouldn't read anything ? */
740         {
741             uResponse = OMAP_HSMMC_READ(RSP10);
742                 memcpy (pResponse, (char *)&uResponse, uLen);
743                 PDEBUG("sdioDrv_ExecuteCmd() response = 0x%x\n", uResponse);
744         }
745         return 0;
746 }
747
748 /*--------------------------------------------------------------------------------------*/
749
750 int sdioDrv_ReadSync (unsigned int uFunc, 
751                       unsigned int uHwAddr, 
752                       void *       pData, 
753                       unsigned int uLen,
754                       unsigned int bIncAddr,
755                       unsigned int bMore)
756 {
757         unsigned int uCmdArg;
758         int          iStatus;
759
760 //      printk(KERN_INFO "in sdioDrv_ReadSync\n");
761         uCmdArg = SDIO_CMD53_READ(0, uFunc, 0, bIncAddr, uHwAddr, uLen);
762
763         iStatus = sdiodrv_data_xfer_sync(OMAP_HSMMC_CMD53_READ, uCmdArg, pData, uLen, BRE);
764         if (iStatus != 0) {
765                 PERR("sdioDrv_ReadSync() FAILED!!\n");
766         }
767 #ifdef TI_SDIO_DEBUG
768         if (uLen == 1)
769                 printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(char *)pData));
770         else if (uLen == 2)
771                 printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(short *)pData));
772         else if (uLen == 4)
773                 printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(long *)pData));
774         else
775                 printk(KERN_INFO "R53: [0x%x](%u)\n", uHwAddr, uLen);
776 #endif
777         return iStatus;
778 }
779
780 /*--------------------------------------------------------------------------------------*/
781 int sdioDrv_ReadAsync (unsigned int uFunc, 
782                        unsigned int uHwAddr, 
783                        void *       pData, 
784                        unsigned int uLen, 
785                        unsigned int bBlkMode,
786                        unsigned int bIncAddr,
787                        unsigned int bMore)
788 {
789         int          iStatus;
790         unsigned int uCmdArg;
791         unsigned int uNumBlks;
792         unsigned int uDmaBlockCount;
793         unsigned int uNumOfElem;
794         dma_addr_t dma_bus_address;
795
796 #ifdef TI_SDIO_DEBUG
797         printk(KERN_INFO "R53: [0x%x](%u) F[%d]\n", uHwAddr, uLen, uFunc);
798 #endif
799
800         //printk(KERN_INFO "in sdioDrv_ReadAsync\n");
801
802     if (bBlkMode)
803     {
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;
809     }
810     else
811     {   
812         uNumBlks = uLen;
813         uDmaBlockCount = 1;
814         uNumOfElem = (uLen + 3) >> 2;
815     }
816
817     uCmdArg = SDIO_CMD53_READ(0, uFunc, bBlkMode, bIncAddr, uHwAddr, uNumBlks);
818
819     iStatus = sdiodrv_send_data_xfer_commad(OMAP_HSMMC_CMD53_READ_DMA, uCmdArg, uNumBlks, BRE, bBlkMode);
820
821     if (!(iStatus & BRE)) 
822     {
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);
825         goto err;
826     }
827
828         sdiodrv_dma_init();
829
830         PDEBUG("sdiodrv_read_async() dma_ch=%d \n",g_drv.dma_rx_channel);
831
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");
835                 goto err;
836         }               
837
838         if (g_drv.dma_read_addr != 0) {
839                 printk(KERN_ERR "sdioDrv_ReadAsync: previous DMA op is not finished!\n");
840                 BUG();
841         }
842         
843         g_drv.dma_read_addr = dma_bus_address;
844         g_drv.dma_read_size = uLen;
845
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,
849                                                                         dma_bus_address,
850                                                                         0, 0);
851
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);
853
854         omap_start_dma(g_drv.dma_rx_channel);
855
856         /* Continued at sdiodrv_irq() after DMA transfer is finished */
857 #ifdef TI_SDIO_DEBUG
858         printk(KERN_INFO "R53: [0x%x](%u) (A)\n", uHwAddr, uLen);
859 #endif
860         return 0;
861 err:
862         return -1;
863
864 }
865
866
867 /*--------------------------------------------------------------------------------------*/
868
869 int sdioDrv_WriteSync (unsigned int uFunc, 
870                        unsigned int uHwAddr, 
871                        void *       pData, 
872                        unsigned int uLen,
873                        unsigned int bIncAddr,
874                        unsigned int bMore)
875 {
876         unsigned int uCmdArg;
877         int          iStatus;
878
879 //      printk(KERN_INFO "in sdioDrv_WriteSync\n");
880
881         uCmdArg = SDIO_CMD53_WRITE(1, uFunc, 0, bIncAddr, uHwAddr, uLen);
882
883         iStatus = sdiodrv_data_xfer_sync(OMAP_HSMMC_CMD53_WRITE, uCmdArg, pData, uLen, BWE);
884         if (iStatus != 0)
885         {
886                 PERR("sdioDrv_WriteSync() FAILED!!\n");
887         }
888 #ifdef TI_SDIO_DEBUG
889         if (uLen == 1)
890                 printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(char *)pData));
891         else if (uLen == 2)
892                 printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(short *)pData));
893         else if (uLen == 4)
894                 printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(long *)pData));
895         else
896                 printk(KERN_INFO "W53: [0x%x](%u)\n", uHwAddr, uLen);
897 #endif
898         return iStatus;
899 }
900
901 /*--------------------------------------------------------------------------------------*/
902 int sdioDrv_WriteAsync (unsigned int uFunc, 
903                         unsigned int uHwAddr, 
904                         void *       pData, 
905                         unsigned int uLen, 
906                         unsigned int bBlkMode,
907                         unsigned int bIncAddr,
908                         unsigned int bMore)
909 {
910         int          iStatus;
911         unsigned int uCmdArg;
912         unsigned int uNumBlks;
913         unsigned int uDmaBlockCount;
914         unsigned int uNumOfElem;
915         dma_addr_t dma_bus_address;
916
917 #ifdef TI_SDIO_DEBUG
918         printk(KERN_INFO "W53: [0x%x](%u) F[%d] B[%d] I[%d]\n", uHwAddr, uLen, uFunc, bBlkMode, bIncAddr);
919 #endif
920
921 //      printk(KERN_INFO "in sdioDrv_WriteAsync\n");
922     if (bBlkMode)
923     {
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;
929     }
930     else
931     {
932         uNumBlks = uLen;
933         uDmaBlockCount = 1;
934         uNumOfElem = (uLen + 3) >> 2;
935     }
936
937     uCmdArg = SDIO_CMD53_WRITE(1, uFunc, bBlkMode, bIncAddr, uHwAddr, uNumBlks);
938
939     iStatus = sdiodrv_send_data_xfer_commad(OMAP_HSMMC_CMD53_WRITE_DMA, uCmdArg, uNumBlks, BWE, bBlkMode);
940     if (!(iStatus & BWE)) 
941     {
942         PERR("sdioDrv_WriteAsync() buffer disabled! length = %d, BLK = 0x%x, Status = 0x%x\n", 
943              uLen, OMAP_HSMMC_READ(BLK), iStatus);
944         goto err;
945     }
946
947         OMAP_HSMMC_WRITE(ISE, TC);
948
949         sdiodrv_dma_init();
950
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");
954                 goto err;
955         }
956
957         if (g_drv.dma_write_addr != 0) {
958                 PERR("sdioDrv_WriteAsync: previous DMA op is not finished!\n");
959                 BUG();
960         }
961         
962         g_drv.dma_write_addr = dma_bus_address;
963         g_drv.dma_write_size = uLen;
964
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,
968                                                                         dma_bus_address,
969                                                                         0, 0);
970
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);
972
973         omap_start_dma(g_drv.dma_tx_channel);
974
975         /* Continued at sdiodrv_irq() after DMA transfer is finished */
976         return 0;
977 err:
978         return -1;
979 }
980
981 /*--------------------------------------------------------------------------------------*/
982
983 int sdioDrv_ReadSyncBytes (unsigned int  uFunc, 
984                            unsigned int  uHwAddr, 
985                            unsigned char *pData, 
986                            unsigned int  uLen, 
987                            unsigned int  bMore)
988 {
989         unsigned int uCmdArg;
990         unsigned int i;
991         int          iStatus;
992
993         for (i = 0; i < uLen; i++) {
994                 uCmdArg = SDIO_CMD52_READ(0, uFunc, 0, uHwAddr);
995
996                 iStatus = sdiodrv_send_command(OMAP_HSMMC_CMD52_READ, uCmdArg);
997
998                 if (!(iStatus & CC)) {
999                         PERR("sdioDrv_ReadSyncBytes() SDIO Command error status = 0x%x\n", iStatus);
1000                         return -1;
1001                 }
1002                 else {
1003                         *pData = (unsigned char)(OMAP_HSMMC_READ(RSP10));
1004                 }
1005 #ifdef TI_SDIO_DEBUG
1006                 printk(KERN_INFO "R52: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)*pData);
1007 #endif
1008                 uHwAddr++;
1009                 pData++;
1010         }
1011
1012         return 0;
1013 }
1014
1015 /*--------------------------------------------------------------------------------------*/
1016
1017 int sdioDrv_WriteSyncBytes (unsigned int  uFunc, 
1018                             unsigned int  uHwAddr, 
1019                             unsigned char *pData, 
1020                             unsigned int  uLen, 
1021                             unsigned int  bMore)
1022 {
1023         unsigned int uCmdArg;
1024         unsigned int i;
1025         int          iStatus;
1026
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);
1030 #endif
1031                 uCmdArg = SDIO_CMD52_WRITE(1, uFunc, 0, uHwAddr, *pData);
1032
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);
1036                         return -1;
1037                 }
1038                 uHwAddr++;
1039                 pData++;
1040         }
1041
1042         return 0;
1043 }
1044
1045 static int sdioDrv_probe(struct platform_device *pdev)
1046 {
1047         int rc;
1048         u32 status;
1049 #ifdef SDIO_1_BIT /* see also in SdioAdapter.c */
1050         unsigned long clock_rate = 6000000;
1051 #else
1052         unsigned long clock_rate = 24000000;
1053 #endif
1054
1055         printk(KERN_INFO "TIWLAN SDIO probe: initializing mmc%d device\n", pdev->id + 1);
1056
1057         /* remember device struct for future DMA operations */
1058         g_drv.dev = &pdev->dev;
1059         g_drv.irq = platform_get_irq(pdev, 0);
1060         if (g_drv.irq < 0)
1061                 return -ENXIO;
1062
1063         rc= request_irq(OMAP_MMC_IRQ, sdiodrv_irq, 0, SDIO_DRIVER_NAME, &g_drv);
1064         if (rc != 0) {
1065                 PERR("sdioDrv_InitHw() - request_irq FAILED!!\n");
1066                 return rc;
1067         }
1068         sdiodrv_irq_requested = 1;
1069
1070         spin_lock_init(&g_drv.clk_lock);
1071
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");
1076 #else
1077         g_drv.fclk = clk_get(&pdev->dev, "mmchs_fck");
1078 #endif
1079         if (IS_ERR(g_drv.fclk)) {
1080                 rc = PTR_ERR(g_drv.fclk);
1081                 PERR("clk_get(fclk) FAILED !!!\n");
1082                 goto err;
1083         }
1084         sdiodrv_fclk_got = 1;
1085
1086 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
1087         g_drv.iclk = clk_get(&dummy_pdev.dev, "ick");
1088 #else
1089         g_drv.iclk = clk_get(&pdev->dev, "mmchs_ick");
1090 #endif
1091         if (IS_ERR(g_drv.iclk)) {
1092                 rc = PTR_ERR(g_drv.iclk);
1093                 PERR("clk_get(iclk) FAILED !!!\n");
1094                 goto err;
1095         }
1096         sdiodrv_iclk_got = 1;
1097         
1098         rc = sdioDrv_clk_enable();
1099         if (rc) {
1100                 PERR("sdioDrv_probe : clk_enable FAILED !!!\n");
1101                 goto err;
1102         }
1103
1104         OMAP3430_mmc_reset();
1105
1106         //obc - init sequence p. 3600,3617
1107         /* 1.8V */
1108         OMAP_HSMMC_WRITE(CAPA,          OMAP_HSMMC_READ(CAPA) | VS18);
1109         OMAP_HSMMC_WRITE(HCTL,          OMAP_HSMMC_READ(HCTL) | SDVS18);//SDVS fits p. 3650
1110         /* clock gating */
1111         OMAP_HSMMC_WRITE(SYSCONFIG, OMAP_HSMMC_READ(SYSCONFIG) | AUTOIDLE);
1112
1113         /* bus power */
1114         OMAP_HSMMC_WRITE(HCTL,          OMAP_HSMMC_READ(HCTL) | SDBP);//SDBP fits p. 3650
1115         /* interrupts */
1116         OMAP_HSMMC_WRITE(ISE,           0);
1117         OMAP_HSMMC_WRITE(IE,            IE_EN_MASK);
1118
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);
1122
1123         /* Bus width */
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));
1127 #else
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
1130 #endif
1131         
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);
1139                 rc = -1;
1140                 goto err;
1141         }
1142         OMAP_HSMMC_WRITE(CON, OMAP_HSMMC_READ(CON) & ~INIT_STREAM);
1143
1144         /* Disabling clocks for now */
1145         sdioDrv_clk_disable();
1146
1147         return 0;
1148 err:
1149         sdiodrv_free_resources();
1150         return rc;
1151 }
1152
1153 static int sdioDrv_remove(struct platform_device *pdev)
1154 {
1155         printk(KERN_INFO "sdioDrv_remove: calling sdiodrv_shutdown\n");
1156         
1157         sdiodrv_shutdown();
1158         
1159         return 0;
1160 }
1161
1162 #ifdef CONFIG_PM
1163 static int sdioDrv_suspend(struct platform_device *pdev, pm_message_t state)
1164 {
1165         printk(KERN_INFO "TISDIO: sdioDrv is suspending\n");
1166         return 0;
1167 }
1168
1169 /* Routine to resume the MMC device */
1170 static int sdioDrv_resume(struct platform_device *pdev)
1171 {
1172         printk(KERN_INFO "TISDIO: sdioDrv is resuming\n");
1173         return 0;
1174 }
1175 #else
1176 #define sdioDrv_suspend         NULL
1177 #define sdioDrv_resume          NULL
1178 #endif
1179
1180 static struct platform_driver sdioDrv_struct = {
1181         .probe          = sdioDrv_probe,
1182         .remove         = sdioDrv_remove,
1183         .suspend        = sdioDrv_suspend,
1184         .resume         = sdioDrv_resume,
1185         .driver         = {
1186                 .name = SDIO_DRIVER_NAME,
1187         },
1188 };
1189
1190 void sdioDrv_register_pm(int (*wlanDrvIf_Start)(void),
1191                                                 int (*wlanDrvIf_Stop)(void))
1192 {
1193         g_drv.wlanDrvIf_pm_resume = wlanDrvIf_Start;
1194         g_drv.wlanDrvIf_pm_suspend = wlanDrvIf_Stop;
1195 }
1196
1197 int sdioDrv_clk_enable(void)
1198 {
1199        unsigned long flags;
1200        int ret = 0;
1201
1202        spin_lock_irqsave(&g_drv.clk_lock, flags);
1203        if (g_drv.ifclks_enabled)
1204                goto done;
1205
1206        ret = clk_enable(g_drv.iclk);
1207        if (ret)
1208               goto clk_en_err1;
1209
1210        ret = clk_enable(g_drv.fclk);
1211        if (ret)
1212                goto clk_en_err2;
1213        g_drv.ifclks_enabled = 1;
1214
1215        sdioDrv_hsmmc_restore_ctx();
1216
1217 done:
1218        spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1219        return ret;
1220
1221 clk_en_err2:
1222        clk_disable(g_drv.iclk);
1223 clk_en_err1 :
1224        spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1225        return ret;
1226 }
1227
1228 void sdioDrv_clk_disable(void)
1229 {
1230        unsigned long flags;
1231
1232        spin_lock_irqsave(&g_drv.clk_lock, flags);
1233        if (!g_drv.ifclks_enabled)
1234                goto done;
1235
1236        sdioDrv_hsmmc_save_ctx();
1237
1238        clk_disable(g_drv.fclk);
1239        clk_disable(g_drv.iclk);
1240        g_drv.ifclks_enabled = 0;
1241 done:
1242        spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1243 }
1244
1245 #ifdef TI_SDIO_STANDALONE
1246 static int __init sdioDrv_init(void)
1247 #else
1248 int __init sdioDrv_init(int sdcnum)
1249 #endif
1250 {
1251         memset(&g_drv, 0, sizeof(g_drv));
1252         memset(&hsmmc_ctx, 0, sizeof(hsmmc_ctx));
1253
1254         printk(KERN_INFO "TIWLAN SDIO init\n");
1255 #ifndef TI_SDIO_STANDALONE
1256         sdio_init( sdcnum );
1257 #endif
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");
1261                 return -EINVAL;
1262         }
1263         /* Register the sdio driver */
1264         return platform_driver_register(&sdioDrv_struct);
1265 }
1266
1267 #ifdef TI_SDIO_STANDALONE
1268 static
1269 #endif
1270 void __exit sdioDrv_exit(void)
1271 {
1272         /* Unregister sdio driver */
1273         platform_driver_unregister(&sdioDrv_struct);
1274         if (g_drv.sdio_wq)
1275                 destroy_workqueue(g_drv.sdio_wq);
1276 }
1277
1278 #ifdef TI_SDIO_STANDALONE
1279 module_init(sdioDrv_init);
1280 module_exit(sdioDrv_exit);
1281 #endif
1282
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");
1297 #endif