summaryrefslogtreecommitdiff
path: root/wl1271/platforms/hw/linux/SdioAdapter.c
diff options
context:
space:
mode:
Diffstat (limited to 'wl1271/platforms/hw/linux/SdioAdapter.c')
-rw-r--r--wl1271/platforms/hw/linux/SdioAdapter.c567
1 files changed, 0 insertions, 567 deletions
diff --git a/wl1271/platforms/hw/linux/SdioAdapter.c b/wl1271/platforms/hw/linux/SdioAdapter.c
deleted file mode 100644
index 9b00e79..0000000
--- a/wl1271/platforms/hw/linux/SdioAdapter.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * SdioAdapter.c
- *
- * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
- * Copyright(c) 2008 - 2009 Google, Inc. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name Texas Instruments nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** \file SdioAdapter.c
- * \brief The SDIO driver adapter. Platform dependent.
- *
- * An adaptation layer between the lower SDIO driver (in BSP) and the upper Sdio
- * Used for issuing all SDIO transaction types towards the lower SDIO-driver.
- * Makes the decision whether to use Sync or Async transaction, and reflects it
- * by the return value and calling its callback in case of Async.
- *
- * \see SdioAdapter.h, SdioDrv.c & h
- */
-
-#ifdef CONFIG_MMC_EMBEDDED_SDIO
-#include <linux/kernel.h>
-#include <linux/mutex.h>
-#include <linux/mmc/core.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include "TxnDefs.h"
-
-#define TI_SDIO_DEBUG
-
-#define TIWLAN_MMC_MAX_DMA 8192
-
-int wifi_set_carddetect( int on );
-
-static struct sdio_func *tiwlan_func = NULL;
-static struct completion sdio_wait;
-
-ETxnStatus sdioAdapt_TransactBytes (unsigned int uFuncId,
- unsigned int uHwAddr,
- void * pHostAddr,
- unsigned int uLength,
- unsigned int bDirection,
- unsigned int bMore);
-
-static int sdio_wifi_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
-{
- int rc;
-
- printk("%s: %d\n", __FUNCTION__, func->class);
-
- if (func->class != SDIO_CLASS_WLAN)
- return -EINVAL;
-
- sdio_claim_host(func);
-
- rc = sdio_enable_func(func);
- if (rc)
- goto err1;
- rc = sdio_set_block_size(func, 512);
-
- if (rc) {
- printk("%s: Unable to set blocksize\n", __FUNCTION__);
- goto err2;
- }
-
- tiwlan_func = func;
- complete(&sdio_wait);
- return 0;
-err2:
- sdio_disable_func(func);
-err1:
- sdio_release_host(func);
- complete(&sdio_wait);
- return rc;
-}
-
-static void sdio_wifi_remove(struct sdio_func *func)
-{
-}
-
-static const struct sdio_device_id sdio_wifi_ids[] = {
- { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) },
- { },
-};
-
-MODULE_DEVICE_TABLE(sdio, sdio_wifi_ids);
-
-static struct sdio_driver sdio_wifi_driver = {
- .probe = sdio_wifi_probe,
- .remove = sdio_wifi_remove,
- .name = "sdio_wifi",
- .id_table = sdio_wifi_ids,
-};
-
-ETxnStatus sdioAdapt_TransactBytes (unsigned int uFuncId,
- unsigned int uHwAddr,
- void * pHostAddr,
- unsigned int uLength,
- unsigned int bDirection,
- unsigned int bMore);
-
-int sdioAdapt_ConnectBus (void * fCbFunc,
- void * hCbArg,
- unsigned int uBlkSizeShift,
- unsigned int uSdioThreadPriority,
- unsigned char **pTxDmaSrcAddr)
-{
- int rc;
-
- init_completion(&sdio_wait);
- wifi_set_carddetect( 1 );
- rc = sdio_register_driver(&sdio_wifi_driver);
- if (rc < 0) {
- printk(KERN_ERR "%s: Fail to register sdio_wifi_driver\n", __func__);
- return rc;
- }
- if (!wait_for_completion_timeout(&sdio_wait, msecs_to_jiffies(10000))) {
- printk(KERN_ERR "%s: Timed out waiting for device detect\n", __func__);
- sdio_unregister_driver(&sdio_wifi_driver);
- return -ENODEV;
- }
- /* Provide the DMA buffer address to the upper layer so it will use it as the transactions host buffer. */
- if (pTxDmaSrcAddr) { /* Dm: check what to do with it */
- *pTxDmaSrcAddr = kmalloc(TIWLAN_MMC_MAX_DMA, GFP_KERNEL | GFP_DMA);
- }
- return 0;
-}
-
-int sdioAdapt_DisconnectBus (void)
-{
- if (tiwlan_func) {
- sdio_disable_func( tiwlan_func );
- sdio_release_host( tiwlan_func );
- }
- wifi_set_carddetect( 0 );
- sdio_unregister_driver(&sdio_wifi_driver);
- return 0;
-}
-
-ETxnStatus sdioAdapt_TransactBytes (unsigned int uFuncId,
- unsigned int uHwAddr,
- void * pHostAddr,
- unsigned int uLength,
- unsigned int bDirection,
- unsigned int bMore)
-{
- unsigned char *pData = pHostAddr;
- unsigned int i;
- int rc = 0, final_rc = 0;
-
- for (i = 0; i < uLength; i++) {
- if( bDirection ) {
- if (uFuncId == 0)
- *pData = (unsigned char)sdio_f0_readb(tiwlan_func, uHwAddr, &rc);
- else
- *pData = (unsigned char)sdio_readb(tiwlan_func, uHwAddr, &rc);
- }
- else {
- if (uFuncId == 0)
- sdio_f0_writeb(tiwlan_func, *pData, uHwAddr, &rc);
- else
- sdio_writeb(tiwlan_func, *pData, uHwAddr, &rc);
- }
- if( rc ) {
- final_rc = rc;
- }
-#ifdef TI_SDIO_DEBUG
- printk(KERN_INFO "%c52: [0x%x](%u) %c 0x%x\n", (bDirection ? 'R' : 'W'), uHwAddr, uLength, (bDirection ? '=' : '<'), (unsigned)*pData);
-#endif
- uHwAddr++;
- pData++;
- }
- /* If failed return ERROR, if succeeded return COMPLETE */
- if (final_rc) {
- return TXN_STATUS_ERROR;
- }
- return TXN_STATUS_COMPLETE;
-}
-
-ETxnStatus sdioAdapt_Transact (unsigned int uFuncId,
- unsigned int uHwAddr,
- void * pHostAddr,
- unsigned int uLength,
- unsigned int bDirection,
- unsigned int bBlkMode,
- unsigned int bFixedAddr,
- unsigned int bMore)
-{
- int rc;
-
- if (uFuncId == 0)
- return sdioAdapt_TransactBytes (uFuncId, uHwAddr, pHostAddr,
- uLength, bDirection, bMore);
- if (bDirection) {
- if (bFixedAddr)
- rc = sdio_memcpy_fromio(tiwlan_func, pHostAddr, uHwAddr, uLength);
- else
- rc = sdio_readsb(tiwlan_func, pHostAddr, uHwAddr, uLength);
-
- }
- else {
- if (bFixedAddr)
- rc = sdio_memcpy_toio(tiwlan_func, uHwAddr, pHostAddr, uLength);
- else
- rc = sdio_writesb(tiwlan_func, uHwAddr, pHostAddr, uLength);
- }
-#ifdef TI_SDIO_DEBUG
- if (uLength == 1)
- printk(KERN_INFO "%c53: [0x%x](%u) %c 0x%x\n", (bDirection ? 'R' : 'W'), uHwAddr, uLength, (bDirection ? '=' : '<'), (unsigned)(*(char *)pHostAddr));
- else if (uLength == 2)
- printk(KERN_INFO "%c53: [0x%x](%u) %c 0x%x\n", (bDirection ? 'R' : 'W'), uHwAddr, uLength, (bDirection ? '=' : '<'), (unsigned)(*(short *)pHostAddr));
- else if (uLength == 4)
- printk(KERN_INFO "%c53: [0x%x](%u) %c 0x%x\n", (bDirection ? 'R' : 'W'), uHwAddr, uLength, (bDirection ? '=' : '<'), (unsigned)(*(long *)pHostAddr));
- else
- printk(KERN_INFO "%c53: [0x%x](%u) F[%d] B[%d] I[%d] = %d\n", (bDirection ? 'R' : 'W'), uHwAddr, uLength, uFuncId, bBlkMode, bFixedAddr, rc);
-#endif
- /* If failed return ERROR, if succeeded return COMPLETE */
- if (rc) {
- return TXN_STATUS_ERROR;
- }
- return TXN_STATUS_COMPLETE;
-}
-
-#else
-
-#include "SdioDrvDbg.h"
-#include "TxnDefs.h"
-#include "SdioAdapter.h"
-#include "SdioDrv.h"
-#include "bmtrace_api.h"
-#include <linux/slab.h>
-
-#ifdef SDIO_1_BIT /* see also in SdioDrv.c */
-#define SDIO_BITS_CODE 0x80 /* 1 bits */
-#else
-#define SDIO_BITS_CODE 0x82 /* 4 bits */
-#endif
-
-static unsigned char *pDmaBufAddr = 0;
-
-/************************************************************************
- * Defines
- ************************************************************************/
-/* Sync/Async Threshold */
-#ifdef FULL_ASYNC_MODE
-#define SYNC_ASYNC_LENGTH_THRESH 0 /* Use Async for all transactions */
-#else
-#define SYNC_ASYNC_LENGTH_THRESH 360 /* Use Async for transactions longer than this threshold (in bytes) */
-#endif
-
-#define MAX_RETRIES 10
-
-#define MAX_BUS_TXN_SIZE 8192 /* Max bus transaction size in bytes (for the DMA buffer allocation) */
-
-/* For block mode configuration */
-#define FN0_FBR2_REG_108 0x210
-#define FN0_FBR2_REG_108_BIT_MASK 0xFFF
-
-int sdioAdapt_ConnectBus (void * fCbFunc,
- void * hCbArg,
- unsigned int uBlkSizeShift,
- unsigned int uSdioThreadPriority,
- unsigned char **pRxDmaBufAddr,
- unsigned int *pRxDmaBufLen,
- unsigned char **pTxDmaBufAddr,
- unsigned int *pTxDmaBufLen)
-{
- unsigned char uByte;
- unsigned long uLong;
- unsigned long uCount = 0;
- unsigned int uBlkSize = 1 << uBlkSizeShift;
- int iStatus;
-
- if (uBlkSize < SYNC_ASYNC_LENGTH_THRESH)
- {
- PERR1("%s(): Block-Size should be bigger than SYNC_ASYNC_LENGTH_THRESH!!\n", __FUNCTION__ );
- }
-
- /* Enabling clocks if thet are not enabled */
- sdioDrv_clk_enable();
-
- /* Allocate a DMA-able buffer and provide it to the upper layer to be used for all read and write transactions */
- if (pDmaBufAddr == 0) /* allocate only once (in case this function is called multiple times) */
- {
- pDmaBufAddr = kmalloc(MAX_BUS_TXN_SIZE, GFP_KERNEL | GFP_DMA);
- if (pDmaBufAddr == 0)
- {
- iStatus = -1;
- goto fail;
- }
- }
- *pRxDmaBufAddr = *pTxDmaBufAddr = pDmaBufAddr;
- *pRxDmaBufLen = *pTxDmaBufLen = MAX_BUS_TXN_SIZE;
-
- /* Init SDIO driver and HW */
- iStatus = sdioDrv_ConnectBus (fCbFunc, hCbArg, uBlkSizeShift, uSdioThreadPriority);
- if (iStatus) { goto fail; }
-
- /* Send commands sequence: 0, 5, 3, 7 */
- iStatus = sdioDrv_ExecuteCmd (SD_IO_GO_IDLE_STATE, 0, MMC_RSP_NONE, &uByte, sizeof(uByte));
- if (iStatus)
- {
- printk("%s %d command number: %d failed\n", __FUNCTION__, __LINE__, SD_IO_GO_IDLE_STATE);
- goto fail;
- }
-
- iStatus = sdioDrv_ExecuteCmd (SDIO_CMD5, VDD_VOLTAGE_WINDOW, MMC_RSP_R4, &uByte, sizeof(uByte));
- if (iStatus) {
- printk("%s %d command number: %d failed\n", __FUNCTION__, __LINE__, SDIO_CMD5);
- goto fail;
- }
-
- iStatus = sdioDrv_ExecuteCmd (SD_IO_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6, &uLong, sizeof(uLong));
- if (iStatus) {
- printk("%s %d command number: %d failed\n", __FUNCTION__, __LINE__, SD_IO_SEND_RELATIVE_ADDR);
- goto fail;
- }
-
- iStatus = sdioDrv_ExecuteCmd (SD_IO_SELECT_CARD, uLong, MMC_RSP_R6, &uByte, sizeof(uByte));
- if (iStatus) {
- printk("%s %d command number: %d failed\n", __FUNCTION__, __LINE__, SD_IO_SELECT_CARD);
- goto fail;
- }
-
- /* NOTE:
- * =====
- * Each of the following loops is a workaround for a HW bug that will be solved in PG1.1 !!
- * Each write of CMD-52 to function-0 should use it as follows:
- * 1) Write the desired byte using CMD-52
- * 2) Read back the byte using CMD-52
- * 3) Write two dummy bytes to address 0xC8 using CMD-53
- * 4) If the byte read in step 2 is different than the written byte repeat the sequence
- */
-
- /* set device side bus width to 4 bit (for 1 bit write 0x80 instead of 0x82) */
- do
- {
- uByte = SDIO_BITS_CODE;
- iStatus = sdioDrv_WriteSyncBytes (TXN_FUNC_ID_CTRL, CCCR_BUS_INTERFACE_CONTOROL, &uByte, 1, 1);
- if (iStatus) { goto fail; }
-
- iStatus = sdioDrv_ReadSyncBytes (TXN_FUNC_ID_CTRL, CCCR_BUS_INTERFACE_CONTOROL, &uByte, 1, 1);
- if (iStatus) { goto fail; }
-
- iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, 0xC8, &uLong, 2, 1, 1);
- if (iStatus) { goto fail; }
-
- uCount++;
-
- } while ((uByte != SDIO_BITS_CODE) && (uCount < MAX_RETRIES));
-
- uCount = 0;
-
- /* allow function 2 */
- do
- {
- uByte = 4;
- iStatus = sdioDrv_WriteSyncBytes (TXN_FUNC_ID_CTRL, CCCR_IO_ENABLE, &uByte, 1, 1);
- if (iStatus) { goto fail; }
-
- iStatus = sdioDrv_ReadSyncBytes (TXN_FUNC_ID_CTRL, CCCR_IO_ENABLE, &uByte, 1, 1);
- if (iStatus) { goto fail; }
-
- iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, 0xC8, &uLong, 2, 1, 1);
- if (iStatus) { goto fail; }
-
- uCount++;
-
- } while ((uByte != 4) && (uCount < MAX_RETRIES));
-
-
-#ifdef SDIO_IN_BAND_INTERRUPT
-
- uCount = 0;
-
- do
- {
- uByte = 3;
- iStatus = sdioDrv_WriteSyncBytes (TXN_FUNC_ID_CTRL, CCCR_INT_ENABLE, &uByte, 1, 1);
- if (iStatus) { goto fail; }
-
- iStatus = sdioDrv_ReadSyncBytes (TXN_FUNC_ID_CTRL, CCCR_INT_ENABLE, &uByte, 1, 1);
- if (iStatus) { goto fail; }
-
- iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, 0xC8, &uLong, 2, 1, 1);
- if (iStatus) { goto fail; }
-
- uCount++;
-
- } while ((uByte != 3) && (uCount < MAX_RETRIES));
-
-
-#endif
-
- uCount = 0;
-
- /* set block size for SDIO block mode */
- do
- {
- uLong = uBlkSize;
- iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, FN0_FBR2_REG_108, &uLong, 2, 1, 1);
- if (iStatus) { goto fail; }
-
- iStatus = sdioDrv_ReadSync (TXN_FUNC_ID_CTRL, FN0_FBR2_REG_108, &uLong, 2, 1, 1);
- if (iStatus) { goto fail; }
-
- iStatus = sdioDrv_WriteSync (TXN_FUNC_ID_CTRL, 0xC8, &uLong, 2, 1, 1);
- if (iStatus) { goto fail; }
-
- uCount++;
-
- } while (((uLong & FN0_FBR2_REG_108_BIT_MASK) != uBlkSize) && (uCount < MAX_RETRIES));
-
- if (uCount >= MAX_RETRIES)
- {
- /* Failed to write CMD52_WRITE to function 0 */
- iStatus = (int)uCount;
- }
-
-fail:
- /* Disable the clocks for now */
- sdioDrv_clk_disable();
-
- return iStatus;
-}
-
-
-int sdioAdapt_DisconnectBus (void)
-{
- if (pDmaBufAddr)
- {
- kfree (pDmaBufAddr);
- pDmaBufAddr = 0;
- }
-
- return sdioDrv_DisconnectBus ();
-}
-
-ETxnStatus sdioAdapt_Transact (unsigned int uFuncId,
- unsigned int uHwAddr,
- void * pHostAddr,
- unsigned int uLength,
- unsigned int bDirection,
- unsigned int bBlkMode,
- unsigned int bFixedAddr,
- unsigned int bMore)
-{
- int iStatus;
-
- /* If transction length is below threshold, use Sync methods */
- if (uLength < SYNC_ASYNC_LENGTH_THRESH)
- {
- /* Call read or write Sync method */
- if (bDirection)
- {
- CL_TRACE_START_L2();
- iStatus = sdioDrv_ReadSync (uFuncId, uHwAddr, pHostAddr, uLength, bFixedAddr, bMore);
- CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "SDIO", ".ReadSync");
- }
- else
- {
- CL_TRACE_START_L2();
- iStatus = sdioDrv_WriteSync (uFuncId, uHwAddr, pHostAddr, uLength, bFixedAddr, bMore);
- CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "SDIO", ".WriteSync");
- }
-
- /* If failed return ERROR, if succeeded return COMPLETE */
- if (iStatus)
- {
- return TXN_STATUS_ERROR;
- }
- return TXN_STATUS_COMPLETE;
- }
-
- /* If transction length is above threshold, use Async methods */
- else
- {
- /* Call read or write Async method */
- if (bDirection)
- {
- CL_TRACE_START_L2();
- iStatus = sdioDrv_ReadAsync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
- CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "SDIO", ".ReadAsync");
- }
- else
- {
- CL_TRACE_START_L2();
- iStatus = sdioDrv_WriteAsync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
- CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "SDIO", ".WriteAsync");
- }
-
- /* If failed return ERROR, if succeeded return PENDING */
- if (iStatus)
- {
- return TXN_STATUS_ERROR;
- }
- return TXN_STATUS_PENDING;
- }
-}
-
-ETxnStatus sdioAdapt_TransactBytes (unsigned int uFuncId,
- unsigned int uHwAddr,
- void * pHostAddr,
- unsigned int uLength,
- unsigned int bDirection,
- unsigned int bMore)
-{
- static unsigned int lastMore = 0;
- int iStatus;
-
- if ((bMore == 1) || (lastMore == bMore))
- {
- sdioDrv_cancel_inact_timer();
- sdioDrv_clk_enable();
- }
-
- /* Call read or write bytes Sync method */
- if (bDirection)
- {
- iStatus = sdioDrv_ReadSyncBytes (uFuncId, uHwAddr, pHostAddr, uLength, bMore);
- }
- else
- {
- iStatus = sdioDrv_WriteSyncBytes (uFuncId, uHwAddr, pHostAddr, uLength, bMore);
- }
-
- if (bMore == 0)
- {
- sdioDrv_start_inact_timer();
- }
- lastMore = bMore;
-
- /* If failed return ERROR, if succeeded return COMPLETE */
- if (iStatus)
- {
- return TXN_STATUS_ERROR;
- }
- return TXN_STATUS_COMPLETE;
-}
-#endif