Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 306673
b: refs/heads/master
c: e9b8d91
h: refs/heads/master
i:
  306671: 925049a
v: v3
  • Loading branch information
Franky Lin authored and John W. Linville committed May 15, 2012
1 parent feb5a19 commit 8e64c2a
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7d9cfc28269b10b19678d7cb57892afec85af8fb
refs/heads/master: e9b8d91d5555e64d30c3b972795579e6d8619908
113 changes: 113 additions & 0 deletions trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,119 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
return err;
}

static int
brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
void *data, bool write)
{
u8 func_num, reg_size;
u32 bar;
s32 retry = 0;
int ret;

/*
* figure out how to read the register based on address range
* 0x00 ~ 0xFF: function 0 CCCR
* 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
* The rest: function 1 silicon backplane core registers
*/
if ((addr & ~REG_F0_CCCR_MASK) == 0) {
func_num = SDIO_FUNC_0;
reg_size = 1;
} else if ((addr & ~REG_F1_MISC_MASK) == 0) {
func_num = SDIO_FUNC_1;
reg_size = 1;
} else {
func_num = SDIO_FUNC_1;
reg_size = 4;

/* Set the window for SB core register */
bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
if (bar != sdiodev->sbwad) {
ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
if (ret != 0) {
memset(data, 0xFF, reg_size);
return ret;
}
sdiodev->sbwad = bar;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
}

do {
if (!write)
memset(data, 0, reg_size);
if (retry) /* wait for 1 ms till bus get settled down */
usleep_range(1000, 2000);
if (reg_size == 1)
ret = brcmf_sdioh_request_byte(sdiodev, write,
func_num, addr, data);
else
ret = brcmf_sdioh_request_word(sdiodev, write,
func_num, addr, data, 4);
} while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);

sdiodev->regfail = (ret != 0);
if (sdiodev->regfail)
brcmf_dbg(ERROR, "failed with %d\n", ret);

return ret;
}

u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
{
u8 data;
int retval;

brcmf_dbg(INFO, "addr:0x%08x\n", addr);
retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
brcmf_dbg(INFO, "data:0x%02x\n", data);

if (ret)
*ret = retval;

return data;
}

u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
{
u32 data;
int retval;

brcmf_dbg(INFO, "addr:0x%08x\n", addr);
retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
brcmf_dbg(INFO, "data:0x%08x\n", data);

if (ret)
*ret = retval;

return data;
}

void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
u8 data, int *ret)
{
int retval;

brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);

if (ret)
*ret = retval;
}

void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
u32 data, int *ret)
{
int retval;

brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);

if (ret)
*ret = retval;
}

u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr)
{
int status;
Expand Down
12 changes: 12 additions & 0 deletions trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
/* Maximum number of I/O funcs */
#define SDIOD_MAX_IOFUNCS 7

/* mask of register map */
#define REG_F0_CCCR_MASK 0xFF
#define REG_F1_MISC_MASK 0x1FFFF

/* as of sdiod rev 0, supports 3 functions */
#define SBSDIO_NUM_FUNCTION 3

Expand Down Expand Up @@ -186,6 +190,14 @@ brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr);
extern u32
brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data);

/* sdio device register access interface */
extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
u8 data, int *ret);
extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
u32 data, int *ret);

/* Indicate if last reg read/write failed */
extern bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev);

Expand Down

0 comments on commit 8e64c2a

Please sign in to comment.