1236 lines
25 KiB
C
1236 lines
25 KiB
C
|
/*
|
||
|
* SDIO IO common routines
|
||
|
*
|
||
|
* $Id: sdio_core.c,v 1.27.2.31 2010/12/31 08:37:43 family Exp $
|
||
|
*
|
||
|
* Copyright (c) 2009 Realtek Semiconductor Corp.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License version 2 as
|
||
|
* published by the Free Software Foundation.
|
||
|
*/
|
||
|
|
||
|
#define _SDIO_IO_C_
|
||
|
|
||
|
#ifdef __KERNEL__
|
||
|
#include <linux/mmc/host.h>
|
||
|
#include <linux/mmc/card.h>
|
||
|
#include <linux/mmc/sdio.h>
|
||
|
#endif
|
||
|
|
||
|
#include "8192cd.h"
|
||
|
#include "8192cd_headers.h"
|
||
|
#include "8192cd_debug.h"
|
||
|
|
||
|
#define SDIO_ERR_VAL8 0xEA
|
||
|
#define SDIO_ERR_VAL16 0xEAEA
|
||
|
#define SDIO_ERR_VAL32 0xEAEAEAEA
|
||
|
|
||
|
u8 sd_f0_read8(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u8 v;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
v = sdio_f0_readb(func, addr, err);
|
||
|
sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
void sd_f0_write8(struct rtl8192cd_priv *priv, u32 addr, u8 v, s32 *err)
|
||
|
{
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
sdio_f0_writeb(func, v, addr, err);
|
||
|
sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Return:
|
||
|
* 0 Success
|
||
|
* others Fail
|
||
|
*/
|
||
|
s32 _sd_cmd52_read(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pdata)
|
||
|
{
|
||
|
int err, i;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
err = 0;
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
for (i = 0; i < cnt; i++) {
|
||
|
pdata[i] = sdio_readb(func, addr+i, &err);
|
||
|
if (err) {
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, err, addr);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Return:
|
||
|
* 0 Success
|
||
|
* others Fail
|
||
|
*/
|
||
|
s32 sd_cmd52_read(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pdata)
|
||
|
{
|
||
|
int err;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
err = 0;
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
err = _sd_cmd52_read(priv, addr, cnt, pdata);
|
||
|
sdio_release_host(func);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Return:
|
||
|
* 0 Success
|
||
|
* others Fail
|
||
|
*/
|
||
|
s32 _sd_cmd52_write(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pdata)
|
||
|
{
|
||
|
int err, i;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
err = 0;
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
for (i = 0; i < cnt; i++) {
|
||
|
sdio_writeb(func, pdata[i], addr+i, &err);
|
||
|
if (err) {
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr, pdata[i]);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Return:
|
||
|
* 0 Success
|
||
|
* others Fail
|
||
|
*/
|
||
|
s32 sd_cmd52_write(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pdata)
|
||
|
{
|
||
|
int err;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
err = 0;
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
err = _sd_cmd52_write(priv, addr, cnt, pdata);
|
||
|
sdio_release_host(func);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
u8 _sd_read8(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u8 v;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
//sdio_claim_host(func);
|
||
|
v = sdio_readb(func, addr, err);
|
||
|
//sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
u8 sd_read8(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u8 v;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
v = sdio_readb(func, addr, err);
|
||
|
sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
u16 sd_read16(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u16 v;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
v = sdio_readw(func, addr, err);
|
||
|
sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
u32 _sd_read32(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u32 v;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
//sdio_claim_host(func);
|
||
|
v = sdio_readl(func, addr, err);
|
||
|
//sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
u32 sd_read32(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u32 v;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
v = sdio_readl(func, addr, err);
|
||
|
sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
|
||
|
|
||
|
return v;
|
||
|
}
|
||
|
|
||
|
void sd_write8(struct rtl8192cd_priv *priv, u32 addr, u8 v, s32 *err)
|
||
|
{
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
sdio_writeb(func, v, addr, err);
|
||
|
sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v);
|
||
|
}
|
||
|
|
||
|
void sd_write16(struct rtl8192cd_priv *priv, u32 addr, u16 v, s32 *err)
|
||
|
{
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
sdio_writew(func, v, addr, err);
|
||
|
sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%04x\n", __func__, *err, addr, v);
|
||
|
}
|
||
|
|
||
|
void _sd_write32(struct rtl8192cd_priv *priv, u32 addr, u32 v, s32 *err)
|
||
|
{
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
//sdio_claim_host(func);
|
||
|
sdio_writel(func, v, addr, err);
|
||
|
//sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%08x\n", __func__, *err, addr, v);
|
||
|
}
|
||
|
|
||
|
void sd_write32(struct rtl8192cd_priv *priv, u32 addr, u32 v, s32 *err)
|
||
|
{
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
sdio_writel(func, v, addr, err);
|
||
|
sdio_release_host(func);
|
||
|
if (err && *err)
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%08x\n", __func__, *err, addr, v);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Use CMD53 to read data from SDIO device.
|
||
|
* This function MUST be called after sdio_claim_host() or
|
||
|
* in SDIO ISR(host had been claimed).
|
||
|
*
|
||
|
* Parameters:
|
||
|
* psdio pointer of SDIO_DATA
|
||
|
* addr address to read
|
||
|
* cnt amount to read
|
||
|
* pdata pointer to put data, this should be a "DMA:able scratch buffer"!
|
||
|
*
|
||
|
* Return:
|
||
|
* 0 Success
|
||
|
* others Fail
|
||
|
*/
|
||
|
s32 _sd_read(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, void *pdata)
|
||
|
{
|
||
|
int err;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
if (unlikely((cnt==1) || (cnt==2)))
|
||
|
{
|
||
|
int i;
|
||
|
u8 *pbuf = (u8*)pdata;
|
||
|
|
||
|
for (i = 0; i < cnt; i++)
|
||
|
{
|
||
|
*(pbuf+i) = sdio_readb(func, addr+i, &err);
|
||
|
|
||
|
if (err) {
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, err, addr);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
err = sdio_memcpy_fromio(func, pdata, addr, cnt);
|
||
|
if (err) {
|
||
|
printk(KERN_ERR "%s: FAIL(%d)! ADDR=%#x Size=%d\n", __func__, err, addr, cnt);
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Use CMD53 to read data from SDIO device.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* psdio pointer of SDIO_DATA
|
||
|
* addr address to read
|
||
|
* cnt amount to read
|
||
|
* pdata pointer to put data, this should be a "DMA:able scratch buffer"!
|
||
|
*
|
||
|
* Return:
|
||
|
* 0 Success
|
||
|
* others Fail
|
||
|
*/
|
||
|
s32 sd_read(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, void *pdata)
|
||
|
{
|
||
|
s32 err;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
err = _sd_read(priv, addr, cnt, pdata);
|
||
|
sdio_release_host(func);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Use CMD53 to write data to SDIO device.
|
||
|
* This function MUST be called after sdio_claim_host() or
|
||
|
* in SDIO ISR(host had been claimed).
|
||
|
*
|
||
|
* Parameters:
|
||
|
* psdio pointer of SDIO_DATA
|
||
|
* addr address to write
|
||
|
* cnt amount to write
|
||
|
* pdata data pointer, this should be a "DMA:able scratch buffer"!
|
||
|
*
|
||
|
* Return:
|
||
|
* 0 Success
|
||
|
* others Fail
|
||
|
*/
|
||
|
s32 _sd_write(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, void *pdata)
|
||
|
{
|
||
|
int err;
|
||
|
struct sdio_func *func;
|
||
|
u32 size;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
// size = sdio_align_size(func, cnt);
|
||
|
|
||
|
if (unlikely((cnt==1) || (cnt==2)))
|
||
|
{
|
||
|
int i;
|
||
|
u8 *pbuf = (u8*)pdata;
|
||
|
|
||
|
for (i = 0; i < cnt; i++)
|
||
|
{
|
||
|
sdio_writeb(func, *(pbuf+i), addr+i, &err);
|
||
|
if (err) {
|
||
|
printk(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr, *(pbuf+i));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
size = cnt;
|
||
|
err = sdio_memcpy_toio(func, addr, pdata, size);
|
||
|
if (err) {
|
||
|
printk(KERN_ERR "%s: FAIL(%d)! ADDR=%#x Size=%d(%d)\n", __func__, err, addr, cnt, size);
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Use CMD53 to write data to SDIO device.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* psdio pointer of SDIO_DATA
|
||
|
* addr address to write
|
||
|
* cnt amount to write
|
||
|
* pdata data pointer, this should be a "DMA:able scratch buffer"!
|
||
|
*
|
||
|
* Return:
|
||
|
* 0 Success
|
||
|
* others Fail
|
||
|
*/
|
||
|
s32 sd_write(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, void *pdata)
|
||
|
{
|
||
|
s32 err;
|
||
|
struct sdio_func *func;
|
||
|
|
||
|
func = priv->pshare->psdio_func;
|
||
|
|
||
|
sdio_claim_host(func);
|
||
|
err = _sd_write(priv, addr, cnt, pdata);
|
||
|
sdio_release_host(func);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
extern void HalSdioGetCmdAddr8723ASdio(struct rtl8192cd_priv *priv, u8 DeviceID, u32 Addr, u32* pCmdAddr);
|
||
|
extern u8 get_deviceid(u32 addr);
|
||
|
extern u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset);
|
||
|
|
||
|
u8 _sdio_read8(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u32 ftaddr;
|
||
|
u8 val;
|
||
|
|
||
|
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||
|
val = _sd_read8(priv, ftaddr, err);
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
u8 sdio_read8(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u32 ftaddr;
|
||
|
u8 val;
|
||
|
|
||
|
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||
|
val = sd_read8(priv, ftaddr, err);
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
u16 sdio_read16(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u32 ftaddr;
|
||
|
u16 val;
|
||
|
s32 ret;
|
||
|
|
||
|
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||
|
ret = sd_cmd52_read(priv, ftaddr, 2, (u8*)&val);
|
||
|
val = le16_to_cpu(val);
|
||
|
|
||
|
if (err)
|
||
|
*err = ret;
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
u32 _sdio_read32(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u8 deviceId;
|
||
|
u16 offset;
|
||
|
u32 ftaddr;
|
||
|
u8 shift;
|
||
|
u32 val;
|
||
|
s32 ret;
|
||
|
|
||
|
ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
|
||
|
|
||
|
if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
|
||
|
|| (FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
ret = _sd_cmd52_read(priv, ftaddr, 4, (u8*)&val);
|
||
|
#ifdef SDIO_DEBUG_IO
|
||
|
if (ret) {
|
||
|
printk(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, ret, addr);
|
||
|
return SDIO_ERR_VAL32;
|
||
|
}
|
||
|
#endif
|
||
|
val = le32_to_cpu(val);
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
// 4 bytes alignment
|
||
|
shift = ftaddr & 0x3;
|
||
|
if (shift == 0) {
|
||
|
val = _sd_read32(priv, ftaddr, &ret);
|
||
|
} else {
|
||
|
u8 tmpbuf[8];
|
||
|
|
||
|
ftaddr &= ~0x3;
|
||
|
ret = _sd_read(priv, ftaddr, 8, tmpbuf);
|
||
|
memcpy(&val, tmpbuf+shift, 4);
|
||
|
val = le32_to_cpu(val);
|
||
|
}
|
||
|
|
||
|
if (err)
|
||
|
*err = ret;
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
u32 sdio_read32(struct rtl8192cd_priv *priv, u32 addr, s32 *err)
|
||
|
{
|
||
|
u8 deviceId;
|
||
|
u16 offset;
|
||
|
u32 ftaddr;
|
||
|
u8 shift;
|
||
|
u32 val;
|
||
|
s32 ret;
|
||
|
|
||
|
ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
|
||
|
|
||
|
if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
|
||
|
|| (FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
ret = sd_cmd52_read(priv, ftaddr, 4, (u8*)&val);
|
||
|
#ifdef SDIO_DEBUG_IO
|
||
|
if (ret) {
|
||
|
printk(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, ret, addr);
|
||
|
return SDIO_ERR_VAL32;
|
||
|
}
|
||
|
#endif
|
||
|
val = le32_to_cpu(val);
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
// 4 bytes alignment
|
||
|
shift = ftaddr & 0x3;
|
||
|
if (shift == 0) {
|
||
|
val = sd_read32(priv, ftaddr, &ret);
|
||
|
} else {
|
||
|
u8 tmpbuf[8];
|
||
|
|
||
|
ftaddr &= ~0x3;
|
||
|
ret = sd_read(priv, ftaddr, 8, tmpbuf);
|
||
|
memcpy(&val, tmpbuf+shift, 4);
|
||
|
val = le32_to_cpu(val);
|
||
|
}
|
||
|
|
||
|
if (err)
|
||
|
*err = ret;
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
s32 sdio_readN(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pbuf)
|
||
|
{
|
||
|
u8 deviceId;
|
||
|
u16 offset;
|
||
|
u32 ftaddr;
|
||
|
u8 shift;
|
||
|
s32 err;
|
||
|
|
||
|
err = 0;
|
||
|
ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
|
||
|
|
||
|
if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
|
||
|
|| (FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
err = sd_cmd52_read(priv, ftaddr, cnt, pbuf);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
// 4 bytes alignment
|
||
|
shift = ftaddr & 0x3;
|
||
|
if (shift == 0) {
|
||
|
err = sd_read(priv, ftaddr, cnt, pbuf);
|
||
|
} else {
|
||
|
u8 *ptmpbuf;
|
||
|
u32 n;
|
||
|
|
||
|
ftaddr &= ~0x3;
|
||
|
n = cnt + shift;
|
||
|
ptmpbuf = rtw_malloc(n);
|
||
|
if (NULL == ptmpbuf) return -ENOMEM;
|
||
|
|
||
|
err = sd_read(priv, ftaddr, n, ptmpbuf);
|
||
|
if (!err)
|
||
|
memcpy(pbuf, ptmpbuf+shift, cnt);
|
||
|
|
||
|
rtw_mfree(ptmpbuf, n);
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
s32 sdio_write8(struct rtl8192cd_priv *priv, u32 addr, u8 val)
|
||
|
{
|
||
|
u32 ftaddr;
|
||
|
s32 err;
|
||
|
|
||
|
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||
|
sd_write8(priv, ftaddr, val, &err);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
s32 sdio_write16(struct rtl8192cd_priv *priv, u32 addr, u16 val)
|
||
|
{
|
||
|
u32 ftaddr;
|
||
|
s32 err;
|
||
|
|
||
|
ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
|
||
|
val = cpu_to_le16(val);
|
||
|
err = sd_cmd52_write(priv, ftaddr, 2, (u8*)&val);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
s32 _sdio_write32(struct rtl8192cd_priv *priv, u32 addr, u32 val)
|
||
|
{
|
||
|
u8 deviceId;
|
||
|
u16 offset;
|
||
|
u32 ftaddr;
|
||
|
u8 shift;
|
||
|
s32 err;
|
||
|
|
||
|
err = 0;
|
||
|
ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
|
||
|
|
||
|
if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
|
||
|
|| (FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
val = cpu_to_le32(val);
|
||
|
err = _sd_cmd52_write(priv, ftaddr, 4, (u8*)&val);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
// 4 bytes alignment
|
||
|
shift = ftaddr & 0x3;
|
||
|
#if 1
|
||
|
if (shift == 0)
|
||
|
{
|
||
|
_sd_write32(priv, ftaddr, val, &err);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
val = cpu_to_le32(val);
|
||
|
err = _sd_cmd52_write(priv, ftaddr, 4, (u8*)&val);
|
||
|
}
|
||
|
#else
|
||
|
if (shift == 0) {
|
||
|
sd_write32(priv, ftaddr, val, &err);
|
||
|
} else {
|
||
|
u8 *ptmpbuf;
|
||
|
|
||
|
ptmpbuf = (u8*)rtw_malloc(8);
|
||
|
if (NULL == ptmpbuf) return -ENOMEM;
|
||
|
|
||
|
ftaddr &= ~0x3;
|
||
|
err = sd_read(priv, ftaddr, 8, ptmpbuf);
|
||
|
if (err) {
|
||
|
_rtw_mfree(ptmpbuf, 8);
|
||
|
return err;
|
||
|
}
|
||
|
val = cpu_to_le32(val);
|
||
|
memcpy(ptmpbuf+shift, &val, 4);
|
||
|
err = sd_write(priv, ftaddr, 8, ptmpbuf);
|
||
|
|
||
|
rtw_mfree(ptmpbuf, 8);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
s32 sdio_write32(struct rtl8192cd_priv *priv, u32 addr, u32 val)
|
||
|
{
|
||
|
u8 deviceId;
|
||
|
u16 offset;
|
||
|
u32 ftaddr;
|
||
|
u8 shift;
|
||
|
s32 err;
|
||
|
|
||
|
err = 0;
|
||
|
ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
|
||
|
|
||
|
if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
|
||
|
|| (FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
val = cpu_to_le32(val);
|
||
|
err = sd_cmd52_write(priv, ftaddr, 4, (u8*)&val);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
// 4 bytes alignment
|
||
|
shift = ftaddr & 0x3;
|
||
|
#if 1
|
||
|
if (shift == 0)
|
||
|
{
|
||
|
sd_write32(priv, ftaddr, val, &err);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
val = cpu_to_le32(val);
|
||
|
err = sd_cmd52_write(priv, ftaddr, 4, (u8*)&val);
|
||
|
}
|
||
|
#else
|
||
|
if (shift == 0) {
|
||
|
sd_write32(priv, ftaddr, val, &err);
|
||
|
} else {
|
||
|
u8 *ptmpbuf;
|
||
|
|
||
|
ptmpbuf = (u8*)rtw_malloc(8);
|
||
|
if (NULL == ptmpbuf) return -ENOMEM;
|
||
|
|
||
|
ftaddr &= ~0x3;
|
||
|
err = sd_read(priv, ftaddr, 8, ptmpbuf);
|
||
|
if (err) {
|
||
|
rtw_mfree(ptmpbuf, 8);
|
||
|
return err;
|
||
|
}
|
||
|
val = cpu_to_le32(val);
|
||
|
memcpy(ptmpbuf+shift, &val, 4);
|
||
|
err = sd_write(priv, ftaddr, 8, ptmpbuf);
|
||
|
|
||
|
rtw_mfree(ptmpbuf, 8);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
s32 sdio_writeN(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8* pbuf)
|
||
|
{
|
||
|
u8 deviceId;
|
||
|
u16 offset;
|
||
|
u32 ftaddr;
|
||
|
u8 shift;
|
||
|
s32 err;
|
||
|
|
||
|
err = 0;
|
||
|
ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
|
||
|
|
||
|
if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
|
||
|
|| (FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
err = sd_cmd52_write(priv, ftaddr, cnt, pbuf);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
shift = ftaddr & 0x3;
|
||
|
if (shift == 0) {
|
||
|
err = sd_write(priv, ftaddr, cnt, pbuf);
|
||
|
} else {
|
||
|
u8 *ptmpbuf;
|
||
|
u32 n;
|
||
|
|
||
|
ftaddr &= ~0x3;
|
||
|
n = cnt + shift;
|
||
|
ptmpbuf = rtw_malloc(n);
|
||
|
if (NULL == ptmpbuf) return -ENOMEM;
|
||
|
err = sd_read(priv, ftaddr, 4, ptmpbuf);
|
||
|
if (err) {
|
||
|
rtw_mfree(ptmpbuf, n);
|
||
|
return err;
|
||
|
}
|
||
|
memcpy(ptmpbuf+shift, pbuf, cnt);
|
||
|
err = sd_write(priv, ftaddr, n, ptmpbuf);
|
||
|
rtw_mfree(ptmpbuf, n);
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Description:
|
||
|
* Read from RX FIFO
|
||
|
* Round read size to block size,
|
||
|
* and make sure data transfer will be done in one command.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* pintfhdl a pointer of intf_hdl
|
||
|
* addr port ID
|
||
|
* cnt size to read
|
||
|
* rmem address to put data
|
||
|
*
|
||
|
* Return:
|
||
|
* = 0 Success
|
||
|
* != 0 Fail
|
||
|
*/
|
||
|
u32 sdio_read_port(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *mem)
|
||
|
{
|
||
|
struct priv_shared_info *pshare = priv->pshare;
|
||
|
HAL_INTF_DATA_TYPE *pHalData = GET_HAL_INTF_DATA(priv);
|
||
|
s32 err;
|
||
|
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, addr, pHalData->SdioRxFIFOCnt++, &addr);
|
||
|
|
||
|
cnt = _RND4(cnt);
|
||
|
if (cnt > pshare->block_transfer_len)
|
||
|
cnt = _RND(cnt, pshare->block_transfer_len);
|
||
|
|
||
|
// cnt = sdio_align_size(cnt);
|
||
|
|
||
|
err = _sd_read(priv, addr, cnt, mem);
|
||
|
//err = sd_read(priv, addr, cnt, mem);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Description:
|
||
|
* Write to TX FIFO
|
||
|
* Align write size block size,
|
||
|
* and make sure data could be written in one command.
|
||
|
*
|
||
|
* Parameters:
|
||
|
* pintfhdl a pointer of intf_hdl
|
||
|
* addr port ID
|
||
|
* cnt size to write
|
||
|
* wmem data pointer to write
|
||
|
*
|
||
|
* Return:
|
||
|
* = 0 Success
|
||
|
* != 0 Fail
|
||
|
*/
|
||
|
u32 sdio_write_port(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *mem)
|
||
|
{
|
||
|
s32 err;
|
||
|
struct priv_shared_info *pshare = priv->pshare;
|
||
|
struct xmit_buf *pxmitbuf = (struct xmit_buf *)mem;
|
||
|
const int q_num = pxmitbuf->q_num;
|
||
|
#ifdef SDIO_STATISTICS_TIME
|
||
|
struct timeval start, now;
|
||
|
#endif
|
||
|
|
||
|
cnt = _RND4(cnt);
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, addr, cnt >> 2, &addr);
|
||
|
|
||
|
if (cnt > pshare->block_transfer_len)
|
||
|
cnt = _RND(cnt, pshare->block_transfer_len);
|
||
|
// cnt = sdio_align_size(cnt);
|
||
|
|
||
|
#ifdef SDIO_STATISTICS_TIME
|
||
|
do_gettimeofday(&start);
|
||
|
#endif
|
||
|
|
||
|
err = sd_write(priv, addr, cnt, pxmitbuf->pkt_data);
|
||
|
pxmitbuf->status = err;
|
||
|
|
||
|
#ifdef SDIO_STATISTICS
|
||
|
if (BE_QUEUE == q_num) {
|
||
|
pshare->writeport_total_count[pxmitbuf->agg_num-1]++;
|
||
|
#ifdef SDIO_STATISTICS_TIME
|
||
|
do_gettimeofday(&now);
|
||
|
pshare->writeport_total_time[pxmitbuf->agg_num-1] += (timeval_to_us(&now) -timeval_to_us(&start));
|
||
|
#endif
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// rtw_sctx_done_err(&xmitbuf->sctx,
|
||
|
// err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
|
||
|
|
||
|
if (err) {
|
||
|
printk("%s, error=%d\n", __func__, err);
|
||
|
}
|
||
|
|
||
|
if ((q_num >= BK_QUEUE) && (q_num <= VO_QUEUE)) {
|
||
|
pshare->low_traffic_xmit_stats[q_num] += pxmitbuf->agg_num;
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Todo: align address to 4 bytes.
|
||
|
*/
|
||
|
s32 _sdio_local_read(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pbuf)
|
||
|
{
|
||
|
s32 err;
|
||
|
u8 *ptmpbuf;
|
||
|
u32 n;
|
||
|
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
|
||
|
if ((FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
// || (_TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
err = _sd_cmd52_read(priv, addr, cnt, pbuf);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
n = _RND4(cnt);
|
||
|
ptmpbuf = (u8*)rtw_malloc(n);
|
||
|
if (NULL == ptmpbuf)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
err = _sd_read(priv, addr, n, ptmpbuf);
|
||
|
if (!err)
|
||
|
memcpy(pbuf, ptmpbuf, cnt);
|
||
|
|
||
|
rtw_mfree(ptmpbuf, n);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Todo: align address to 4 bytes.
|
||
|
*/
|
||
|
s32 sdio_local_read(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pbuf)
|
||
|
{
|
||
|
s32 err;
|
||
|
u8 *ptmpbuf;
|
||
|
u32 n;
|
||
|
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
|
||
|
if ((FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
err = sd_cmd52_read(priv, addr, cnt, pbuf);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
n = _RND4(cnt);
|
||
|
ptmpbuf = (u8*)rtw_malloc(n);
|
||
|
if (NULL == ptmpbuf)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
err = sd_read(priv, addr, n, ptmpbuf);
|
||
|
if (!err)
|
||
|
memcpy(pbuf, ptmpbuf, cnt);
|
||
|
|
||
|
rtw_mfree(ptmpbuf, n);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Todo: align address to 4 bytes.
|
||
|
*/
|
||
|
s32 _sdio_local_write(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pbuf)
|
||
|
{
|
||
|
s32 err;
|
||
|
u8 *ptmpbuf;
|
||
|
|
||
|
if (addr & 0x3)
|
||
|
printk("%s, address must be 4 bytes alignment\n", __FUNCTION__);
|
||
|
|
||
|
if (cnt & 0x3)
|
||
|
printk("%s, size must be the multiple of 4 \n", __FUNCTION__);
|
||
|
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
|
||
|
if ((FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
// || (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
err = _sd_cmd52_write(priv, addr, cnt, pbuf);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
ptmpbuf = (u8*)rtw_malloc(cnt);
|
||
|
if (NULL == ptmpbuf)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
memcpy(ptmpbuf, pbuf, cnt);
|
||
|
|
||
|
err = _sd_write(priv, addr, cnt, ptmpbuf);
|
||
|
|
||
|
rtw_mfree(ptmpbuf, cnt);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Todo: align address to 4 bytes.
|
||
|
*/
|
||
|
s32 sdio_local_write(struct rtl8192cd_priv *priv, u32 addr, u32 cnt, u8 *pbuf)
|
||
|
{
|
||
|
s32 err;
|
||
|
u8 *ptmpbuf;
|
||
|
|
||
|
if (addr & 0x3)
|
||
|
printk("%s, address must be 4 bytes alignment\n", __FUNCTION__);
|
||
|
|
||
|
if (cnt & 0x3)
|
||
|
printk("%s, size must be the multiple of 4 \n", __FUNCTION__);
|
||
|
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
|
||
|
if ((FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
err = sd_cmd52_write(priv, addr, cnt, pbuf);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
ptmpbuf = (u8*)rtw_malloc(cnt);
|
||
|
if (NULL == ptmpbuf)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
memcpy(ptmpbuf, pbuf, cnt);
|
||
|
|
||
|
err = sd_write(priv, addr, cnt, ptmpbuf);
|
||
|
|
||
|
rtw_mfree(ptmpbuf, cnt);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
u8 SdioLocalCmd52Read1Byte(struct rtl8192cd_priv *priv, u32 addr)
|
||
|
{
|
||
|
u8 val = 0;
|
||
|
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
sd_cmd52_read(priv, addr, 1, &val);
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
u16 SdioLocalCmd52Read2Byte(struct rtl8192cd_priv *priv, u32 addr)
|
||
|
{
|
||
|
u16 val = 0;
|
||
|
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
sd_cmd52_read(priv, addr, 2, (u8*)&val);
|
||
|
|
||
|
val = le16_to_cpu(val);
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
u32 SdioLocalCmd52Read4Byte(struct rtl8192cd_priv *priv, u32 addr)
|
||
|
{
|
||
|
u32 val = 0;
|
||
|
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
sd_cmd52_read(priv, addr, 4, (u8*)&val);
|
||
|
|
||
|
val = le32_to_cpu(val);
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
u32 SdioLocalCmd53Read4Byte(struct rtl8192cd_priv *priv, u32 addr)
|
||
|
{
|
||
|
u32 val;
|
||
|
|
||
|
val = 0;
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
if ((FALSE == GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn)
|
||
|
#ifdef CONFIG_LPS_LCLK
|
||
|
|| (TRUE == padapter->pwrctrlpriv.bFwCurrentInPSMode)
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
sd_cmd52_read(priv, addr, 4, (u8*)&val);
|
||
|
val = le32_to_cpu(val);
|
||
|
}
|
||
|
else
|
||
|
val = sd_read32(priv, addr, NULL);
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
void SdioLocalCmd52Write1Byte(struct rtl8192cd_priv *priv, u32 addr, u8 v)
|
||
|
{
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
sd_cmd52_write(priv, addr, 1, &v);
|
||
|
}
|
||
|
|
||
|
void SdioLocalCmd52Write2Byte(struct rtl8192cd_priv *priv, u32 addr, u16 v)
|
||
|
{
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
v = cpu_to_le16(v);
|
||
|
sd_cmd52_write(priv, addr, 2, (u8*)&v);
|
||
|
}
|
||
|
|
||
|
void SdioLocalCmd52Write4Byte(struct rtl8192cd_priv *priv, u32 addr, u32 v)
|
||
|
{
|
||
|
HalSdioGetCmdAddr8723ASdio(priv, SDIO_LOCAL_DEVICE_ID, addr, &addr);
|
||
|
v = cpu_to_le32(v);
|
||
|
sd_cmd52_write(priv, addr, 4, (u8*)&v);
|
||
|
}
|
||
|
|
||
|
static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn,
|
||
|
unsigned addr, u8 in, u8 *out)
|
||
|
{
|
||
|
struct mmc_command cmd = {0};
|
||
|
int err;
|
||
|
|
||
|
BUG_ON(!host);
|
||
|
BUG_ON(fn > 7);
|
||
|
|
||
|
/* sanity check */
|
||
|
if (addr & ~0x1FFFF)
|
||
|
return -EINVAL;
|
||
|
|
||
|
cmd.opcode = SD_IO_RW_DIRECT;
|
||
|
cmd.arg = write ? 0x80000000 : 0x00000000;
|
||
|
cmd.arg |= fn << 28;
|
||
|
cmd.arg |= (write && out) ? 0x08000000 : 0x00000000;
|
||
|
cmd.arg |= addr << 9;
|
||
|
cmd.arg |= in;
|
||
|
cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
|
||
|
|
||
|
err = mmc_wait_for_cmd(host, &cmd, 0);
|
||
|
if (err)
|
||
|
return err;
|
||
|
|
||
|
if (mmc_host_is_spi(host)) {
|
||
|
/* host driver already reported errors */
|
||
|
} else {
|
||
|
if (cmd.resp[0] & R5_ERROR)
|
||
|
return -EIO;
|
||
|
if (cmd.resp[0] & R5_FUNCTION_NUMBER)
|
||
|
return -EINVAL;
|
||
|
if (cmd.resp[0] & R5_OUT_OF_RANGE)
|
||
|
return -ERANGE;
|
||
|
}
|
||
|
|
||
|
if (out) {
|
||
|
if (mmc_host_is_spi(host))
|
||
|
*out = (cmd.resp[0] >> 8) & 0xFF;
|
||
|
else
|
||
|
*out = cmd.resp[0] & 0xFF;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
|
||
|
unsigned addr, u8 in, u8 *out)
|
||
|
{
|
||
|
BUG_ON(!card);
|
||
|
return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out);
|
||
|
}
|
||
|
|
||
|
void dump_sdio_cccr(struct rtl8192cd_priv *priv)
|
||
|
{
|
||
|
int i;
|
||
|
u8 data[0x100];
|
||
|
|
||
|
struct mmc_card *card = priv->pshare->psdio_func->card;
|
||
|
|
||
|
sdio_claim_host(priv->pshare->psdio_func);
|
||
|
for (i = 0; i < 0x100; ++i) {
|
||
|
if (mmc_io_rw_direct(card, 0, 0, i, 0, &data[i]))
|
||
|
break;
|
||
|
}
|
||
|
sdio_release_host(priv->pshare->psdio_func);
|
||
|
|
||
|
mem_dump("SDIO CCCR Registers:", data, i);
|
||
|
}
|
||
|
|
||
|
void dump_sdio_local_reg(struct rtl8192cd_priv *priv)
|
||
|
{
|
||
|
#define REG_SZ 0x100
|
||
|
|
||
|
u8 data[REG_SZ];
|
||
|
u32 val;
|
||
|
|
||
|
int i, j, len;
|
||
|
unsigned char tmpbuf[100];
|
||
|
|
||
|
if (sdio_local_read(priv, 0, REG_SZ, data))
|
||
|
return;
|
||
|
|
||
|
printk(KERN_ERR "SDIO Local Registers:\n");
|
||
|
|
||
|
for (i = 0; i < REG_SZ; i += 0x10) {
|
||
|
len = sprintf((char *)tmpbuf, "%03X\t", i);
|
||
|
for (j = i; j < i+0x10; j += 4) {
|
||
|
val = le32_to_cpup((__le32 *)&data[j]);
|
||
|
len += sprintf((char *)(tmpbuf+len), "%08X ", val);
|
||
|
}
|
||
|
printk(KERN_ERR "%s\n", tmpbuf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void dump_reg(struct rtl8192cd_priv *priv)
|
||
|
{
|
||
|
int i, j, len;
|
||
|
unsigned char tmpbuf[100];
|
||
|
|
||
|
printk(KERN_ERR "MAC Registers:\n");
|
||
|
|
||
|
for (i = 0; i < 0x1000; i += 0x10) {
|
||
|
len = sprintf((char *)tmpbuf, "%03X\t", i);
|
||
|
for (j = i; j < i+0x10; j += 4)
|
||
|
len += sprintf((char *)(tmpbuf+len), "%08X ", RTL_R32(j));
|
||
|
printk(KERN_ERR "%s\n", tmpbuf);
|
||
|
}
|
||
|
}
|
||
|
|