1/*
2 * SdioDrv.c
3 *
4 * Copyright (C) 2009 Texas Instruments, Inc. - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/version.h>
19#include <linux/moduleparam.h>
20#include <linux/delay.h>
21#include <linux/interrupt.h>
22#include <linux/slab.h>
23#include <linux/types.h>
24#include <linux/dma-mapping.h>
25#include <linux/platform_device.h>
26#include <linux/i2c/twl4030.h>
27#include <linux/errno.h>
28#include <linux/clk.h>
29#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
30#include <plat/hardware.h>
31#include <plat/board.h>
32#include <plat/clock.h>
33#include <plat/dma.h>
34#include <plat/io.h>
35#include <plat/resource.h>
36#define IO_ADDRESS(pa)	OMAP2_L4_IO_ADDRESS(pa)
37#else
38#include <mach/hardware.h>
39#include <mach/board.h>
40#include <mach/clock.h>
41#include <mach/dma.h>
42#include <mach/io.h>
43#include <mach/resource.h>
44#endif
45typedef void *TI_HANDLE;
46#include "host_platform.h"
47#include "SdioDrvDbg.h"
48#include "SdioDrv.h"
49
50/* #define TI_SDIO_DEBUG */
51
52#ifndef CONFIG_MMC_EMBEDDED_SDIO
53
54#define SDIOWQ_NAME			"sdio_wq"
55
56/*
57 * HSMMC Address and DMA Settings
58 */
59static unsigned long TIWLAN_MMC_CONTROLLER = 2; /* MMC3 */
60static unsigned long TIWLAN_MMC_CONTROLLER_BASE_ADDR = OMAP_HSMMC3_BASE;
61#define TIWLAN_MMC_CONTROLLER_BASE_SIZE	512
62#define TIWLAN_MMC_MAX_DMA		8192
63static unsigned long TIWLAN_MMC_DMA_TX = OMAP34XX_DMA_MMC3_TX;
64static unsigned long TIWLAN_MMC_DMA_RX = OMAP34XX_DMA_MMC3_RX;
65static unsigned long OMAP_MMC_IRQ = INT_MMC3_IRQ;
66
67#define OMAP_MMC_MASTER_CLOCK          96000000
68/*
69 *  HSMMC Host Controller Registers
70 */
71#define OMAP_HSMMC_SYSCONFIG           0x0010
72#define OMAP_HSMMC_SYSSTATUS           0x0014
73#define OMAP_HSMMC_CSRE                0x0024
74#define OMAP_HSMMC_SYSTEST             0x0028
75#define OMAP_HSMMC_CON                 0x002C
76#define OMAP_HSMMC_BLK                 0x0104
77#define OMAP_HSMMC_ARG                 0x0108
78#define OMAP_HSMMC_CMD                 0x010C
79#define OMAP_HSMMC_RSP10               0x0110
80#define OMAP_HSMMC_RSP32               0x0114
81#define OMAP_HSMMC_RSP54               0x0118
82#define OMAP_HSMMC_RSP76               0x011C
83#define OMAP_HSMMC_DATA                0x0120
84#define OMAP_HSMMC_PSTATE              0x0124
85#define OMAP_HSMMC_HCTL                0x0128
86#define OMAP_HSMMC_SYSCTL              0x012C
87#define OMAP_HSMMC_STAT                0x0130
88#define OMAP_HSMMC_IE                  0x0134
89#define OMAP_HSMMC_ISE                 0x0138
90#define OMAP_HSMMC_AC12                0x013C
91#define OMAP_HSMMC_CAPA                0x0140
92#define OMAP_HSMMC_CUR_CAPA            0x0148
93#define OMAP_HSMMC_REV                 0x01FC
94
95#define VS18                           (1 << 26)
96#define VS30                           (1 << 25)
97#define SRA                            (1 << 24)
98#define SDVS18                         (0x5 << 9)
99#define SDVS30                         (0x6 << 9)
100#define SDVSCLR                        0xFFFFF1FF
101#define SDVSDET                        0x00000400
102#define SIDLE_MODE                     (0x2 << 3)
103#define AUTOIDLE                       0x1
104#define SDBP                           (1 << 8)
105#define DTO                            0xE
106#define ICE                            0x1
107#define ICS                            0x2
108#define CEN                            (1 << 2)
109#define CLKD_MASK                      0x0000FFC0
110#define IE_EN_MASK                     0x317F0137
111#define INIT_STREAM                    (1 << 1)
112#define DP_SELECT                      (1 << 21)
113#define DDIR                           (1 << 4)
114#define DMA_EN                         0x1
115#define MSBS                           (1 << 5)
116#define BCE                            (1 << 1)
117#define ONE_BIT                        (~(0x2))
118#define EIGHT_BIT                      (~(0x20))
119#define CC                             0x1
120#define TC                             0x02
121#define OD                             0x1
122#define BRW                            0x400
123#define BRR                            0x800
124#define BRE                            (1 << 11)
125#define BWE                            (1 << 10)
126#define SBGR                           (1 << 16)
127#define CT                             (1 << 17)
128#define SDIO_READ                      (1 << 31)
129#define SDIO_BLKMODE                   (1 << 27)
130#define OMAP_HSMMC_ERR                 (1 << 15)  /* Any error */
131#define OMAP_HSMMC_CMD_TIMEOUT         (1 << 16)  /* Com mand response time-out */
132#define OMAP_HSMMC_DATA_TIMEOUT        (1 << 20)  /* Data response time-out */
133#define OMAP_HSMMC_CMD_CRC             (1 << 17)  /* Command CRC error */
134#define OMAP_HSMMC_DATA_CRC            (1 << 21)  /* Date CRC error */
135#define OMAP_HSMMC_CARD_ERR            (1 << 28)  /* Card ERR */
136#define OMAP_HSMMC_STAT_CLEAR          0xFFFFFFFF
137#define INIT_STREAM_CMD                0x00000000
138#define INT_CLEAR                      0x00000000
139#define BLK_CLEAR                      0x00000000
140
141/* SCM CONTROL_DEVCONF1 MMC1 overwrite but */
142
143#define MMC1_ACTIVE_OVERWRITE          (1 << 31)
144
145#define sdio_blkmode_regaddr           0x2000
146#define sdio_blkmode_mask              0xFF00
147
148#define IO_RW_DIRECT_MASK              0xF000FF00
149#define IO_RW_DIRECT_ARG_MASK          0x80001A00
150
151#define RMASK                          (MMC_RSP_MASK | MMC_RSP_CRC)
152#define MMC_TIMEOUT_MS                 100 /*on the new 2430 it was 20, i changed back to 100*//* obc */
153#define MMCA_VSN_4                     4
154
155#define VMMC1_DEV_GRP                  0x27
156#define P1_DEV_GRP                     0x20
157#define VMMC1_DEDICATED                0x2A
158#define VSEL_3V                        0x02
159#define VSEL_18V                       0x00
160#define PBIAS_3V                       0x03
161#define PBIAS_18V                      0x02
162#define PBIAS_LITE                     0x04A0
163#define PBIAS_CLR                      0x00
164
165#define OMAP_MMC_REGS_BASE             IO_ADDRESS(TIWLAN_MMC_CONTROLLER_BASE_ADDR)
166
167/*
168 * MMC Host controller read/write API's.
169 */
170#define OMAP_HSMMC_READ_OFFSET(offset) (__raw_readl((OMAP_MMC_REGS_BASE) + (offset)))
171#define OMAP_HSMMC_READ(reg)           (__raw_readl((OMAP_MMC_REGS_BASE) + OMAP_HSMMC_##reg))
172#define OMAP_HSMMC_WRITE(reg, val)     (__raw_writel((val), (OMAP_MMC_REGS_BASE) + OMAP_HSMMC_##reg))
173
174#define OMAP_HSMMC_SEND_COMMAND(cmd, arg) do \
175{ \
176	OMAP_HSMMC_WRITE(ARG, arg); \
177	OMAP_HSMMC_WRITE(CMD, cmd); \
178} while (0)
179
180#define OMAP_HSMMC_CMD52_WRITE     ((SD_IO_RW_DIRECT    << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16))
181#define OMAP_HSMMC_CMD52_READ      (((SD_IO_RW_DIRECT   << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DDIR)
182#define OMAP_HSMMC_CMD53_WRITE     (((SD_IO_RW_EXTENDED << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DP_SELECT)
183#define OMAP_HSMMC_CMD53_READ      (((SD_IO_RW_EXTENDED << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DP_SELECT | DDIR)
184#define OMAP_HSMMC_CMD53_READ_DMA  (OMAP_HSMMC_CMD53_READ  | DMA_EN)
185#define OMAP_HSMMC_CMD53_WRITE_DMA (OMAP_HSMMC_CMD53_WRITE | DMA_EN)
186
187/* Macros to build commands 52 and 53 in format according to SDIO spec */
188#define SDIO_CMD52_READ(v1,v2,v3,v4)        (SDIO_RWFLAG(v1)|SDIO_FUNCN(v2)|SDIO_RAWFLAG(v3)| SDIO_ADDRREG(v4))
189#define SDIO_CMD52_WRITE(v1,v2,v3,v4,v5)    (SDIO_RWFLAG(v1)|SDIO_FUNCN(v2)|SDIO_RAWFLAG(v3)| SDIO_ADDRREG(v4)|(v5))
190#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))
191#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))
192
193#define SDIODRV_MAX_LOOPS	50000
194
195#define VMMC2_DEV_GRP		0x2B
196#define VMMC2_DEDICATED		0x2E
197#define VSEL_S2_18V		0x05
198#define LDO_CLR			0x00
199#define VSEL_S2_CLR		0x40
200#define GPIO_0_BIT_POS		1 << 0
201#define GPIO_1_BIT_POS		1 << 1
202#define VSIM_DEV_GRP		0x37
203#define VSIM_DEDICATED		0x3A
204#define TWL4030_MODULE_PM_RECIEVER	0x13
205
206typedef struct OMAP3430_sdiodrv
207{
208	struct clk    *fclk, *iclk, *dbclk;
209	int           ifclks_enabled;
210	spinlock_t    clk_lock;
211	int           dma_tx_channel;
212	int           dma_rx_channel;
213	int           irq;
214	void          (*BusTxnCB)(void* BusTxnHandle, int status);
215	void*         BusTxnHandle;
216	unsigned int  uBlkSize;
217	unsigned int  uBlkSizeShift;
218	char          *dma_buffer;
219	void          *async_buffer;
220	unsigned int  async_length;
221	int           async_status;
222	int (*wlanDrvIf_pm_resume)(void);
223	int (*wlanDrvIf_pm_suspend)(void);
224	struct device *dev;
225	dma_addr_t dma_read_addr;
226	size_t dma_read_size;
227	dma_addr_t dma_write_addr;
228	size_t dma_write_size;
229	struct workqueue_struct *sdio_wq; /* Work Queue */
230	struct work_struct sdiodrv_work;
231} OMAP3430_sdiodrv_t;
232
233struct omap_hsmmc_regs {
234        u32 hctl;
235        u32 capa;
236        u32 sysconfig;
237        u32 ise;
238        u32 ie;
239        u32 con;
240        u32 sysctl;
241};
242static struct omap_hsmmc_regs hsmmc_ctx;
243
244#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
245static struct platform_device dummy_pdev = {
246	.dev = {
247		.bus = &platform_bus_type,
248	},
249};
250#endif
251
252#define SDIO_DRIVER_NAME 			"TIWLAN_SDIO"
253
254module_param(g_sdio_debug_level, int, 0644);
255MODULE_PARM_DESC(g_sdio_debug_level, "debug level");
256int g_sdio_debug_level = SDIO_DEBUGLEVEL_ERR;
257EXPORT_SYMBOL(g_sdio_debug_level);
258
259OMAP3430_sdiodrv_t g_drv;
260
261static int sdiodrv_dma_on = 0;
262static int sdiodrv_irq_requested = 0;
263static int sdiodrv_iclk_got = 0;
264static int sdiodrv_fclk_got = 0;
265
266int sdioDrv_clk_enable(void);
267void sdioDrv_clk_disable(void);
268static void sdioDrv_hsmmc_save_ctx(void);
269static void sdioDrv_hsmmc_restore_ctx(void);
270
271#ifndef TI_SDIO_STANDALONE
272void sdio_init( int sdcnum )
273{
274	if( sdcnum <= 0 )
275		return;
276	TIWLAN_MMC_CONTROLLER = sdcnum - 1;
277	if( sdcnum == 2 ) {
278		TIWLAN_MMC_CONTROLLER_BASE_ADDR = OMAP_HSMMC2_BASE;
279		TIWLAN_MMC_DMA_TX = OMAP24XX_DMA_MMC2_TX;
280		TIWLAN_MMC_DMA_RX = OMAP24XX_DMA_MMC2_RX;
281		OMAP_MMC_IRQ = INT_MMC2_IRQ;
282	}
283	else if( sdcnum == 3 ) {
284		TIWLAN_MMC_CONTROLLER_BASE_ADDR	= OMAP_HSMMC3_BASE;
285		TIWLAN_MMC_DMA_TX = OMAP34XX_DMA_MMC3_TX;
286		TIWLAN_MMC_DMA_RX = OMAP34XX_DMA_MMC3_RX;
287		OMAP_MMC_IRQ = INT_MMC3_IRQ;
288	}
289}
290#endif
291
292static void sdioDrv_hsmmc_save_ctx(void)
293{
294	/* MMC : context save */
295	hsmmc_ctx.hctl = OMAP_HSMMC_READ(HCTL);
296	hsmmc_ctx.capa = OMAP_HSMMC_READ(CAPA);
297	hsmmc_ctx.sysconfig = OMAP_HSMMC_READ(SYSCONFIG);
298	hsmmc_ctx.ise = OMAP_HSMMC_READ(ISE);
299	hsmmc_ctx.ie = OMAP_HSMMC_READ(IE);
300	hsmmc_ctx.con = OMAP_HSMMC_READ(CON);
301	hsmmc_ctx.sysctl = OMAP_HSMMC_READ(SYSCTL);
302	OMAP_HSMMC_WRITE(ISE, 0);
303	OMAP_HSMMC_WRITE(IE, 0);
304}
305
306static void sdioDrv_hsmmc_restore_ctx(void)
307{
308        /* MMC : context restore */
309        OMAP_HSMMC_WRITE(HCTL, hsmmc_ctx.hctl);
310        OMAP_HSMMC_WRITE(CAPA, hsmmc_ctx.capa);
311        OMAP_HSMMC_WRITE(SYSCONFIG, hsmmc_ctx.sysconfig);
312        OMAP_HSMMC_WRITE(CON, hsmmc_ctx.con);
313        OMAP_HSMMC_WRITE(ISE, hsmmc_ctx.ise);
314        OMAP_HSMMC_WRITE(IE, hsmmc_ctx.ie);
315        OMAP_HSMMC_WRITE(SYSCTL, hsmmc_ctx.sysctl);
316        OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | SDBP);
317}
318
319void sdiodrv_task(struct work_struct *unused)
320{
321	PDEBUG("sdiodrv_tasklet()\n");
322
323	if (g_drv.dma_read_addr != 0) {
324		dma_unmap_single(g_drv.dev, g_drv.dma_read_addr, g_drv.dma_read_size, DMA_FROM_DEVICE);
325		g_drv.dma_read_addr = 0;
326		g_drv.dma_read_size = 0;
327	}
328
329	if (g_drv.dma_write_addr != 0) {
330		dma_unmap_single(g_drv.dev, g_drv.dma_write_addr, g_drv.dma_write_size, DMA_TO_DEVICE);
331		g_drv.dma_write_addr = 0;
332		g_drv.dma_write_size = 0;
333	}
334
335	if (g_drv.async_buffer) {
336		memcpy(g_drv.async_buffer, g_drv.dma_buffer, g_drv.async_length);
337		g_drv.async_buffer = NULL;
338	}
339
340	if (g_drv.BusTxnCB != NULL) {
341		g_drv.BusTxnCB(g_drv.BusTxnHandle, g_drv.async_status);
342	}
343}
344
345irqreturn_t sdiodrv_irq(int irq, void *drv)
346{
347	int status;
348
349	PDEBUG("sdiodrv_irq()\n");
350
351	status = OMAP_HSMMC_READ(STAT);
352	OMAP_HSMMC_WRITE(ISE, 0);
353	g_drv.async_status = status & (OMAP_HSMMC_ERR);
354	if (g_drv.async_status) {
355		PERR("sdiodrv_irq: ERROR in STAT = 0x%x\n", status);
356	}
357	queue_work(g_drv.sdio_wq, &g_drv.sdiodrv_work);
358	return IRQ_HANDLED;
359}
360
361void sdiodrv_dma_read_cb(int lch, u16 ch_status, void *data)
362{
363	PDEBUG("sdiodrv_dma_read_cb() channel=%d status=0x%x\n", lch, (int)ch_status);
364
365	g_drv.async_status = ch_status & (1 << 7);
366
367	queue_work(g_drv.sdio_wq, &g_drv.sdiodrv_work);
368}
369
370void sdiodrv_dma_write_cb(int lch, u16 ch_status, void *data)
371{
372}
373
374int sdiodrv_dma_init(void)
375{
376	int rc;
377
378	rc = omap_request_dma(TIWLAN_MMC_DMA_TX, "SDIO WRITE", sdiodrv_dma_write_cb, &g_drv, &g_drv.dma_tx_channel);
379	if (rc != 0) {
380		PERR("sdiodrv_dma_init() omap_request_dma(TIWLAN_MMC_DMA_TX) FAILED\n");
381		goto out;
382	}
383
384	rc = omap_request_dma(TIWLAN_MMC_DMA_RX, "SDIO READ", sdiodrv_dma_read_cb, &g_drv, &g_drv.dma_rx_channel);
385	if (rc != 0) {
386		PERR("sdiodrv_dma_init() omap_request_dma(TIWLAN_MMC_DMA_RX) FAILED\n");
387		goto freetx;
388	}
389
390	omap_set_dma_src_params(g_drv.dma_rx_channel,
391  							0,			// src_port is only for OMAP1
392  							OMAP_DMA_AMODE_CONSTANT,
393  							(TIWLAN_MMC_CONTROLLER_BASE_ADDR) + OMAP_HSMMC_DATA, 0, 0);
394
395	omap_set_dma_dest_params(g_drv.dma_tx_channel,
396							0,			// dest_port is only for OMAP1
397  	  						OMAP_DMA_AMODE_CONSTANT,
398  	  						(TIWLAN_MMC_CONTROLLER_BASE_ADDR) + OMAP_HSMMC_DATA, 0, 0);
399
400	if ((g_drv.dma_buffer = kmalloc(TIWLAN_MMC_MAX_DMA, GFP_ATOMIC|GFP_DMA)) == NULL) {
401		rc = -ENOMEM;
402		goto freerx;
403	}
404
405	return 0;
406
407freerx:
408	omap_free_dma(g_drv.dma_rx_channel);
409freetx:
410	omap_free_dma(g_drv.dma_tx_channel);
411out:
412	return rc;
413}
414
415void sdiodrv_dma_shutdown(void)
416{
417	omap_free_dma(g_drv.dma_tx_channel);
418	omap_free_dma(g_drv.dma_rx_channel);
419	if (g_drv.dma_buffer) {
420		kfree(g_drv.dma_buffer);
421		g_drv.dma_buffer = NULL;
422	}
423} /* sdiodrv_dma_shutdown() */
424
425static u32 sdiodrv_poll_status(u32 reg_offset, u32 stat, unsigned int msecs)
426{
427	u32 status=0, loops=0;
428
429	do
430	{
431		status = OMAP_HSMMC_READ_OFFSET(reg_offset);
432		if(( status & stat))
433		{
434			break;
435		}
436	} while (loops++ < SDIODRV_MAX_LOOPS);
437
438	return status;
439} /* sdiodrv_poll_status */
440
441void dumpreg(void)
442{
443	printk(KERN_ERR "\n MMCHS_SYSCONFIG   for mmc3 = %x  ", omap_readl( 0x480AD010 ));
444	printk(KERN_ERR "\n MMCHS_SYSSTATUS   for mmc3 = %x  ", omap_readl( 0x480AD014 ));
445	printk(KERN_ERR "\n MMCHS_CSRE	      for mmc3 = %x  ", omap_readl( 0x480AD024 ));
446	printk(KERN_ERR "\n MMCHS_SYSTEST     for mmc3 = %x  ", omap_readl( 0x480AD028 ));
447	printk(KERN_ERR "\n MMCHS_CON         for mmc3 = %x  ", omap_readl( 0x480AD02C ));
448	printk(KERN_ERR "\n MMCHS_PWCNT       for mmc3 = %x  ", omap_readl( 0x480AD030 ));
449	printk(KERN_ERR "\n MMCHS_BLK         for mmc3 = %x  ", omap_readl( 0x480AD104 ));
450	printk(KERN_ERR "\n MMCHS_ARG         for mmc3 = %x  ", omap_readl( 0x480AD108 ));
451	printk(KERN_ERR "\n MMCHS_CMD         for mmc3 = %x  ", omap_readl( 0x480AD10C ));
452	printk(KERN_ERR "\n MMCHS_RSP10       for mmc3 = %x  ", omap_readl( 0x480AD110 ));
453	printk(KERN_ERR "\n MMCHS_RSP32       for mmc3 = %x  ", omap_readl( 0x480AD114 ));
454	printk(KERN_ERR "\n MMCHS_RSP54       for mmc3 = %x  ", omap_readl( 0x480AD118 ));
455	printk(KERN_ERR "\n MMCHS_RSP76       for mmc3 = %x  ", omap_readl( 0x480AD11C ));
456	printk(KERN_ERR "\n MMCHS_DATA        for mmc3 = %x  ", omap_readl( 0x480AD120 ));
457	printk(KERN_ERR "\n MMCHS_PSTATE      for mmc3 = %x  ", omap_readl( 0x480AD124 ));
458	printk(KERN_ERR "\n MMCHS_HCTL        for mmc3 = %x  ", omap_readl( 0x480AD128 ));
459	printk(KERN_ERR "\n MMCHS_SYSCTL      for mmc3 = %x  ", omap_readl( 0x480AD12C ));
460	printk(KERN_ERR "\n MMCHS_STAT        for mmc3 = %x  ", omap_readl( 0x480AD130 ));
461	printk(KERN_ERR "\n MMCHS_IE          for mmc3 = %x  ", omap_readl( 0x480AD134 ));
462	printk(KERN_ERR "\n MMCHS_ISE         for mmc3 = %x  ", omap_readl( 0x480AD138 ));
463	printk(KERN_ERR "\n MMCHS_AC12        for mmc3 = %x  ", omap_readl( 0x480AD13C ));
464	printk(KERN_ERR "\n MMCHS_CAPA        for mmc3 = %x  ", omap_readl( 0x480AD140 ));
465	printk(KERN_ERR "\n MMCHS_CUR_CAPA    for mmc3 = %x  ", omap_readl( 0x480AD148 ));
466}
467
468//cmd flow p. 3609 obc
469static int sdiodrv_send_command(u32 cmdreg, u32 cmdarg)
470{
471	OMAP_HSMMC_WRITE(STAT, OMAP_HSMMC_STAT_CLEAR);
472	OMAP_HSMMC_SEND_COMMAND(cmdreg, cmdarg);
473
474	return sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS);
475} /* sdiodrv_send_command() */
476
477/*
478 *  Disable clock to the card
479 */
480static void OMAP3430_mmc_stop_clock(void)
481{
482	OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) & ~CEN);
483	if ((OMAP_HSMMC_READ(SYSCTL) & CEN) != 0x0)
484    {
485		PERR("MMC clock not stoped, clock freq can not be altered\n");
486    }
487} /* OMAP3430_mmc_stop_clock */
488
489/*
490 *  Reset the SD system
491 */
492int OMAP3430_mmc_reset(void)
493{
494	int status, loops=0;
495	//p. 3598 - need to set SOFTRESET to 0x1 0bc
496	OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | SRA);
497	while ((status = OMAP_HSMMC_READ(SYSCTL) &  SRA) && loops++ < SDIODRV_MAX_LOOPS);
498	if (status & SRA)
499	{
500	    PERR("OMAP3430_mmc_reset() MMC reset FAILED!! status=0x%x\n",status);
501	}
502
503	return status;
504
505} /* OMAP3430_mmc_reset */
506
507//p. 3611
508static void OMAP3430_mmc_set_clock(unsigned int clock, OMAP3430_sdiodrv_t *host)
509{
510	u16           dsor = 0;
511	unsigned long regVal;
512	int           status;
513
514	PDEBUG("OMAP3430_mmc_set_clock(%d)\n",clock);
515	if (clock) {
516		/* Enable MMC_SD_CLK */
517		dsor = OMAP_MMC_MASTER_CLOCK / clock;
518		if (dsor < 1) {
519			dsor = 1;
520		}
521		if (OMAP_MMC_MASTER_CLOCK / dsor > clock) {
522			dsor++;
523		}
524		if (dsor > 250) {
525			dsor = 250;
526		}
527	}
528	OMAP3430_mmc_stop_clock();
529	regVal = OMAP_HSMMC_READ(SYSCTL);
530	regVal = regVal & ~(CLKD_MASK);//p. 3652
531	regVal = regVal | (dsor << 6);
532	regVal = regVal | (DTO << 16);//data timeout
533	OMAP_HSMMC_WRITE(SYSCTL, regVal);
534	OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | ICE);//internal clock enable. obc not mentioned in the spec
535	/*
536     * wait till the the clock is stable (ICS) bit is set
537	 */
538	status  = sdiodrv_poll_status(OMAP_HSMMC_SYSCTL, ICS, MMC_TIMEOUT_MS);
539	if(!(status & ICS)) {
540	    PERR("OMAP3430_mmc_set_clock() clock not stable!! status=0x%x\n",status);
541	}
542	/*
543	 * Enable clock to the card
544	 */
545	OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | CEN);
546
547} /* OMAP3430_mmc_set_clock() */
548
549static void sdiodrv_free_resources(void)
550{
551	if(g_drv.ifclks_enabled) {
552		sdioDrv_clk_disable();
553	}
554
555	if (sdiodrv_fclk_got) {
556		clk_put(g_drv.fclk);
557		sdiodrv_fclk_got = 0;
558	}
559
560	if (sdiodrv_iclk_got) {
561		clk_put(g_drv.iclk);
562		sdiodrv_iclk_got = 0;
563	}
564
565        if (sdiodrv_irq_requested) {
566                free_irq(OMAP_MMC_IRQ, &g_drv);
567                sdiodrv_irq_requested = 0;
568        }
569
570        if (sdiodrv_dma_on) {
571                sdiodrv_dma_shutdown();
572                sdiodrv_dma_on = 0;
573        }
574}
575
576int sdioDrv_InitHw(void)
577{
578	return 0;
579} /* sdiodrv_init */
580
581void sdiodrv_shutdown(void)
582{
583	PDEBUG("entering %s()\n" , __FUNCTION__ );
584
585	sdiodrv_free_resources();
586
587	PDEBUG("exiting %s\n", __FUNCTION__);
588} /* sdiodrv_shutdown() */
589
590static int sdiodrv_send_data_xfer_commad(u32 cmd, u32 cmdarg, int length, u32 buffer_enable_status, unsigned int bBlkMode)
591{
592    int status;
593
594	PDEBUG("%s() writing CMD 0x%x ARG 0x%x\n",__FUNCTION__, cmd, cmdarg);
595
596    /* block mode */
597	if(bBlkMode) {
598        /*
599         * Bits 31:16 of BLK reg: NBLK Blocks count for current transfer.
600         *                        in case of Block MOde the lenght is treated here as number of blocks
601         *                        (and not as a length).
602         * Bits 11:0 of BLK reg: BLEN Transfer Block Size. in case of block mode set that field to block size.
603         */
604        OMAP_HSMMC_WRITE(BLK, (length << 16) | (g_drv.uBlkSize << 0));
605
606        /*
607         * In CMD reg:
608         * BCE: Block Count Enable
609         * MSBS: Multi/Single block select
610         */
611        cmd |= MSBS | BCE ;
612	} else {
613        OMAP_HSMMC_WRITE(BLK, length);
614    }
615
616    status = sdiodrv_send_command(cmd, cmdarg);
617	if(!(status & CC)) {
618	    PERR("sdiodrv_send_data_xfer_commad() SDIO Command error! STAT = 0x%x\n", status);
619	    return 0;
620	}
621	PDEBUG("%s() length = %d(%dw) BLK = 0x%x\n",
622		   __FUNCTION__, length,((length + 3) >> 2), OMAP_HSMMC_READ(BLK));
623
624    return sdiodrv_poll_status(OMAP_HSMMC_PSTATE, buffer_enable_status, MMC_TIMEOUT_MS);
625
626} /* sdiodrv_send_data_xfer_commad() */
627
628int sdiodrv_data_xfer_sync(u32 cmd, u32 cmdarg, void *data, int length, u32 buffer_enable_status)
629{
630    u32 buf_start, buf_end, data32;
631	int status;
632
633    status = sdiodrv_send_data_xfer_commad(cmd, cmdarg, length, buffer_enable_status, 0);
634	if(!(status & buffer_enable_status))
635    {
636	    PERR("sdiodrv_data_xfer_sync() buffer disabled! length = %d BLK = 0x%x PSTATE = 0x%x\n",
637			   length, OMAP_HSMMC_READ(BLK), status);
638	    return -1;
639	}
640	buf_end = (u32)data+(u32)length;
641
642	//obc need to check BRE/BWE every time, see p. 3605
643	/*
644	 * Read loop
645	 */
646	if (buffer_enable_status == BRE)
647	{
648	  if (((u32)data & 3) == 0) /* 4 bytes aligned */
649	  {
650		for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
651		{
652		  *((unsigned long*)(data)) = OMAP_HSMMC_READ(DATA);
653		}
654	  }
655	  else                      /* 2 bytes aligned */
656	  {
657		for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
658		{
659		  data32 = OMAP_HSMMC_READ(DATA);
660		  *((unsigned short *)data)     = (unsigned short)data32;
661		  *((unsigned short *)data + 1) = (unsigned short)(data32 >> 16);
662		}
663	  }
664	}
665	/*
666	 * Write loop
667	 */
668	else
669	{
670	  if (((u32)data & 3) == 0) /* 4 bytes aligned */
671	  {
672		for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
673		{
674		  OMAP_HSMMC_WRITE(DATA,*((unsigned long*)(data)));
675		}
676	  }
677	  else                      /* 2 bytes aligned */
678	  {
679		for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
680		{
681		  OMAP_HSMMC_WRITE(DATA,*((unsigned short*)data) | *((unsigned short*)data+1) << 16 );
682		}
683
684	  }
685	}
686	status  = sdiodrv_poll_status(OMAP_HSMMC_STAT, TC, MMC_TIMEOUT_MS);
687	if(!(status & TC))
688	{
689	    PERR("sdiodrv_data_xfer_sync() transfer error! STAT = 0x%x\n", status);
690	    return -1;
691	}
692
693	return 0;
694
695} /* sdiodrv_data_xfer_sync() */
696
697int sdioDrv_ConnectBus (void *       fCbFunc,
698                        void *       hCbArg,
699                        unsigned int uBlkSizeShift,
700                        unsigned int uSdioThreadPriority,
701                        unsigned char **pTxDmaSrcAddr)
702{
703	g_drv.BusTxnCB      = fCbFunc;
704	g_drv.BusTxnHandle  = hCbArg;
705	g_drv.uBlkSizeShift = uBlkSizeShift;
706	g_drv.uBlkSize      = 1 << uBlkSizeShift;
707
708	INIT_WORK(&g_drv.sdiodrv_work, sdiodrv_task);
709
710	/* Provide the DMA buffer address to the upper layer so it will use it
711	   as the transactions host buffer. */
712	if (pTxDmaSrcAddr)
713	{
714		*pTxDmaSrcAddr = g_drv.dma_buffer;
715	}
716	return sdioDrv_InitHw ();
717}
718
719int sdioDrv_DisconnectBus (void)
720{
721	sdioDrv_clk_disable(); /* To process Stop command properly */
722	return 0;
723}
724
725//p.3609 cmd flow
726int sdioDrv_ExecuteCmd (unsigned int uCmd,
727                        unsigned int uArg,
728                        unsigned int uRespType,
729                        void *       pResponse,
730                        unsigned int uLen)
731{
732	unsigned int uCmdReg   = 0;
733	unsigned int uStatus   = 0;
734	unsigned int uResponse = 0;
735
736	PDEBUG("sdioDrv_ExecuteCmd() starting cmd %02x arg %08x\n", (int)uCmd, (int)uArg);
737
738	sdioDrv_clk_enable(); /* To make sure we have clocks enable */
739
740	uCmdReg = (uCmd << 24) | (uRespType << 16) ;
741
742	uStatus = sdiodrv_send_command(uCmdReg, uArg);
743
744	if (!(uStatus & CC))
745	{
746	    PERR("sdioDrv_ExecuteCmd() SDIO Command error status = 0x%x\n", uStatus);
747	    return -1;
748	}
749	if ((uLen > 0) && (uLen <= 4))/*obc - Len > 4 ? shouldn't read anything ? */
750	{
751	    uResponse = OMAP_HSMMC_READ(RSP10);
752		memcpy (pResponse, (char *)&uResponse, uLen);
753		PDEBUG("sdioDrv_ExecuteCmd() response = 0x%x\n", uResponse);
754	}
755	return 0;
756}
757
758/*--------------------------------------------------------------------------------------*/
759
760int sdioDrv_ReadSync (unsigned int uFunc,
761                      unsigned int uHwAddr,
762                      void *       pData,
763                      unsigned int uLen,
764                      unsigned int bIncAddr,
765                      unsigned int bMore)
766{
767	unsigned int uCmdArg;
768	int          iStatus;
769
770//	printk(KERN_INFO "in sdioDrv_ReadSync\n");
771	uCmdArg = SDIO_CMD53_READ(0, uFunc, 0, bIncAddr, uHwAddr, uLen);
772
773	iStatus = sdiodrv_data_xfer_sync(OMAP_HSMMC_CMD53_READ, uCmdArg, pData, uLen, BRE);
774	if (iStatus != 0) {
775		PERR("sdioDrv_ReadSync() FAILED!!\n");
776	}
777#ifdef TI_SDIO_DEBUG
778	if (uLen == 1)
779		printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(char *)pData));
780	else if (uLen == 2)
781		printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(short *)pData));
782	else if (uLen == 4)
783		printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(long *)pData));
784	else
785		printk(KERN_INFO "R53: [0x%x](%u)\n", uHwAddr, uLen);
786#endif
787	return iStatus;
788}
789
790/*--------------------------------------------------------------------------------------*/
791int sdioDrv_ReadAsync (unsigned int uFunc,
792                       unsigned int uHwAddr,
793                       void *       pData,
794                       unsigned int uLen,
795                       unsigned int bBlkMode,
796                       unsigned int bIncAddr,
797                       unsigned int bMore)
798{
799	int          iStatus;
800	unsigned int uCmdArg;
801	unsigned int uNumBlks;
802	unsigned int uDmaBlockCount;
803	unsigned int uNumOfElem;
804	void         *dma_buffer;
805	dma_addr_t dma_bus_address;
806
807#ifdef TI_SDIO_DEBUG
808	printk(KERN_INFO "R53: [0x%x](%u) F[%d]\n", uHwAddr, uLen, uFunc);
809#endif
810
811	//printk(KERN_INFO "in sdioDrv_ReadAsync\n");
812
813    if (bBlkMode)
814    {
815        /* For block mode use number of blocks instead of length in bytes */
816        uNumBlks = uLen >> g_drv.uBlkSizeShift;
817        uDmaBlockCount = uNumBlks;
818        /* due to the DMA config to 32Bit per element (OMAP_DMA_DATA_TYPE_S32) the division is by 4 */
819        uNumOfElem = g_drv.uBlkSize >> 2;
820    }
821    else
822    {
823        uNumBlks = uLen;
824        uDmaBlockCount = 1;
825        uNumOfElem = (uLen + 3) >> 2;
826    }
827
828	if (((u32)pData & 3) == 0) /* 4 bytes aligned */
829	{
830	  dma_buffer         = pData;
831	}
832	else                      /* 2 bytes aligned */
833	{
834	  dma_buffer         = g_drv.dma_buffer;
835	  g_drv.async_buffer = pData;
836	  g_drv.async_length = uLen;
837	}
838
839    uCmdArg = SDIO_CMD53_READ(0, uFunc, bBlkMode, bIncAddr, uHwAddr, uNumBlks);
840
841    iStatus = sdiodrv_send_data_xfer_commad(OMAP_HSMMC_CMD53_READ_DMA, uCmdArg, uNumBlks, BRE, bBlkMode);
842
843    if (!(iStatus & BRE))
844    {
845        PERR("sdioDrv_ReadAsync() buffer disabled! length = %d BLK = 0x%x PSTATE = 0x%x, BlkMode = %d\n",
846              uLen, OMAP_HSMMC_READ(BLK), iStatus, bBlkMode);
847	goto err;
848    }
849
850	PDEBUG("sdiodrv_read_async() dma_ch=%d \n",g_drv.dma_rx_channel);
851
852	dma_bus_address = dma_map_single(g_drv.dev, dma_buffer, uLen, DMA_FROM_DEVICE);
853	if (!dma_bus_address) {
854		PERR("sdioDrv_ReadAsync: dma_map_single failed\n");
855		goto err;
856	}
857
858	if (g_drv.dma_read_addr != 0) {
859		printk(KERN_ERR "sdioDrv_ReadAsync: previous DMA op is not finished!\n");
860		BUG();
861	}
862
863	g_drv.dma_read_addr = dma_bus_address;
864	g_drv.dma_read_size = uLen;
865
866	omap_set_dma_dest_params    (g_drv.dma_rx_channel,
867									0,			// dest_port is only for OMAP1
868									OMAP_DMA_AMODE_POST_INC,
869									dma_bus_address,
870									0, 0);
871
872	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);
873
874	omap_start_dma(g_drv.dma_rx_channel);
875
876	/* Continued at sdiodrv_irq() after DMA transfer is finished */
877#ifdef TI_SDIO_DEBUG
878	printk(KERN_INFO "R53: [0x%x](%u) (A)\n", uHwAddr, uLen);
879#endif
880	return 0;
881err:
882	return -1;
883
884}
885
886
887/*--------------------------------------------------------------------------------------*/
888
889int sdioDrv_WriteSync (unsigned int uFunc,
890                       unsigned int uHwAddr,
891                       void *       pData,
892                       unsigned int uLen,
893                       unsigned int bIncAddr,
894                       unsigned int bMore)
895{
896	unsigned int uCmdArg;
897	int          iStatus;
898
899//	printk(KERN_INFO "in sdioDrv_WriteSync\n");
900
901	uCmdArg = SDIO_CMD53_WRITE(1, uFunc, 0, bIncAddr, uHwAddr, uLen);
902
903	iStatus = sdiodrv_data_xfer_sync(OMAP_HSMMC_CMD53_WRITE, uCmdArg, pData, uLen, BWE);
904	if (iStatus != 0)
905	{
906		PERR("sdioDrv_WriteSync() FAILED!!\n");
907	}
908#ifdef TI_SDIO_DEBUG
909	if (uLen == 1)
910		printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(char *)pData));
911	else if (uLen == 2)
912		printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(short *)pData));
913	else if (uLen == 4)
914		printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(long *)pData));
915	else
916		printk(KERN_INFO "W53: [0x%x](%u)\n", uHwAddr, uLen);
917#endif
918	return iStatus;
919}
920
921/*--------------------------------------------------------------------------------------*/
922int sdioDrv_WriteAsync (unsigned int uFunc,
923                        unsigned int uHwAddr,
924                        void *       pData,
925                        unsigned int uLen,
926                        unsigned int bBlkMode,
927                        unsigned int bIncAddr,
928                        unsigned int bMore)
929{
930	int          iStatus;
931	unsigned int uCmdArg;
932	unsigned int uNumBlks;
933	unsigned int uDmaBlockCount;
934	unsigned int uNumOfElem;
935	dma_addr_t dma_bus_address;
936
937#ifdef TI_SDIO_DEBUG
938	printk(KERN_INFO "W53: [0x%x](%u) F[%d] B[%d] I[%d]\n", uHwAddr, uLen, uFunc, bBlkMode, bIncAddr);
939#endif
940
941//	printk(KERN_INFO "in sdioDrv_WriteAsync\n");
942    if (bBlkMode)
943    {
944        /* For block mode use number of blocks instead of length in bytes */
945        uNumBlks = uLen >> g_drv.uBlkSizeShift;
946        uDmaBlockCount = uNumBlks;
947        /* due to the DMA config to 32Bit per element (OMAP_DMA_DATA_TYPE_S32) the division is by 4 */
948        uNumOfElem = g_drv.uBlkSize >> 2;
949    }
950    else
951    {
952        uNumBlks = uLen;
953        uDmaBlockCount = 1;
954        uNumOfElem = (uLen + 3) >> 2;
955    }
956
957    uCmdArg = SDIO_CMD53_WRITE(1, uFunc, bBlkMode, bIncAddr, uHwAddr, uNumBlks);
958
959    iStatus = sdiodrv_send_data_xfer_commad(OMAP_HSMMC_CMD53_WRITE_DMA, uCmdArg, uNumBlks, BWE, bBlkMode);
960    if (!(iStatus & BWE))
961    {
962        PERR("sdioDrv_WriteAsync() buffer disabled! length = %d, BLK = 0x%x, Status = 0x%x\n",
963             uLen, OMAP_HSMMC_READ(BLK), iStatus);
964	goto err;
965    }
966
967	OMAP_HSMMC_WRITE(ISE, TC);
968
969	dma_bus_address = dma_map_single(g_drv.dev, pData, uLen, DMA_TO_DEVICE);
970	if (!dma_bus_address) {
971		PERR("sdioDrv_WriteAsync: dma_map_single failed\n");
972		goto err;
973	}
974
975	if (g_drv.dma_write_addr != 0) {
976		PERR("sdioDrv_WriteAsync: previous DMA op is not finished!\n");
977		BUG();
978	}
979
980	g_drv.dma_write_addr = dma_bus_address;
981	g_drv.dma_write_size = uLen;
982
983	omap_set_dma_src_params     (g_drv.dma_tx_channel,
984									0,			// src_port is only for OMAP1
985									OMAP_DMA_AMODE_POST_INC,
986									dma_bus_address,
987									0, 0);
988
989	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);
990
991	omap_start_dma(g_drv.dma_tx_channel);
992
993	/* Continued at sdiodrv_irq() after DMA transfer is finished */
994	return 0;
995err:
996	return -1;
997}
998
999/*--------------------------------------------------------------------------------------*/
1000
1001int sdioDrv_ReadSyncBytes (unsigned int  uFunc,
1002                           unsigned int  uHwAddr,
1003                           unsigned char *pData,
1004                           unsigned int  uLen,
1005                           unsigned int  bMore)
1006{
1007	unsigned int uCmdArg;
1008	unsigned int i;
1009	int          iStatus;
1010
1011	for (i = 0; i < uLen; i++) {
1012		uCmdArg = SDIO_CMD52_READ(0, uFunc, 0, uHwAddr);
1013
1014		iStatus = sdiodrv_send_command(OMAP_HSMMC_CMD52_READ, uCmdArg);
1015
1016		if (!(iStatus & CC)) {
1017			PERR("sdioDrv_ReadSyncBytes() SDIO Command error status = 0x%x\n", iStatus);
1018			return -1;
1019		}
1020		else {
1021			*pData = (unsigned char)(OMAP_HSMMC_READ(RSP10));
1022		}
1023#ifdef TI_SDIO_DEBUG
1024		printk(KERN_INFO "R52: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)*pData);
1025#endif
1026		uHwAddr++;
1027		pData++;
1028	}
1029
1030	return 0;
1031}
1032
1033/*--------------------------------------------------------------------------------------*/
1034
1035int sdioDrv_WriteSyncBytes (unsigned int  uFunc,
1036                            unsigned int  uHwAddr,
1037                            unsigned char *pData,
1038                            unsigned int  uLen,
1039                            unsigned int  bMore)
1040{
1041	unsigned int uCmdArg;
1042	unsigned int i;
1043	int          iStatus;
1044
1045	for (i = 0; i < uLen; i++) {
1046#ifdef TI_SDIO_DEBUG
1047		printk(KERN_INFO "W52: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)*pData);
1048#endif
1049		uCmdArg = SDIO_CMD52_WRITE(1, uFunc, 0, uHwAddr, *pData);
1050
1051		iStatus = sdiodrv_send_command(OMAP_HSMMC_CMD52_WRITE, uCmdArg);
1052		if (!(iStatus & CC)) {
1053			PERR("sdioDrv_WriteSyncBytes() SDIO Command error status = 0x%x\n", iStatus);
1054			return -1;
1055		}
1056		uHwAddr++;
1057		pData++;
1058	}
1059
1060	return 0;
1061}
1062
1063static int sdioDrv_probe(struct platform_device *pdev)
1064{
1065	int rc;
1066	u32 status;
1067#ifdef SDIO_1_BIT /* see also in SdioAdapter.c */
1068	unsigned long clock_rate = 6000000;
1069#else
1070	unsigned long clock_rate = 24000000;
1071#endif
1072
1073	printk(KERN_INFO "TIWLAN SDIO probe: initializing mmc%d device\n", pdev->id + 1);
1074
1075	/* remember device struct for future DMA operations */
1076	g_drv.dev = &pdev->dev;
1077	g_drv.irq = platform_get_irq(pdev, 0);
1078	if (g_drv.irq < 0)
1079		return -ENXIO;
1080
1081        rc= request_irq(OMAP_MMC_IRQ, sdiodrv_irq, 0, SDIO_DRIVER_NAME, &g_drv);
1082        if (rc != 0) {
1083                PERR("sdioDrv_InitHw() - request_irq FAILED!!\n");
1084                return rc;
1085        }
1086        sdiodrv_irq_requested = 1;
1087
1088        rc = sdiodrv_dma_init();
1089        if (rc != 0) {
1090                PERR("sdiodrv_init() - sdiodrv_dma_init FAILED!!\n");
1091                free_irq(OMAP_MMC_IRQ, &g_drv);
1092                return rc;
1093        }
1094        sdiodrv_dma_on = 1;
1095
1096	spin_lock_init(&g_drv.clk_lock);
1097
1098#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
1099	dummy_pdev.id = TIWLAN_MMC_CONTROLLER;
1100	dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%lu", TIWLAN_MMC_CONTROLLER);
1101	g_drv.fclk = clk_get(&dummy_pdev.dev, "fck");
1102#else
1103	g_drv.fclk = clk_get(&pdev->dev, "mmchs_fck");
1104#endif
1105	if (IS_ERR(g_drv.fclk)) {
1106		rc = PTR_ERR(g_drv.fclk);
1107		PERR("clk_get(fclk) FAILED !!!\n");
1108		goto err;
1109	}
1110	sdiodrv_fclk_got = 1;
1111
1112#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
1113	g_drv.iclk = clk_get(&dummy_pdev.dev, "ick");
1114#else
1115	g_drv.iclk = clk_get(&pdev->dev, "mmchs_ick");
1116#endif
1117	if (IS_ERR(g_drv.iclk)) {
1118		rc = PTR_ERR(g_drv.iclk);
1119		PERR("clk_get(iclk) FAILED !!!\n");
1120		goto err;
1121	}
1122	sdiodrv_iclk_got = 1;
1123
1124        rc = sdioDrv_clk_enable();
1125        if (rc) {
1126                PERR("sdioDrv_probe : clk_enable FAILED !!!\n");
1127                goto err;
1128        }
1129
1130	OMAP3430_mmc_reset();
1131
1132	//obc - init sequence p. 3600,3617
1133	/* 1.8V */
1134	OMAP_HSMMC_WRITE(CAPA,		OMAP_HSMMC_READ(CAPA) | VS18);
1135	OMAP_HSMMC_WRITE(HCTL,		OMAP_HSMMC_READ(HCTL) | SDVS18);//SDVS fits p. 3650
1136	/* clock gating */
1137	OMAP_HSMMC_WRITE(SYSCONFIG, OMAP_HSMMC_READ(SYSCONFIG) | AUTOIDLE);
1138
1139	/* bus power */
1140	OMAP_HSMMC_WRITE(HCTL,		OMAP_HSMMC_READ(HCTL) | SDBP);//SDBP fits p. 3650
1141	/* interrupts */
1142	OMAP_HSMMC_WRITE(ISE,		0);
1143	OMAP_HSMMC_WRITE(IE,		IE_EN_MASK);
1144
1145	//p. 3601 suggests moving to the end
1146	OMAP3430_mmc_set_clock(clock_rate, &g_drv);
1147	printk(KERN_INFO "SDIO clock Configuration is now set to %dMhz\n",(int)clock_rate/1000000);
1148
1149	/* Bus width */
1150#ifdef SDIO_1_BIT /* see also in SdioAdapter.c */
1151	PDEBUG("%s() setting %d data lines\n",__FUNCTION__, 1);
1152	OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) & (ONE_BIT));
1153#else
1154	PDEBUG("%s() setting %d data lines\n",__FUNCTION__, 4);
1155	OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | (1 << 1));//DTW 4 bits - p. 3650
1156#endif
1157
1158	/* send the init sequence. 80 clocks of synchronization in the SDIO */
1159	//doesn't match p. 3601,3617 - obc
1160	OMAP_HSMMC_WRITE( CON, OMAP_HSMMC_READ(CON) | INIT_STREAM);
1161	OMAP_HSMMC_SEND_COMMAND( 0, 0);
1162	status = sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS);
1163	if (!(status & CC)) {
1164		PERR("sdioDrv_InitHw() SDIO Command error status = 0x%x\n", status);
1165		rc = -1;
1166		goto err;
1167	}
1168	OMAP_HSMMC_WRITE(CON, OMAP_HSMMC_READ(CON) & ~INIT_STREAM);
1169
1170	return 0;
1171err:
1172	sdiodrv_free_resources();
1173	return rc;
1174}
1175
1176static int sdioDrv_remove(struct platform_device *pdev)
1177{
1178	printk(KERN_INFO "sdioDrv_remove: calling sdiodrv_shutdown\n");
1179
1180	sdiodrv_shutdown();
1181
1182	return 0;
1183}
1184
1185#ifdef CONFIG_PM
1186static int sdioDrv_suspend(struct platform_device *pdev, pm_message_t state)
1187{
1188#if 0
1189	int rc = 0;
1190
1191	/* Tell WLAN driver to suspend, if a suspension function has been registered */
1192	if (g_drv.wlanDrvIf_pm_suspend) {
1193		printk(KERN_INFO "TISDIO: Asking TIWLAN to suspend\n");
1194		rc = g_drv.wlanDrvIf_pm_suspend();
1195		if (rc != 0)
1196			return rc;
1197	}
1198
1199	sdiodrv_shutdown();
1200#endif
1201	printk(KERN_INFO "TISDIO: sdioDrv is suspending\n");
1202	return 0;
1203}
1204
1205/* Routine to resume the MMC device */
1206static int sdioDrv_resume(struct platform_device *pdev)
1207{
1208/*	int rc; */
1209
1210	printk(KERN_INFO "TISDIO: sdioDrv is resuming\n");
1211#if 0
1212	rc = sdioDrv_probe(pdev);
1213	if (rc != 0) {
1214		printk(KERN_ERR "TISDIO: resume error\n");
1215		return rc;
1216	}
1217
1218	if (g_drv.wlanDrvIf_pm_resume) {
1219		printk(KERN_INFO "TISDIO: Asking TIWLAN to resume\n");
1220		return(g_drv.wlanDrvIf_pm_resume());
1221	}
1222#endif
1223	return 0;
1224}
1225#else
1226#define sdioDrv_suspend		NULL
1227#define sdioDrv_resume		NULL
1228#endif
1229
1230static struct platform_driver sdioDrv_struct = {
1231	.probe		= sdioDrv_probe,
1232	.remove		= sdioDrv_remove,
1233	.suspend	= sdioDrv_suspend,
1234	.resume		= sdioDrv_resume,
1235	.driver		= {
1236		.name = SDIO_DRIVER_NAME,
1237	},
1238};
1239
1240void sdioDrv_register_pm(int (*wlanDrvIf_Start)(void),
1241						int (*wlanDrvIf_Stop)(void))
1242{
1243	g_drv.wlanDrvIf_pm_resume = wlanDrvIf_Start;
1244	g_drv.wlanDrvIf_pm_suspend = wlanDrvIf_Stop;
1245}
1246
1247int sdioDrv_clk_enable(void)
1248{
1249       unsigned long flags;
1250       int ret = 0;
1251
1252       spin_lock_irqsave(&g_drv.clk_lock, flags);
1253       if (g_drv.ifclks_enabled)
1254               goto done;
1255
1256       ret = clk_enable(g_drv.iclk);
1257       if (ret)
1258              goto clk_en_err1;
1259
1260       ret = clk_enable(g_drv.fclk);
1261       if (ret)
1262               goto clk_en_err2;
1263       g_drv.ifclks_enabled = 1;
1264
1265       sdioDrv_hsmmc_restore_ctx();
1266
1267done:
1268       spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1269       return ret;
1270
1271clk_en_err2:
1272       clk_disable(g_drv.iclk);
1273clk_en_err1 :
1274       spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1275       return ret;
1276}
1277
1278void sdioDrv_clk_disable(void)
1279{
1280       unsigned long flags;
1281
1282       spin_lock_irqsave(&g_drv.clk_lock, flags);
1283       if (!g_drv.ifclks_enabled)
1284               goto done;
1285
1286       sdioDrv_hsmmc_save_ctx();
1287
1288       clk_disable(g_drv.fclk);
1289       clk_disable(g_drv.iclk);
1290       g_drv.ifclks_enabled = 0;
1291done:
1292       spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1293}
1294
1295#ifdef TI_SDIO_STANDALONE
1296static int __init sdioDrv_init(void)
1297#else
1298int __init sdioDrv_init(int sdcnum)
1299#endif
1300{
1301	memset(&g_drv, 0, sizeof(g_drv));
1302	memset(&hsmmc_ctx, 0, sizeof(hsmmc_ctx));
1303
1304	printk(KERN_INFO "TIWLAN SDIO init\n");
1305#ifndef TI_SDIO_STANDALONE
1306	sdio_init( sdcnum );
1307#endif
1308	g_drv.sdio_wq = create_freezeable_workqueue(SDIOWQ_NAME);
1309	if (!g_drv.sdio_wq) {
1310		printk("TISDIO: Fail to create SDIO WQ\n");
1311		return -EINVAL;
1312	}
1313	/* Register the sdio driver */
1314	return platform_driver_register(&sdioDrv_struct);
1315}
1316
1317#ifdef TI_SDIO_STANDALONE
1318static
1319#endif
1320void __exit sdioDrv_exit(void)
1321{
1322	/* Unregister sdio driver */
1323	platform_driver_unregister(&sdioDrv_struct);
1324	if (g_drv.sdio_wq)
1325		destroy_workqueue(g_drv.sdio_wq);
1326}
1327
1328#ifdef TI_SDIO_STANDALONE
1329module_init(sdioDrv_init);
1330module_exit(sdioDrv_exit);
1331#endif
1332
1333EXPORT_SYMBOL(sdioDrv_ConnectBus);
1334EXPORT_SYMBOL(sdioDrv_DisconnectBus);
1335EXPORT_SYMBOL(sdioDrv_ExecuteCmd);
1336EXPORT_SYMBOL(sdioDrv_ReadSync);
1337EXPORT_SYMBOL(sdioDrv_WriteSync);
1338EXPORT_SYMBOL(sdioDrv_ReadAsync);
1339EXPORT_SYMBOL(sdioDrv_WriteAsync);
1340EXPORT_SYMBOL(sdioDrv_ReadSyncBytes);
1341EXPORT_SYMBOL(sdioDrv_WriteSyncBytes);
1342EXPORT_SYMBOL(sdioDrv_register_pm);
1343MODULE_DESCRIPTION("TI WLAN SDIO driver");
1344MODULE_LICENSE("GPL");
1345MODULE_ALIAS(SDIO_DRIVER_NAME);
1346MODULE_AUTHOR("Texas Instruments Inc");
1347#endif
1348