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