diff options
| author | David S. Miller <davem@davemloft.net> | 2010-02-26 02:26:21 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-02-26 02:26:21 -0500 |
| commit | 19bc291c99f018bd4f2c38bbf69144086dca903f (patch) | |
| tree | 9d3cf9bc0c5a78e363dc0547da8bcd1e7c394265 /drivers/net/wireless/wl12xx/wl1271_spi.c | |
| parent | 04488734806948624dabc4514f96f14cd75b9a50 (diff) | |
| parent | 4a6967b88af02eebeedfbb91bc09160750225bb5 (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/rt2x00/rt2800pci.c
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_spi.c')
| -rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_spi.c | 157 |
1 files changed, 0 insertions, 157 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index ee9564aa6ecc..67a82934f36e 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c | |||
| @@ -30,28 +30,6 @@ | |||
| 30 | #include "wl12xx_80211.h" | 30 | #include "wl12xx_80211.h" |
| 31 | #include "wl1271_spi.h" | 31 | #include "wl1271_spi.h" |
| 32 | 32 | ||
| 33 | static int wl1271_translate_addr(struct wl1271 *wl, int addr) | ||
| 34 | { | ||
| 35 | /* | ||
| 36 | * To translate, first check to which window of addresses the | ||
| 37 | * particular address belongs. Then subtract the starting address | ||
| 38 | * of that window from the address. Then, add offset of the | ||
| 39 | * translated region. | ||
| 40 | * | ||
| 41 | * The translated regions occur next to each other in physical device | ||
| 42 | * memory, so just add the sizes of the preceeding address regions to | ||
| 43 | * get the offset to the new region. | ||
| 44 | * | ||
| 45 | * Currently, only the two first regions are addressed, and the | ||
| 46 | * assumption is that all addresses will fall into either of those | ||
| 47 | * two. | ||
| 48 | */ | ||
| 49 | if ((addr >= wl->part.reg.start) && | ||
| 50 | (addr < wl->part.reg.start + wl->part.reg.size)) | ||
| 51 | return addr - wl->part.reg.start + wl->part.mem.size; | ||
| 52 | else | ||
| 53 | return addr - wl->part.mem.start; | ||
| 54 | } | ||
| 55 | 33 | ||
| 56 | void wl1271_spi_reset(struct wl1271 *wl) | 34 | void wl1271_spi_reset(struct wl1271 *wl) |
| 57 | { | 35 | { |
| @@ -133,67 +111,6 @@ void wl1271_spi_init(struct wl1271 *wl) | |||
| 133 | wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); | 111 | wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); |
| 134 | } | 112 | } |
| 135 | 113 | ||
| 136 | /* Set the SPI partitions to access the chip addresses | ||
| 137 | * | ||
| 138 | * To simplify driver code, a fixed (virtual) memory map is defined for | ||
| 139 | * register and memory addresses. Because in the chipset, in different stages | ||
| 140 | * of operation, those addresses will move around, an address translation | ||
| 141 | * mechanism is required. | ||
| 142 | * | ||
| 143 | * There are four partitions (three memory and one register partition), | ||
| 144 | * which are mapped to two different areas of the hardware memory. | ||
| 145 | * | ||
| 146 | * Virtual address | ||
| 147 | * space | ||
| 148 | * | ||
| 149 | * | | | ||
| 150 | * ...+----+--> mem.start | ||
| 151 | * Physical address ... | | | ||
| 152 | * space ... | | [PART_0] | ||
| 153 | * ... | | | ||
| 154 | * 00000000 <--+----+... ...+----+--> mem.start + mem.size | ||
| 155 | * | | ... | | | ||
| 156 | * |MEM | ... | | | ||
| 157 | * | | ... | | | ||
| 158 | * mem.size <--+----+... | | {unused area) | ||
| 159 | * | | ... | | | ||
| 160 | * |REG | ... | | | ||
| 161 | * mem.size | | ... | | | ||
| 162 | * + <--+----+... ...+----+--> reg.start | ||
| 163 | * reg.size | | ... | | | ||
| 164 | * |MEM2| ... | | [PART_1] | ||
| 165 | * | | ... | | | ||
| 166 | * ...+----+--> reg.start + reg.size | ||
| 167 | * | | | ||
| 168 | * | ||
| 169 | */ | ||
| 170 | int wl1271_set_partition(struct wl1271 *wl, | ||
| 171 | struct wl1271_partition_set *p) | ||
| 172 | { | ||
| 173 | /* copy partition info */ | ||
| 174 | memcpy(&wl->part, p, sizeof(*p)); | ||
| 175 | |||
| 176 | wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", | ||
| 177 | p->mem.start, p->mem.size); | ||
| 178 | wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", | ||
| 179 | p->reg.start, p->reg.size); | ||
| 180 | wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X", | ||
| 181 | p->mem2.start, p->mem2.size); | ||
| 182 | wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X", | ||
| 183 | p->mem3.start, p->mem3.size); | ||
| 184 | |||
| 185 | /* write partition info to the chipset */ | ||
| 186 | wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); | ||
| 187 | wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); | ||
| 188 | wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); | ||
| 189 | wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); | ||
| 190 | wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); | ||
| 191 | wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); | ||
| 192 | wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); | ||
| 193 | |||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | #define WL1271_BUSY_WORD_TIMEOUT 1000 | 114 | #define WL1271_BUSY_WORD_TIMEOUT 1000 |
| 198 | 115 | ||
| 199 | /* FIXME: Check busy words, removed due to SPI bug */ | 116 | /* FIXME: Check busy words, removed due to SPI bug */ |
| @@ -338,77 +255,3 @@ void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
| 338 | wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); | 255 | wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); |
| 339 | wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); | 256 | wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); |
| 340 | } | 257 | } |
| 341 | |||
| 342 | void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len, | ||
| 343 | bool fixed) | ||
| 344 | { | ||
| 345 | int physical; | ||
| 346 | |||
| 347 | physical = wl1271_translate_addr(wl, addr); | ||
| 348 | |||
| 349 | wl1271_spi_raw_read(wl, physical, buf, len, fixed); | ||
| 350 | } | ||
| 351 | |||
| 352 | void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len, | ||
| 353 | bool fixed) | ||
| 354 | { | ||
| 355 | int physical; | ||
| 356 | |||
| 357 | physical = wl1271_translate_addr(wl, addr); | ||
| 358 | |||
| 359 | wl1271_spi_raw_write(wl, physical, buf, len, fixed); | ||
| 360 | } | ||
| 361 | |||
| 362 | u32 wl1271_spi_read32(struct wl1271 *wl, int addr) | ||
| 363 | { | ||
| 364 | return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); | ||
| 365 | } | ||
| 366 | |||
| 367 | void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val) | ||
| 368 | { | ||
| 369 | wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); | ||
| 370 | } | ||
| 371 | |||
| 372 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) | ||
| 373 | { | ||
| 374 | /* write address >> 1 + 0x30000 to OCP_POR_CTR */ | ||
| 375 | addr = (addr >> 1) + 0x30000; | ||
| 376 | wl1271_spi_write32(wl, OCP_POR_CTR, addr); | ||
| 377 | |||
| 378 | /* write value to OCP_POR_WDATA */ | ||
| 379 | wl1271_spi_write32(wl, OCP_DATA_WRITE, val); | ||
| 380 | |||
| 381 | /* write 1 to OCP_CMD */ | ||
| 382 | wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_WRITE); | ||
| 383 | } | ||
| 384 | |||
| 385 | u16 wl1271_top_reg_read(struct wl1271 *wl, int addr) | ||
| 386 | { | ||
| 387 | u32 val; | ||
| 388 | int timeout = OCP_CMD_LOOP; | ||
| 389 | |||
| 390 | /* write address >> 1 + 0x30000 to OCP_POR_CTR */ | ||
| 391 | addr = (addr >> 1) + 0x30000; | ||
| 392 | wl1271_spi_write32(wl, OCP_POR_CTR, addr); | ||
| 393 | |||
| 394 | /* write 2 to OCP_CMD */ | ||
| 395 | wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_READ); | ||
| 396 | |||
| 397 | /* poll for data ready */ | ||
| 398 | do { | ||
| 399 | val = wl1271_spi_read32(wl, OCP_DATA_READ); | ||
| 400 | } while (!(val & OCP_READY_MASK) && --timeout); | ||
| 401 | |||
| 402 | if (!timeout) { | ||
| 403 | wl1271_warning("Top register access timed out."); | ||
| 404 | return 0xffff; | ||
| 405 | } | ||
| 406 | |||
| 407 | /* check data status and return if OK */ | ||
| 408 | if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK) | ||
| 409 | return val & 0xffff; | ||
| 410 | else { | ||
| 411 | wl1271_warning("Top register access returned error."); | ||
| 412 | return 0xffff; | ||
| 413 | } | ||
| 414 | } | ||
