12a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*
22a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * SdioDrv.c
32a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt *
42a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * Copyright (C) 2009 Texas Instruments, Inc. - http://www.ti.com/
54f8090754cf37855c39899666899497743d261f8Dmitry Shmidt *
62a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * This program is free software; you can redistribute it and/or
74f8090754cf37855c39899666899497743d261f8Dmitry Shmidt * modify it under the terms of the GNU General Public License as
82a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * published by the Free Software Foundation version 2.
92a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt *
102a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * This program is distributed "as is" WITHOUT ANY WARRANTY of any
112a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * kind, whether express or implied; without even the implied warranty
122a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * GNU General Public License for more details.
142a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt */
152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
162a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/kernel.h>
172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/module.h>
189b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <linux/version.h>
192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/moduleparam.h>
202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/delay.h>
212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/interrupt.h>
222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/slab.h>
232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/types.h>
242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/dma-mapping.h>
252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/platform_device.h>
262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/i2c/twl4030.h>
272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/errno.h>
282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <linux/clk.h>
299b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
309b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <plat/hardware.h>
319b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <plat/board.h>
329b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <plat/clock.h>
339b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <plat/dma.h>
349b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <plat/io.h>
359b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <plat/resource.h>
369b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#define IO_ADDRESS(pa)	OMAP2_L4_IO_ADDRESS(pa)
379b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#else
389b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <mach/hardware.h>
399b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#include <mach/board.h>
402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <mach/clock.h>
412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <mach/dma.h>
422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <mach/io.h>
432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include <mach/resource.h>
449b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#endif
454f8090754cf37855c39899666899497743d261f8Dmitry Shmidttypedef void *TI_HANDLE;
462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include "host_platform.h"
472a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include "SdioDrvDbg.h"
482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#include "SdioDrv.h"
492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
500f1d5d4137d6a6bc5d3556d06e81406d50c84155Dmitry Shmidt/* #define TI_SDIO_DEBUG */
513df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt
523df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#ifndef CONFIG_MMC_EMBEDDED_SDIO
53266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt
54266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt#define SDIOWQ_NAME			"sdio_wq"
55266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt
562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*
572a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * HSMMC Address and DMA Settings
582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt */
592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic unsigned long TIWLAN_MMC_CONTROLLER = 2; /* MMC3 */
602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic unsigned long TIWLAN_MMC_CONTROLLER_BASE_ADDR = OMAP_HSMMC3_BASE;
612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define TIWLAN_MMC_CONTROLLER_BASE_SIZE	512
62762d794c97ce8ff01eb025b1129c18fac5f11ac4Dmitry Shmidt#define TIWLAN_MMC_MAX_DMA		8192
632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic unsigned long TIWLAN_MMC_DMA_TX = OMAP34XX_DMA_MMC3_TX;
642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic unsigned long TIWLAN_MMC_DMA_RX = OMAP34XX_DMA_MMC3_RX;
652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic unsigned long OMAP_MMC_IRQ = INT_MMC3_IRQ;
662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
672a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_MMC_MASTER_CLOCK          96000000
682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*
692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt *  HSMMC Host Controller Registers
702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt */
712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_SYSCONFIG           0x0010
722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_SYSSTATUS           0x0014
732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CSRE                0x0024
742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_SYSTEST             0x0028
752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CON                 0x002C
762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_BLK                 0x0104
772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_ARG                 0x0108
782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD                 0x010C
792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_RSP10               0x0110
802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_RSP32               0x0114
812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_RSP54               0x0118
822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_RSP76               0x011C
832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_DATA                0x0120
842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_PSTATE              0x0124
852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_HCTL                0x0128
862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_SYSCTL              0x012C
872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_STAT                0x0130
882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_IE                  0x0134
892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_ISE                 0x0138
902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_AC12                0x013C
912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CAPA                0x0140
922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CUR_CAPA            0x0148
932a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_REV                 0x01FC
942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define VS18                           (1 << 26)
962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define VS30                           (1 << 25)
972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SRA                            (1 << 24)
982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SDVS18                         (0x5 << 9)
992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SDVS30                         (0x6 << 9)
1002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SDVSCLR                        0xFFFFF1FF
1012a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SDVSDET                        0x00000400
1022a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SIDLE_MODE                     (0x2 << 3)
1032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define AUTOIDLE                       0x1
1044f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define SDBP                           (1 << 8)
1054f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define DTO                            0xE
1064f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define ICE                            0x1
1074f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define ICS                            0x2
1084f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define CEN                            (1 << 2)
1094f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define CLKD_MASK                      0x0000FFC0
1104f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define IE_EN_MASK                     0x317F0137
1114f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define INIT_STREAM                    (1 << 1)
1124f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define DP_SELECT                      (1 << 21)
1134f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define DDIR                           (1 << 4)
1144f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define DMA_EN                         0x1
1152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define MSBS                           (1 << 5)
1164f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define BCE                            (1 << 1)
1172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define ONE_BIT                        (~(0x2))
1184f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define EIGHT_BIT                      (~(0x20))
1194f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define CC                             0x1
1204f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define TC                             0x02
1214f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define OD                             0x1
1224f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define BRW                            0x400
1234f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define BRR                            0x800
1244f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define BRE                            (1 << 11)
1254f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define BWE                            (1 << 10)
1264f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define SBGR                           (1 << 16)
1274f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define CT                             (1 << 17)
1284f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define SDIO_READ                      (1 << 31)
1294f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define SDIO_BLKMODE                   (1 << 27)
1302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_ERR                 (1 << 15)  /* Any error */
1312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD_TIMEOUT         (1 << 16)  /* Com mand response time-out */
1322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_DATA_TIMEOUT        (1 << 20)  /* Data response time-out */
1332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD_CRC             (1 << 17)  /* Command CRC error */
1342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_DATA_CRC            (1 << 21)  /* Date CRC error */
1352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CARD_ERR            (1 << 28)  /* Card ERR */
1364f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define OMAP_HSMMC_STAT_CLEAR          0xFFFFFFFF
1374f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define INIT_STREAM_CMD                0x00000000
1384f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define INT_CLEAR                      0x00000000
1394f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define BLK_CLEAR                      0x00000000
1402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
1412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/* SCM CONTROL_DEVCONF1 MMC1 overwrite but */
1422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
1434f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define MMC1_ACTIVE_OVERWRITE          (1 << 31)
1444f8090754cf37855c39899666899497743d261f8Dmitry Shmidt
1454f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define sdio_blkmode_regaddr           0x2000
1464f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define sdio_blkmode_mask              0xFF00
1474f8090754cf37855c39899666899497743d261f8Dmitry Shmidt
1484f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define IO_RW_DIRECT_MASK              0xF000FF00
1494f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define IO_RW_DIRECT_ARG_MASK          0x80001A00
1504f8090754cf37855c39899666899497743d261f8Dmitry Shmidt
1514f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define RMASK                          (MMC_RSP_MASK | MMC_RSP_CRC)
1522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define MMC_TIMEOUT_MS                 100 /*on the new 2430 it was 20, i changed back to 100*//* obc */
1534f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define MMCA_VSN_4                     4
1544f8090754cf37855c39899666899497743d261f8Dmitry Shmidt
1554f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define VMMC1_DEV_GRP                  0x27
1564f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define P1_DEV_GRP                     0x20
1574f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define VMMC1_DEDICATED                0x2A
1584f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define VSEL_3V                        0x02
1594f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define VSEL_18V                       0x00
1604f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define PBIAS_3V                       0x03
1614f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define PBIAS_18V                      0x02
1624f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define PBIAS_LITE                     0x04A0
1634f8090754cf37855c39899666899497743d261f8Dmitry Shmidt#define PBIAS_CLR                      0x00
1642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
1652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_MMC_REGS_BASE             IO_ADDRESS(TIWLAN_MMC_CONTROLLER_BASE_ADDR)
1662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
1674f8090754cf37855c39899666899497743d261f8Dmitry Shmidt/*
1682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt * MMC Host controller read/write API's.
1692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt */
1702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_READ_OFFSET(offset) (__raw_readl((OMAP_MMC_REGS_BASE) + (offset)))
1712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_READ(reg)           (__raw_readl((OMAP_MMC_REGS_BASE) + OMAP_HSMMC_##reg))
1722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_WRITE(reg, val)     (__raw_writel((val), (OMAP_MMC_REGS_BASE) + OMAP_HSMMC_##reg))
1732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
1742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_SEND_COMMAND(cmd, arg) do \
1752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{ \
1762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(ARG, arg); \
1772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(CMD, cmd); \
1782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} while (0)
1792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
1802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD52_WRITE     ((SD_IO_RW_DIRECT    << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16))
1812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD52_READ      (((SD_IO_RW_DIRECT   << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DDIR)
1822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD53_WRITE     (((SD_IO_RW_EXTENDED << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DP_SELECT)
1832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD53_READ      (((SD_IO_RW_EXTENDED << 24) | (OMAP_HSMMC_CMD_SHORT_RESPONSE << 16)) | DP_SELECT | DDIR)
1842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD53_READ_DMA  (OMAP_HSMMC_CMD53_READ  | DMA_EN)
1852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define OMAP_HSMMC_CMD53_WRITE_DMA (OMAP_HSMMC_CMD53_WRITE | DMA_EN)
1862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
1872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/* Macros to build commands 52 and 53 in format according to SDIO spec */
1882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SDIO_CMD52_READ(v1,v2,v3,v4)        (SDIO_RWFLAG(v1)|SDIO_FUNCN(v2)|SDIO_RAWFLAG(v3)| SDIO_ADDRREG(v4))
1892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SDIO_CMD52_WRITE(v1,v2,v3,v4,v5)    (SDIO_RWFLAG(v1)|SDIO_FUNCN(v2)|SDIO_RAWFLAG(v3)| SDIO_ADDRREG(v4)|(v5))
1902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#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))
1912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#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))
1922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
193ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt#define SDIODRV_MAX_LOOPS	50000
1942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
1952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define VMMC2_DEV_GRP		0x2B
1962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define VMMC2_DEDICATED		0x2E
1972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define VSEL_S2_18V		0x05
1982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define LDO_CLR			0x00
1992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define VSEL_S2_CLR		0x40
2002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define GPIO_0_BIT_POS		1 << 0
2012a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define GPIO_1_BIT_POS		1 << 1
2022a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define VSIM_DEV_GRP		0x37
2032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define VSIM_DEDICATED		0x3A
2042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define TWL4030_MODULE_PM_RECIEVER	0x13
2052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
2062a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidttypedef struct OMAP3430_sdiodrv
2072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
2082a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	struct clk    *fclk, *iclk, *dbclk;
209a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	int           ifclks_enabled;
210a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	spinlock_t    clk_lock;
2112a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int           dma_tx_channel;
2122a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int           dma_rx_channel;
2132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int           irq;
2142a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	void          (*BusTxnCB)(void* BusTxnHandle, int status);
2152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	void*         BusTxnHandle;
2162a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int  uBlkSize;
2172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int  uBlkSizeShift;
2182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	char          *dma_buffer;
2192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	void          *async_buffer;
2202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int  async_length;
2212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int           async_status;
2222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int (*wlanDrvIf_pm_resume)(void);
2232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int (*wlanDrvIf_pm_suspend)(void);
2242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	struct device *dev;
2252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	dma_addr_t dma_read_addr;
2262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	size_t dma_read_size;
2272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	dma_addr_t dma_write_addr;
2282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	size_t dma_write_size;
229266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	struct workqueue_struct *sdio_wq; /* Work Queue */
230266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	struct work_struct sdiodrv_work;
2312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} OMAP3430_sdiodrv_t;
2322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
233a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtstruct omap_hsmmc_regs {
234a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        u32 hctl;
235a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        u32 capa;
236a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        u32 sysconfig;
237a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        u32 ise;
238a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        u32 ie;
239a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        u32 con;
240a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        u32 sysctl;
241a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt};
242a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtstatic struct omap_hsmmc_regs hsmmc_ctx;
243a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
2449b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
2459b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidtstatic struct platform_device dummy_pdev = {
2469b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt	.dev = {
2479b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt		.bus = &platform_bus_type,
2489b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt	},
2499b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt};
2509b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#endif
2519b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt
2522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#define SDIO_DRIVER_NAME 			"TIWLAN_SDIO"
2532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
2542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtmodule_param(g_sdio_debug_level, int, 0644);
2552a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtMODULE_PARM_DESC(g_sdio_debug_level, "debug level");
256653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidtint g_sdio_debug_level = SDIO_DEBUGLEVEL_ERR;
257266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry ShmidtEXPORT_SYMBOL(g_sdio_debug_level);
2582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
2592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtOMAP3430_sdiodrv_t g_drv;
2602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
2612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdiodrv_dma_on = 0;
2622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdiodrv_irq_requested = 0;
2632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdiodrv_iclk_got = 0;
2642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdiodrv_fclk_got = 0;
2652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
2669a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidtint sdioDrv_clk_enable(void);
2679a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidtvoid sdioDrv_clk_disable(void);
268a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtstatic void sdioDrv_hsmmc_save_ctx(void);
269a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtstatic void sdioDrv_hsmmc_restore_ctx(void);
270a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
2712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#ifndef TI_SDIO_STANDALONE
2722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtvoid sdio_init( int sdcnum )
2732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
2742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if( sdcnum <= 0 )
2752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		return;
2762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	TIWLAN_MMC_CONTROLLER = sdcnum - 1;
2772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if( sdcnum == 2 ) {
2782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		TIWLAN_MMC_CONTROLLER_BASE_ADDR = OMAP_HSMMC2_BASE;
2792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		TIWLAN_MMC_DMA_TX = OMAP24XX_DMA_MMC2_TX;
2802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		TIWLAN_MMC_DMA_RX = OMAP24XX_DMA_MMC2_RX;
2812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		OMAP_MMC_IRQ = INT_MMC2_IRQ;
2822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
2832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	else if( sdcnum == 3 ) {
2842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		TIWLAN_MMC_CONTROLLER_BASE_ADDR	= OMAP_HSMMC3_BASE;
2852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		TIWLAN_MMC_DMA_TX = OMAP34XX_DMA_MMC3_TX;
2862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		TIWLAN_MMC_DMA_RX = OMAP34XX_DMA_MMC3_RX;
2872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		OMAP_MMC_IRQ = INT_MMC3_IRQ;
2882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
2892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
2902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#endif
2912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
292a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtstatic void sdioDrv_hsmmc_save_ctx(void)
293a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt{
2946910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	/* MMC : context save */
2956910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	hsmmc_ctx.hctl = OMAP_HSMMC_READ(HCTL);
2966910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	hsmmc_ctx.capa = OMAP_HSMMC_READ(CAPA);
2976910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	hsmmc_ctx.sysconfig = OMAP_HSMMC_READ(SYSCONFIG);
2986910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	hsmmc_ctx.ise = OMAP_HSMMC_READ(ISE);
2996910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	hsmmc_ctx.ie = OMAP_HSMMC_READ(IE);
3006910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	hsmmc_ctx.con = OMAP_HSMMC_READ(CON);
3016910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	hsmmc_ctx.sysctl = OMAP_HSMMC_READ(SYSCTL);
3026910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	OMAP_HSMMC_WRITE(ISE, 0);
3036910c6d18774fec1bd7f4903bf95f71ccd80b773Dmitry Shmidt	OMAP_HSMMC_WRITE(IE, 0);
304a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt}
305653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt
306653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidtstatic void sdioDrv_hsmmc_restore_ctx(void)
307a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt{
308a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        /* MMC : context restore */
309a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        OMAP_HSMMC_WRITE(HCTL, hsmmc_ctx.hctl);
310a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        OMAP_HSMMC_WRITE(CAPA, hsmmc_ctx.capa);
311653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt        OMAP_HSMMC_WRITE(SYSCONFIG, hsmmc_ctx.sysconfig);
312a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        OMAP_HSMMC_WRITE(CON, hsmmc_ctx.con);
313a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        OMAP_HSMMC_WRITE(ISE, hsmmc_ctx.ise);
314a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        OMAP_HSMMC_WRITE(IE, hsmmc_ctx.ie);
315a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        OMAP_HSMMC_WRITE(SYSCTL, hsmmc_ctx.sysctl);
316a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | SDBP);
317a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt}
318a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
3192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtvoid sdiodrv_task(struct work_struct *unused)
3202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
3212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("sdiodrv_tasklet()\n");
3222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.dma_read_addr != 0) {
3242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		dma_unmap_single(g_drv.dev, g_drv.dma_read_addr, g_drv.dma_read_size, DMA_FROM_DEVICE);
3252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		g_drv.dma_read_addr = 0;
3262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		g_drv.dma_read_size = 0;
3272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
3282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.dma_write_addr != 0) {
3302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		dma_unmap_single(g_drv.dev, g_drv.dma_write_addr, g_drv.dma_write_size, DMA_TO_DEVICE);
3312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		g_drv.dma_write_addr = 0;
3322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		g_drv.dma_write_size = 0;
3332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
3342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.async_buffer) {
3362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		memcpy(g_drv.async_buffer, g_drv.dma_buffer, g_drv.async_length);
3372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		g_drv.async_buffer = NULL;
3382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
3392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.BusTxnCB != NULL) {
3412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		g_drv.BusTxnCB(g_drv.BusTxnHandle, g_drv.async_status);
3422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
3432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
3442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3452a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtirqreturn_t sdiodrv_irq(int irq, void *drv)
3462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
3472a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int status;
3482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("sdiodrv_irq()\n");
3502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3512a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	status = OMAP_HSMMC_READ(STAT);
3522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(ISE, 0);
3532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.async_status = status & (OMAP_HSMMC_ERR);
3542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.async_status) {
3552a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("sdiodrv_irq: ERROR in STAT = 0x%x\n", status);
3562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
357266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	queue_work(g_drv.sdio_wq, &g_drv.sdiodrv_work);
3582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return IRQ_HANDLED;
3592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
3602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtvoid sdiodrv_dma_read_cb(int lch, u16 ch_status, void *data)
3622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
3632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("sdiodrv_dma_read_cb() channel=%d status=0x%x\n", lch, (int)ch_status);
3642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.async_status = ch_status & (1 << 7);
366653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt
367266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	queue_work(g_drv.sdio_wq, &g_drv.sdiodrv_work);
3682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
3692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
370653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidtvoid sdiodrv_dma_write_cb(int lch, u16 ch_status, void *data)
371653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt{
372653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt}
373653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt
3742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdiodrv_dma_init(void)
3752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
3762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int rc;
3772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
378653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	rc = omap_request_dma(TIWLAN_MMC_DMA_TX, "SDIO WRITE", sdiodrv_dma_write_cb, &g_drv, &g_drv.dma_tx_channel);
3792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (rc != 0) {
3802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("sdiodrv_dma_init() omap_request_dma(TIWLAN_MMC_DMA_TX) FAILED\n");
3812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		goto out;
3822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
3832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	rc = omap_request_dma(TIWLAN_MMC_DMA_RX, "SDIO READ", sdiodrv_dma_read_cb, &g_drv, &g_drv.dma_rx_channel);
3852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (rc != 0) {
3862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("sdiodrv_dma_init() omap_request_dma(TIWLAN_MMC_DMA_RX) FAILED\n");
3872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		goto freetx;
3882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
3892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	omap_set_dma_src_params(g_drv.dma_rx_channel,
3912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt  							0,			// src_port is only for OMAP1
3922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt  							OMAP_DMA_AMODE_CONSTANT,
3932a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt  							(TIWLAN_MMC_CONTROLLER_BASE_ADDR) + OMAP_HSMMC_DATA, 0, 0);
3942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
3952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	omap_set_dma_dest_params(g_drv.dma_tx_channel,
3962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt							0,			// dest_port is only for OMAP1
3972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt  	  						OMAP_DMA_AMODE_CONSTANT,
3982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt  	  						(TIWLAN_MMC_CONTROLLER_BASE_ADDR) + OMAP_HSMMC_DATA, 0, 0);
3992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if ((g_drv.dma_buffer = kmalloc(TIWLAN_MMC_MAX_DMA, GFP_ATOMIC|GFP_DMA)) == NULL) {
4012a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		rc = -ENOMEM;
4022a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		goto freerx;
4032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
4042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return 0;
4062a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtfreerx:
408a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	omap_free_dma(g_drv.dma_rx_channel);
4092a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtfreetx:
4102a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	omap_free_dma(g_drv.dma_tx_channel);
4112a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtout:
4122a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return rc;
4132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
4142a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtvoid sdiodrv_dma_shutdown(void)
4162a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
417a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	omap_free_dma(g_drv.dma_tx_channel);
418a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	omap_free_dma(g_drv.dma_rx_channel);
4192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.dma_buffer) {
420a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt		kfree(g_drv.dma_buffer);
4212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		g_drv.dma_buffer = NULL;
422a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	}
4232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* sdiodrv_dma_shutdown() */
4242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic u32 sdiodrv_poll_status(u32 reg_offset, u32 stat, unsigned int msecs)
4262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
427ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt	u32 status=0, loops=0;
4282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	do
430ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt	{
431ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt		status = OMAP_HSMMC_READ_OFFSET(reg_offset);
432ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt		if(( status & stat))
4332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		{
434ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt			break;
4352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		}
4362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	} while (loops++ < SDIODRV_MAX_LOOPS);
4372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return status;
4392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* sdiodrv_poll_status */
440ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt
4412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtvoid dumpreg(void)
4422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
4432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_SYSCONFIG   for mmc3 = %x  ", omap_readl( 0x480AD010 ));
4442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_SYSSTATUS   for mmc3 = %x  ", omap_readl( 0x480AD014 ));
445653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	printk(KERN_ERR "\n MMCHS_CSRE	      for mmc3 = %x  ", omap_readl( 0x480AD024 ));
4462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_SYSTEST     for mmc3 = %x  ", omap_readl( 0x480AD028 ));
4472a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_CON         for mmc3 = %x  ", omap_readl( 0x480AD02C ));
4482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_PWCNT       for mmc3 = %x  ", omap_readl( 0x480AD030 ));
4492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_BLK         for mmc3 = %x  ", omap_readl( 0x480AD104 ));
4502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_ARG         for mmc3 = %x  ", omap_readl( 0x480AD108 ));
4512a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_CMD         for mmc3 = %x  ", omap_readl( 0x480AD10C ));
4522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_RSP10       for mmc3 = %x  ", omap_readl( 0x480AD110 ));
4532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_RSP32       for mmc3 = %x  ", omap_readl( 0x480AD114 ));
4542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_RSP54       for mmc3 = %x  ", omap_readl( 0x480AD118 ));
4552a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_RSP76       for mmc3 = %x  ", omap_readl( 0x480AD11C ));
4562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_DATA        for mmc3 = %x  ", omap_readl( 0x480AD120 ));
4572a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_PSTATE      for mmc3 = %x  ", omap_readl( 0x480AD124 ));
4582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_HCTL        for mmc3 = %x  ", omap_readl( 0x480AD128 ));
4592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_SYSCTL      for mmc3 = %x  ", omap_readl( 0x480AD12C ));
4602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_STAT        for mmc3 = %x  ", omap_readl( 0x480AD130 ));
4612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_IE          for mmc3 = %x  ", omap_readl( 0x480AD134 ));
4622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_ISE         for mmc3 = %x  ", omap_readl( 0x480AD138 ));
4632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_AC12        for mmc3 = %x  ", omap_readl( 0x480AD13C ));
4642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_CAPA        for mmc3 = %x  ", omap_readl( 0x480AD140 ));
4652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_ERR "\n MMCHS_CUR_CAPA    for mmc3 = %x  ", omap_readl( 0x480AD148 ));
4662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
4672a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt//cmd flow p. 3609 obc
4692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdiodrv_send_command(u32 cmdreg, u32 cmdarg)
4702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
471ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt	OMAP_HSMMC_WRITE(STAT, OMAP_HSMMC_STAT_CLEAR);
4722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_SEND_COMMAND(cmdreg, cmdarg);
4732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS);
4752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* sdiodrv_send_command() */
4762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*
4782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt *  Disable clock to the card
4792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt */
4802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic void OMAP3430_mmc_stop_clock(void)
4812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
4822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) & ~CEN);
4832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if ((OMAP_HSMMC_READ(SYSCTL) & CEN) != 0x0)
4842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    {
4852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("MMC clock not stoped, clock freq can not be altered\n");
4862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    }
4872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* OMAP3430_mmc_stop_clock */
4882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
4892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*
4902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt *  Reset the SD system
4912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt */
4922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint OMAP3430_mmc_reset(void)
4932a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
4942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int status, loops=0;
4952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	//p. 3598 - need to set SOFTRESET to 0x1 0bc
4962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | SRA);
4972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	while ((status = OMAP_HSMMC_READ(SYSCTL) &  SRA) && loops++ < SDIODRV_MAX_LOOPS);
4982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (status & SRA)
4992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	{
5002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    PERR("OMAP3430_mmc_reset() MMC reset FAILED!! status=0x%x\n",status);
5012a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
5022a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return status;
5042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* OMAP3430_mmc_reset */
5062a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt//p. 3611
5082a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic void OMAP3430_mmc_set_clock(unsigned int clock, OMAP3430_sdiodrv_t *host)
5092a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
5102a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	u16           dsor = 0;
5112a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned long regVal;
5122a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int           status;
5132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5142a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("OMAP3430_mmc_set_clock(%d)\n",clock);
5152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (clock) {
5162a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		/* Enable MMC_SD_CLK */
5172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		dsor = OMAP_MMC_MASTER_CLOCK / clock;
5182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		if (dsor < 1) {
5192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt			dsor = 1;
5202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		}
5212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		if (OMAP_MMC_MASTER_CLOCK / dsor > clock) {
5222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt			dsor++;
5232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		}
5242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		if (dsor > 250) {
5252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt			dsor = 250;
5262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		}
5272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
5282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP3430_mmc_stop_clock();
5292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	regVal = OMAP_HSMMC_READ(SYSCTL);
5302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	regVal = regVal & ~(CLKD_MASK);//p. 3652
5312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	regVal = regVal | (dsor << 6);
5322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	regVal = regVal | (DTO << 16);//data timeout
5332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(SYSCTL, regVal);
5342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | ICE);//internal clock enable. obc not mentioned in the spec
5352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/*
536653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt     * wait till the the clock is stable (ICS) bit is set
5372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	 */
5382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	status  = sdiodrv_poll_status(OMAP_HSMMC_SYSCTL, ICS, MMC_TIMEOUT_MS);
5392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if(!(status & ICS)) {
5402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    PERR("OMAP3430_mmc_set_clock() clock not stable!! status=0x%x\n",status);
5412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
5422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/*
5432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	 * Enable clock to the card
5442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	 */
5452a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(SYSCTL, OMAP_HSMMC_READ(SYSCTL) | CEN);
5462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5472a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* OMAP3430_mmc_set_clock() */
5482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic void sdiodrv_free_resources(void)
5502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
551653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	if(g_drv.ifclks_enabled) {
552653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt		sdioDrv_clk_disable();
5532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
5542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5552a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (sdiodrv_fclk_got) {
5562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		clk_put(g_drv.fclk);
5572a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		sdiodrv_fclk_got = 0;
5582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
5592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (sdiodrv_iclk_got) {
5612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		clk_put(g_drv.iclk);
5622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		sdiodrv_iclk_got = 0;
5632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
564a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
565a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        if (sdiodrv_irq_requested) {
566a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                free_irq(OMAP_MMC_IRQ, &g_drv);
567a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                sdiodrv_irq_requested = 0;
568a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        }
569a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
570a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        if (sdiodrv_dma_on) {
571a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                sdiodrv_dma_shutdown();
572a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                sdiodrv_dma_on = 0;
573a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        }
5742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
5752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_InitHw(void)
5772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
5782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return 0;
5792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* sdiodrv_init */
5802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtvoid sdiodrv_shutdown(void)
5822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
5832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("entering %s()\n" , __FUNCTION__ );
5842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	sdiodrv_free_resources();
5862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("exiting %s\n", __FUNCTION__);
5882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* sdiodrv_shutdown() */
5892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdiodrv_send_data_xfer_commad(u32 cmd, u32 cmdarg, int length, u32 buffer_enable_status, unsigned int bBlkMode)
5912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
5922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    int status;
5932a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("%s() writing CMD 0x%x ARG 0x%x\n",__FUNCTION__, cmd, cmdarg);
5952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
5962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    /* block mode */
5972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if(bBlkMode) {
5982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        /*
5992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         * Bits 31:16 of BLK reg: NBLK Blocks count for current transfer.
6002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         *                        in case of Block MOde the lenght is treated here as number of blocks
6012a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         *                        (and not as a length).
6022a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         * Bits 11:0 of BLK reg: BLEN Transfer Block Size. in case of block mode set that field to block size.
6032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         */
6042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        OMAP_HSMMC_WRITE(BLK, (length << 16) | (g_drv.uBlkSize << 0));
6052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6062a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        /*
6072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         * In CMD reg:
6082a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         * BCE: Block Count Enable
6092a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         * MSBS: Multi/Single block select
6102a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt         */
6112a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        cmd |= MSBS | BCE ;
6122a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	} else {
6132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        OMAP_HSMMC_WRITE(BLK, length);
6142a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    }
6152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6162a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    status = sdiodrv_send_command(cmd, cmdarg);
6172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if(!(status & CC)) {
6182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    PERR("sdiodrv_send_data_xfer_commad() SDIO Command error! STAT = 0x%x\n", status);
6192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    return 0;
6202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
6212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("%s() length = %d(%dw) BLK = 0x%x\n",
6222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		   __FUNCTION__, length,((length + 3) >> 2), OMAP_HSMMC_READ(BLK));
6232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    return sdiodrv_poll_status(OMAP_HSMMC_PSTATE, buffer_enable_status, MMC_TIMEOUT_MS);
6252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* sdiodrv_send_data_xfer_commad() */
6272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdiodrv_data_xfer_sync(u32 cmd, u32 cmdarg, void *data, int length, u32 buffer_enable_status)
6292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
6302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    u32 buf_start, buf_end, data32;
6312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int status;
6322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    status = sdiodrv_send_data_xfer_commad(cmd, cmdarg, length, buffer_enable_status, 0);
6342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if(!(status & buffer_enable_status))
6352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    {
6362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    PERR("sdiodrv_data_xfer_sync() buffer disabled! length = %d BLK = 0x%x PSTATE = 0x%x\n",
6372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt			   length, OMAP_HSMMC_READ(BLK), status);
6382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    return -1;
6392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
6402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	buf_end = (u32)data+(u32)length;
6412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	//obc need to check BRE/BWE every time, see p. 3605
6432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/*
6442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	 * Read loop
6452a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	 */
6462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (buffer_enable_status == BRE)
6472a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	{
6482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  if (((u32)data & 3) == 0) /* 4 bytes aligned */
6492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  {
6502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
6512a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		{
6522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		  *((unsigned long*)(data)) = OMAP_HSMMC_READ(DATA);
6532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		}
6542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  }
6552a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  else                      /* 2 bytes aligned */
6562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  {
6572a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
6582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		{
6592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		  data32 = OMAP_HSMMC_READ(DATA);
6602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		  *((unsigned short *)data)     = (unsigned short)data32;
6612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		  *((unsigned short *)data + 1) = (unsigned short)(data32 >> 16);
6622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		}
6632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  }
6642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
6652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/*
6662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	 * Write loop
6672a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	 */
6682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	else
6692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	{
6702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  if (((u32)data & 3) == 0) /* 4 bytes aligned */
6712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  {
6722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
6732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		{
6742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		  OMAP_HSMMC_WRITE(DATA,*((unsigned long*)(data)));
6752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		}
6762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  }
6772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  else                      /* 2 bytes aligned */
6782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  {
6792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		for (buf_start = (u32)data; (u32)data < buf_end; data += sizeof(unsigned long))
6802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		{
6812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		  OMAP_HSMMC_WRITE(DATA,*((unsigned short*)data) | *((unsigned short*)data+1) << 16 );
6822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		}
6832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  }
6852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
6862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	status  = sdiodrv_poll_status(OMAP_HSMMC_STAT, TC, MMC_TIMEOUT_MS);
6872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if(!(status & TC))
6889a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	{
6892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    PERR("sdiodrv_data_xfer_sync() transfer error! STAT = 0x%x\n", status);
6902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    return -1;
6912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
6922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6939a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	return 0;
6942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
6952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt} /* sdiodrv_data_xfer_sync() */
6962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
697653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidtint sdioDrv_ConnectBus (void *       fCbFunc,
698653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt                        void *       hCbArg,
699653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt                        unsigned int uBlkSizeShift,
700653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt                        unsigned int uSdioThreadPriority,
701653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt                        unsigned char **pTxDmaSrcAddr)
7022a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
7039a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	g_drv.BusTxnCB      = fCbFunc;
7049a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	g_drv.BusTxnHandle  = hCbArg;
7059a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	g_drv.uBlkSizeShift = uBlkSizeShift;
7069a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	g_drv.uBlkSize      = 1 << uBlkSizeShift;
7072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
708266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	INIT_WORK(&g_drv.sdiodrv_work, sdiodrv_task);
7092a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
710653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	/* Provide the DMA buffer address to the upper layer so it will use it
711653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	   as the transactions host buffer. */
712653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	if (pTxDmaSrcAddr)
713653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	{
714653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt		*pTxDmaSrcAddr = g_drv.dma_buffer;
715653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	}
7169a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	return sdioDrv_InitHw ();
7172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
7182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_DisconnectBus (void)
7202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
7214f8090754cf37855c39899666899497743d261f8Dmitry Shmidt	sdioDrv_clk_disable(); /* To process Stop command properly */
7229a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	return 0;
7232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
7242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt//p.3609 cmd flow
7262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_ExecuteCmd (unsigned int uCmd,
7272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        unsigned int uArg,
7282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        unsigned int uRespType,
7292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        void *       pResponse,
7302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        unsigned int uLen)
7312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
7322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uCmdReg   = 0;
7332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uStatus   = 0;
7342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uResponse = 0;
7352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("sdioDrv_ExecuteCmd() starting cmd %02x arg %08x\n", (int)uCmd, (int)uArg);
7372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7389a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	sdioDrv_clk_enable(); /* To make sure we have clocks enable */
7399a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt
7402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	uCmdReg = (uCmd << 24) | (uRespType << 16) ;
7412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	uStatus = sdiodrv_send_command(uCmdReg, uArg);
7432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (!(uStatus & CC))
745ab438fc855fd64b4b2b700f814972c085a1772ffDmitry Shmidt	{
7462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    PERR("sdioDrv_ExecuteCmd() SDIO Command error status = 0x%x\n", uStatus);
7472a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    return -1;
7482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
7492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if ((uLen > 0) && (uLen <= 4))/*obc - Len > 4 ? shouldn't read anything ? */
7502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	{
7512a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	    uResponse = OMAP_HSMMC_READ(RSP10);
7522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		memcpy (pResponse, (char *)&uResponse, uLen);
7532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PDEBUG("sdioDrv_ExecuteCmd() response = 0x%x\n", uResponse);
7542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
7559a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	return 0;
7562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
7572a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*--------------------------------------------------------------------------------------*/
7592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_ReadSync (unsigned int uFunc,
7612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                      unsigned int uHwAddr,
7622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                      void *       pData,
7632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                      unsigned int uLen,
7642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                      unsigned int bIncAddr,
7652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                      unsigned int bMore)
7662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
7672a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uCmdArg;
7682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int          iStatus;
7692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt//	printk(KERN_INFO "in sdioDrv_ReadSync\n");
7712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	uCmdArg = SDIO_CMD53_READ(0, uFunc, 0, bIncAddr, uHwAddr, uLen);
7722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	iStatus = sdiodrv_data_xfer_sync(OMAP_HSMMC_CMD53_READ, uCmdArg, pData, uLen, BRE);
7743df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	if (iStatus != 0) {
7753df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		PERR("sdioDrv_ReadSync() FAILED!!\n");
7762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
7773df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#ifdef TI_SDIO_DEBUG
7783df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	if (uLen == 1)
7793df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(char *)pData));
7803df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	else if (uLen == 2)
7813df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(short *)pData));
7823df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	else if (uLen == 4)
7833df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "R53: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)(*(long *)pData));
7843df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	else
7853df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "R53: [0x%x](%u)\n", uHwAddr, uLen);
7863df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#endif
7872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return iStatus;
7882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
7892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
7902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*--------------------------------------------------------------------------------------*/
7912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_ReadAsync (unsigned int uFunc,
7922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int uHwAddr,
7932a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       void *       pData,
7942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int uLen,
7952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int bBlkMode,
7962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int bIncAddr,
7972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int bMore)
7982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
7992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int          iStatus;
8002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uCmdArg;
8013df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	unsigned int uNumBlks;
8023df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	unsigned int uDmaBlockCount;
8033df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	unsigned int uNumOfElem;
8042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	void         *dma_buffer;
8052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	dma_addr_t dma_bus_address;
8063df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt
8073df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#ifdef TI_SDIO_DEBUG
8083df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	printk(KERN_INFO "R53: [0x%x](%u) F[%d]\n", uHwAddr, uLen, uFunc);
8093df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#endif
8103df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt
8112a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	//printk(KERN_INFO "in sdioDrv_ReadAsync\n");
8123df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt
8132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    if (bBlkMode)
8142a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    {
8152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        /* For block mode use number of blocks instead of length in bytes */
8162a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uNumBlks = uLen >> g_drv.uBlkSizeShift;
8172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uDmaBlockCount = uNumBlks;
8182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        /* due to the DMA config to 32Bit per element (OMAP_DMA_DATA_TYPE_S32) the division is by 4 */
8192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uNumOfElem = g_drv.uBlkSize >> 2;
8202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    }
8212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    else
8222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    {
8232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uNumBlks = uLen;
8242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uDmaBlockCount = 1;
8252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uNumOfElem = (uLen + 3) >> 2;
8262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    }
8272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (((u32)pData & 3) == 0) /* 4 bytes aligned */
8292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	{
8302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  dma_buffer         = pData;
8312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
8322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	else                      /* 2 bytes aligned */
8332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	{
8342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  dma_buffer         = g_drv.dma_buffer;
8352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  g_drv.async_buffer = pData;
8362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	  g_drv.async_length = uLen;
8372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
8382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    uCmdArg = SDIO_CMD53_READ(0, uFunc, bBlkMode, bIncAddr, uHwAddr, uNumBlks);
8402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    iStatus = sdiodrv_send_data_xfer_commad(OMAP_HSMMC_CMD53_READ_DMA, uCmdArg, uNumBlks, BRE, bBlkMode);
8422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    if (!(iStatus & BRE))
8442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    {
8452a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        PERR("sdioDrv_ReadAsync() buffer disabled! length = %d BLK = 0x%x PSTATE = 0x%x, BlkMode = %d\n",
8462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt              uLen, OMAP_HSMMC_READ(BLK), iStatus, bBlkMode);
8472a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	goto err;
8482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    }
8492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("sdiodrv_read_async() dma_ch=%d \n",g_drv.dma_rx_channel);
8512a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	dma_bus_address = dma_map_single(g_drv.dev, dma_buffer, uLen, DMA_FROM_DEVICE);
8532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (!dma_bus_address) {
8542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("sdioDrv_ReadAsync: dma_map_single failed\n");
8552a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		goto err;
8562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
8572a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.dma_read_addr != 0) {
8592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		printk(KERN_ERR "sdioDrv_ReadAsync: previous DMA op is not finished!\n");
8602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		BUG();
8612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
8622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.dma_read_addr = dma_bus_address;
8642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.dma_read_size = uLen;
8652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	omap_set_dma_dest_params    (g_drv.dma_rx_channel,
8672a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt									0,			// dest_port is only for OMAP1
8682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt									OMAP_DMA_AMODE_POST_INC,
8692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt									dma_bus_address,
8702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt									0, 0);
8712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	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);
8732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	omap_start_dma(g_drv.dma_rx_channel);
8752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
876a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	/* Continued at sdiodrv_irq() after DMA transfer is finished */
877a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt#ifdef TI_SDIO_DEBUG
878a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	printk(KERN_INFO "R53: [0x%x](%u) (A)\n", uHwAddr, uLen);
879a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt#endif
8802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return 0;
8812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidterr:
8822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return -1;
8832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
8852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*--------------------------------------------------------------------------------------*/
8882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
8892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_WriteSync (unsigned int uFunc,
8902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int uHwAddr,
8912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       void *       pData,
8922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int uLen,
8932a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int bIncAddr,
8942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                       unsigned int bMore)
8952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
8962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uCmdArg;
8972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int          iStatus;
8983df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt
8992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt//	printk(KERN_INFO "in sdioDrv_WriteSync\n");
9002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9013df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	uCmdArg = SDIO_CMD53_WRITE(1, uFunc, 0, bIncAddr, uHwAddr, uLen);
9022a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	iStatus = sdiodrv_data_xfer_sync(OMAP_HSMMC_CMD53_WRITE, uCmdArg, pData, uLen, BWE);
9042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (iStatus != 0)
9052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	{
9063df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		PERR("sdioDrv_WriteSync() FAILED!!\n");
9072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
9083df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#ifdef TI_SDIO_DEBUG
9093df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	if (uLen == 1)
9103df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(char *)pData));
9113df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	else if (uLen == 2)
9123df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(short *)pData));
9133df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	else if (uLen == 4)
9143df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "W53: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)(*(long *)pData));
9153df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	else
9163df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "W53: [0x%x](%u)\n", uHwAddr, uLen);
9173df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#endif
9182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return iStatus;
9192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
9202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*--------------------------------------------------------------------------------------*/
9222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_WriteAsync (unsigned int uFunc,
9232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        unsigned int uHwAddr,
9242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        void *       pData,
9252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        unsigned int uLen,
9262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        unsigned int bBlkMode,
9272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        unsigned int bIncAddr,
9282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                        unsigned int bMore)
9292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
9302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int          iStatus;
9312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uCmdArg;
9323df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	unsigned int uNumBlks;
9333df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	unsigned int uDmaBlockCount;
9343df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	unsigned int uNumOfElem;
9352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	dma_addr_t dma_bus_address;
9363df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt
9373df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#ifdef TI_SDIO_DEBUG
938a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	printk(KERN_INFO "W53: [0x%x](%u) F[%d] B[%d] I[%d]\n", uHwAddr, uLen, uFunc, bBlkMode, bIncAddr);
9393df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#endif
9403df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt
9412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt//	printk(KERN_INFO "in sdioDrv_WriteAsync\n");
9422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    if (bBlkMode)
9432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    {
9442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        /* For block mode use number of blocks instead of length in bytes */
9452a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uNumBlks = uLen >> g_drv.uBlkSizeShift;
9462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uDmaBlockCount = uNumBlks;
9472a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        /* due to the DMA config to 32Bit per element (OMAP_DMA_DATA_TYPE_S32) the division is by 4 */
9482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uNumOfElem = g_drv.uBlkSize >> 2;
9492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    }
9502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    else
951a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt    {
9522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uNumBlks = uLen;
9532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uDmaBlockCount = 1;
9542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        uNumOfElem = (uLen + 3) >> 2;
9552a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    }
9562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9572a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    uCmdArg = SDIO_CMD53_WRITE(1, uFunc, bBlkMode, bIncAddr, uHwAddr, uNumBlks);
9582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    iStatus = sdiodrv_send_data_xfer_commad(OMAP_HSMMC_CMD53_WRITE_DMA, uCmdArg, uNumBlks, BWE, bBlkMode);
9602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    if (!(iStatus & BWE))
9612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    {
9622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt        PERR("sdioDrv_WriteAsync() buffer disabled! length = %d, BLK = 0x%x, Status = 0x%x\n",
9632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt             uLen, OMAP_HSMMC_READ(BLK), iStatus);
9642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	goto err;
9652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt    }
9662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9672a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(ISE, TC);
9682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	dma_bus_address = dma_map_single(g_drv.dev, pData, uLen, DMA_TO_DEVICE);
9702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (!dma_bus_address) {
9712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("sdioDrv_WriteAsync: dma_map_single failed\n");
9722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		goto err;
9732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
9742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.dma_write_addr != 0) {
9762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("sdioDrv_WriteAsync: previous DMA op is not finished!\n");
9772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		BUG();
9782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
9792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.dma_write_addr = dma_bus_address;
9812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.dma_write_size = uLen;
9822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	omap_set_dma_src_params     (g_drv.dma_tx_channel,
9842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt									0,			// src_port is only for OMAP1
9852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt									OMAP_DMA_AMODE_POST_INC,
9862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt									dma_bus_address,
9872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt									0, 0);
9882a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	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);
9902a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	omap_start_dma(g_drv.dma_tx_channel);
9922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
993a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	/* Continued at sdiodrv_irq() after DMA transfer is finished */
9942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return 0;
9952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidterr:
9962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return -1;
9972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
9982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
9992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*--------------------------------------------------------------------------------------*/
10002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10012a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_ReadSyncBytes (unsigned int  uFunc,
10022a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                           unsigned int  uHwAddr,
10032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                           unsigned char *pData,
10042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                           unsigned int  uLen,
10052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                           unsigned int  bMore)
10062a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
10072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uCmdArg;
10082a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int i;
10092a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int          iStatus;
10102a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10113df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	for (i = 0; i < uLen; i++) {
10123df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		uCmdArg = SDIO_CMD52_READ(0, uFunc, 0, uHwAddr);
10132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10143df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		iStatus = sdiodrv_send_command(OMAP_HSMMC_CMD52_READ, uCmdArg);
10152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10163df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		if (!(iStatus & CC)) {
10173df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt			PERR("sdioDrv_ReadSyncBytes() SDIO Command error status = 0x%x\n", iStatus);
10183df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt			return -1;
10193df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		}
10203df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		else {
10213df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt			*pData = (unsigned char)(OMAP_HSMMC_READ(RSP10));
10223df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		}
10233df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#ifdef TI_SDIO_DEBUG
10243df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "R52: [0x%x](%u) = 0x%x\n", uHwAddr, uLen, (unsigned)*pData);
10253df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#endif
10262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		uHwAddr++;
10273df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		pData++;
10283df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	}
10292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10303df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	return 0;
10312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
10322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/*--------------------------------------------------------------------------------------*/
10342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint sdioDrv_WriteSyncBytes (unsigned int  uFunc,
10362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                            unsigned int  uHwAddr,
10372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                            unsigned char *pData,
10382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                            unsigned int  uLen,
10392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt                            unsigned int  bMore)
10402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
10412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int uCmdArg;
10422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned int i;
10432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int          iStatus;
10442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10453df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	for (i = 0; i < uLen; i++) {
10463df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#ifdef TI_SDIO_DEBUG
10473df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		printk(KERN_INFO "W52: [0x%x](%u) < 0x%x\n", uHwAddr, uLen, (unsigned)*pData);
10483df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#endif
10493df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		uCmdArg = SDIO_CMD52_WRITE(1, uFunc, 0, uHwAddr, *pData);
10502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10513df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		iStatus = sdiodrv_send_command(OMAP_HSMMC_CMD52_WRITE, uCmdArg);
10523df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		if (!(iStatus & CC)) {
10533df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt			PERR("sdioDrv_WriteSyncBytes() SDIO Command error status = 0x%x\n", iStatus);
10543df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt			return -1;
10553df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		}
10562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		uHwAddr++;
10573df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt		pData++;
10583df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	}
10592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10603df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt	return 0;
10612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
10622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdioDrv_probe(struct platform_device *pdev)
10642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
10652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int rc;
10662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	u32 status;
10672a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#ifdef SDIO_1_BIT /* see also in SdioAdapter.c */
10682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned long clock_rate = 6000000;
10692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#else
10702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	unsigned long clock_rate = 24000000;
10712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#endif
10722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_INFO "TIWLAN SDIO probe: initializing mmc%d device\n", pdev->id + 1);
10742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
10752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* remember device struct for future DMA operations */
10762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.dev = &pdev->dev;
10772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.irq = platform_get_irq(pdev, 0);
10782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.irq < 0)
10792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		return -ENXIO;
1080a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1081a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        rc= request_irq(OMAP_MMC_IRQ, sdiodrv_irq, 0, SDIO_DRIVER_NAME, &g_drv);
1082a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        if (rc != 0) {
1083a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                PERR("sdioDrv_InitHw() - request_irq FAILED!!\n");
1084a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                return rc;
1085a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        }
1086a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        sdiodrv_irq_requested = 1;
1087a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1088a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        rc = sdiodrv_dma_init();
1089a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        if (rc != 0) {
1090a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                PERR("sdiodrv_init() - sdiodrv_dma_init FAILED!!\n");
1091a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                free_irq(OMAP_MMC_IRQ, &g_drv);
1092a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                return rc;
1093a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        }
1094a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        sdiodrv_dma_on = 1;
1095653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt
1096653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	spin_lock_init(&g_drv.clk_lock);
10979b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt
10989b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
10999b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt	dummy_pdev.id = TIWLAN_MMC_CONTROLLER;
11009b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt	dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%lu", TIWLAN_MMC_CONTROLLER);
11019b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt	g_drv.fclk = clk_get(&dummy_pdev.dev, "fck");
11029b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#else
11032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.fclk = clk_get(&pdev->dev, "mmchs_fck");
11049b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#endif
11052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (IS_ERR(g_drv.fclk)) {
11062a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		rc = PTR_ERR(g_drv.fclk);
11072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("clk_get(fclk) FAILED !!!\n");
11082a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		goto err;
11092a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
11102a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	sdiodrv_fclk_got = 1;
11112a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11129b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
11139b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt	g_drv.iclk = clk_get(&dummy_pdev.dev, "ick");
11149b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#else
1115a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	g_drv.iclk = clk_get(&pdev->dev, "mmchs_ick");
11169b3da433c530331aa650193732160d8981ad6c8bDmitry Shmidt#endif
11172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (IS_ERR(g_drv.iclk)) {
11182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		rc = PTR_ERR(g_drv.iclk);
11192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("clk_get(iclk) FAILED !!!\n");
11202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		goto err;
11212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
11222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	sdiodrv_iclk_got = 1;
1123a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1124a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        rc = sdioDrv_clk_enable();
1125a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        if (rc) {
1126a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                PERR("sdioDrv_probe : clk_enable FAILED !!!\n");
1127a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt                goto err;
1128a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt        }
11292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP3430_mmc_reset();
11312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	//obc - init sequence p. 3600,3617
11332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* 1.8V */
11342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(CAPA,		OMAP_HSMMC_READ(CAPA) | VS18);
11352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(HCTL,		OMAP_HSMMC_READ(HCTL) | SDVS18);//SDVS fits p. 3650
11362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* clock gating */
11372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(SYSCONFIG, OMAP_HSMMC_READ(SYSCONFIG) | AUTOIDLE);
11382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* bus power */
11402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(HCTL,		OMAP_HSMMC_READ(HCTL) | SDBP);//SDBP fits p. 3650
11412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* interrupts */
11422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(ISE,		0);
11432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(IE,		IE_EN_MASK);
11442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11452a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	//p. 3601 suggests moving to the end
11462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP3430_mmc_set_clock(clock_rate, &g_drv);
1147a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt	printk(KERN_INFO "SDIO clock Configuration is now set to %dMhz\n",(int)clock_rate/1000000);
11482a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11492a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* Bus width */
11502a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#ifdef SDIO_1_BIT /* see also in SdioAdapter.c */
11512a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("%s() setting %d data lines\n",__FUNCTION__, 1);
11522a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) & (ONE_BIT));
11532a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#else
11542a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	PDEBUG("%s() setting %d data lines\n",__FUNCTION__, 4);
11552a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(HCTL, OMAP_HSMMC_READ(HCTL) | (1 << 1));//DTW 4 bits - p. 3650
11562a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#endif
11572a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11582a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* send the init sequence. 80 clocks of synchronization in the SDIO */
11592a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	//doesn't match p. 3601,3617 - obc
11602a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE( CON, OMAP_HSMMC_READ(CON) | INIT_STREAM);
11612a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_SEND_COMMAND( 0, 0);
11622a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	status = sdiodrv_poll_status(OMAP_HSMMC_STAT, CC, MMC_TIMEOUT_MS);
11632a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (!(status & CC)) {
11642a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		PERR("sdioDrv_InitHw() SDIO Command error status = 0x%x\n", status);
11652a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		rc = -1;
11662a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		goto err;
11672a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
11682a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	OMAP_HSMMC_WRITE(CON, OMAP_HSMMC_READ(CON) & ~INIT_STREAM);
11692a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11702a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return 0;
11712a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidterr:
11722a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	sdiodrv_free_resources();
11732a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return rc;
11742a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
11752a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11762a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdioDrv_remove(struct platform_device *pdev)
11772a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
11782a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_INFO "sdioDrv_remove: calling sdiodrv_shutdown\n");
11792a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11802a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	sdiodrv_shutdown();
11812a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11822a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return 0;
11832a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
11842a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11852a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#ifdef CONFIG_PM
11862a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdioDrv_suspend(struct platform_device *pdev, pm_message_t state)
11872a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
11889a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt#if 0
11892a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	int rc = 0;
1190653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt
11912a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* Tell WLAN driver to suspend, if a suspension function has been registered */
11922a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.wlanDrvIf_pm_suspend) {
11932a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		printk(KERN_INFO "TISDIO: Asking TIWLAN to suspend\n");
11942a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		rc = g_drv.wlanDrvIf_pm_suspend();
11952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		if (rc != 0)
11962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt			return rc;
11972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
11982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
11992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	sdiodrv_shutdown();
12009a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt#endif
12019a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	printk(KERN_INFO "TISDIO: sdioDrv is suspending\n");
12029a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	return 0;
12032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
12042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
12052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt/* Routine to resume the MMC device */
12062a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int sdioDrv_resume(struct platform_device *pdev)
12072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
1208653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt/*	int rc; */
12092a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
12102a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_INFO "TISDIO: sdioDrv is resuming\n");
12119a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt#if 0
12122a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	rc = sdioDrv_probe(pdev);
12132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (rc != 0) {
12142a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		printk(KERN_ERR "TISDIO: resume error\n");
12152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		return rc;
12162a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
12172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
12182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	if (g_drv.wlanDrvIf_pm_resume) {
12192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		printk(KERN_INFO "TISDIO: Asking TIWLAN to resume\n");
12202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		return(g_drv.wlanDrvIf_pm_resume());
12212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	}
12229a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt#endif
12239a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt	return 0;
12242a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
12252a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#else
122664b6e23421bc0b85ae06e6d93a4564a666bf07a6Dmitry Shmidt#define sdioDrv_suspend		NULL
122764b6e23421bc0b85ae06e6d93a4564a666bf07a6Dmitry Shmidt#define sdioDrv_resume		NULL
12282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#endif
12292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
12302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic struct platform_driver sdioDrv_struct = {
12312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	.probe		= sdioDrv_probe,
12322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	.remove		= sdioDrv_remove,
12332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	.suspend	= sdioDrv_suspend,
12342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	.resume		= sdioDrv_resume,
12352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	.driver		= {
12362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt		.name = SDIO_DRIVER_NAME,
12372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	},
12382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt};
12392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
12402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtvoid sdioDrv_register_pm(int (*wlanDrvIf_Start)(void),
12412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt						int (*wlanDrvIf_Stop)(void))
12422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
12432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.wlanDrvIf_pm_resume = wlanDrvIf_Start;
12442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	g_drv.wlanDrvIf_pm_suspend = wlanDrvIf_Stop;
12452a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
12462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
12479a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidtint sdioDrv_clk_enable(void)
1248a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt{
1249a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       unsigned long flags;
1250a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       int ret = 0;
1251a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1252a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       spin_lock_irqsave(&g_drv.clk_lock, flags);
1253a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       if (g_drv.ifclks_enabled)
1254a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt               goto done;
1255a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1256a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       ret = clk_enable(g_drv.iclk);
1257a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       if (ret)
1258a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt              goto clk_en_err1;
1259a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1260a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       ret = clk_enable(g_drv.fclk);
1261a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       if (ret)
1262a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt               goto clk_en_err2;
1263a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       g_drv.ifclks_enabled = 1;
1264a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1265a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       sdioDrv_hsmmc_restore_ctx();
1266a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1267a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtdone:
1268a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1269a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       return ret;
1270a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1271a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtclk_en_err2:
1272a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       clk_disable(g_drv.iclk);
1273a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtclk_en_err1 :
1274a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1275a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       return ret;
1276a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt}
1277a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
12789a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidtvoid sdioDrv_clk_disable(void)
1279a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt{
1280a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       unsigned long flags;
12819a6af3ba4826df0b0206f5ebc3395a9c49482205Dmitry Shmidt
1282a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       spin_lock_irqsave(&g_drv.clk_lock, flags);
1283a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       if (!g_drv.ifclks_enabled)
1284a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt               goto done;
1285a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1286a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       sdioDrv_hsmmc_save_ctx();
1287a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
1288a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       clk_disable(g_drv.fclk);
1289a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       clk_disable(g_drv.iclk);
1290a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       g_drv.ifclks_enabled = 0;
1291a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidtdone:
1292a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt       spin_unlock_irqrestore(&g_drv.clk_lock, flags);
1293a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt}
1294a67e2e5196684101f6b16308dd998cde279d3ba1Dmitry Shmidt
12952a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#ifdef TI_SDIO_STANDALONE
12962a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic int __init sdioDrv_init(void)
12972a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#else
12982a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtint __init sdioDrv_init(int sdcnum)
12992a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#endif
13002a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
13012a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	memset(&g_drv, 0, sizeof(g_drv));
1302653850f71f9caaa41af19cadbab24bb5e655daf4Dmitry Shmidt	memset(&hsmmc_ctx, 0, sizeof(hsmmc_ctx));
13032a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
13042a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	printk(KERN_INFO "TIWLAN SDIO init\n");
13052a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#ifndef TI_SDIO_STANDALONE
13062a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	sdio_init( sdcnum );
13072a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#endif
1308266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	g_drv.sdio_wq = create_freezeable_workqueue(SDIOWQ_NAME);
1309266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	if (!g_drv.sdio_wq) {
1310266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt		printk("TISDIO: Fail to create SDIO WQ\n");
1311266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt		return -EINVAL;
1312266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	}
13132a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* Register the sdio driver */
13142a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	return platform_driver_register(&sdioDrv_struct);
13152a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
13162a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
13172a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#ifdef TI_SDIO_STANDALONE
13182a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtstatic
13192a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#endif
13202a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtvoid __exit sdioDrv_exit(void)
13212a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt{
13222a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	/* Unregister sdio driver */
13232a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt	platform_driver_unregister(&sdioDrv_struct);
1324266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt	if (g_drv.sdio_wq)
1325266077c22ef474c20b103c27f27f2f01f03dfbfeDmitry Shmidt		destroy_workqueue(g_drv.sdio_wq);
13262a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt}
13272a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
13282a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#ifdef TI_SDIO_STANDALONE
13292a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtmodule_init(sdioDrv_init);
13302a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidtmodule_exit(sdioDrv_exit);
13312a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt#endif
13322a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry Shmidt
13332a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_ConnectBus);
13342a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_DisconnectBus);
13352a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_ExecuteCmd);
13362a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_ReadSync);
13372a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_WriteSync);
13382a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_ReadAsync);
13392a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_WriteAsync);
13402a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_ReadSyncBytes);
13412a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_WriteSyncBytes);
13422a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtEXPORT_SYMBOL(sdioDrv_register_pm);
13432a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtMODULE_DESCRIPTION("TI WLAN SDIO driver");
13442a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtMODULE_LICENSE("GPL");
13452a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtMODULE_ALIAS(SDIO_DRIVER_NAME);
13462a41c9bcfdb878f169a6794b7d7e55ec821ffa9cDmitry ShmidtMODULE_AUTHOR("Texas Instruments Inc");
13473df4a33bc0739d3afad19b25d720fc4ea9953938Dmitry Shmidt#endif
1348