aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2009-10-12 08:08:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:48:04 -0400
commite8768eeb5993bf9695adb4afe4118b7fd5e307a3 (patch)
tree5148ff8752d786125c208008d50e01d33e4791c7
parent732a1ad93e820768bb14732b8365493dbd69ecc8 (diff)
wl1271: Add top-register access functions
Add top register access function. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c27
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.h15
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c46
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.h16
4 files changed, 66 insertions, 38 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 2eb7836c9ac1..1a3084cca9b8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -419,34 +419,13 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
419 419
420static int wl1271_boot_write_irq_polarity(struct wl1271 *wl) 420static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
421{ 421{
422 u32 polarity, status, i; 422 u32 polarity;
423 423
424 wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY); 424 polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY);
425 wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_READ);
426
427 /* Wait until the command is complete (ie. bit 18 is set) */
428 for (i = 0; i < OCP_CMD_LOOP; i++) {
429 polarity = wl1271_reg_read32(wl, OCP_DATA_READ);
430 if (polarity & OCP_READY_MASK)
431 break;
432 }
433 if (i == OCP_CMD_LOOP) {
434 wl1271_error("OCP command timeout!");
435 return -EIO;
436 }
437
438 status = polarity & OCP_STATUS_MASK;
439 if (status != OCP_STATUS_OK) {
440 wl1271_error("OCP command failed (%d)", status);
441 return -EIO;
442 }
443 425
444 /* We use HIGH polarity, so unset the LOW bit */ 426 /* We use HIGH polarity, so unset the LOW bit */
445 polarity &= ~POLARITY_LOW; 427 polarity &= ~POLARITY_LOW;
446 428 wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity);
447 wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
448 wl1271_reg_write32(wl, OCP_DATA_WRITE, polarity);
449 wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_WRITE);
450 429
451 return 0; 430 return 0;
452} 431}
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index b0d8fb46a439..4501653fb52a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -50,20 +50,7 @@ struct wl1271_static_data {
50#define WU_COUNTER_PAUSE_VAL 0x3FF 50#define WU_COUNTER_PAUSE_VAL 0x3FF
51#define WELP_ARM_COMMAND_VAL 0x4 51#define WELP_ARM_COMMAND_VAL 0x4
52 52
53#define OCP_CMD_LOOP 32 53#define OCP_REG_POLARITY 0x0064
54
55#define OCP_CMD_WRITE 0x1
56#define OCP_CMD_READ 0x2
57
58#define OCP_READY_MASK BIT(18)
59#define OCP_STATUS_MASK (BIT(16) | BIT(17))
60
61#define OCP_STATUS_NO_RESP 0x00000
62#define OCP_STATUS_OK 0x10000
63#define OCP_STATUS_REQ_FAILED 0x20000
64#define OCP_STATUS_RESP_ERROR 0x30000
65
66#define OCP_REG_POLARITY 0x30032
67 54
68#define CMD_MBOX_ADDRESS 0x407B4 55#define CMD_MBOX_ADDRESS 0x407B4
69 56
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 367f2d3319ac..7a7890b77b89 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -395,3 +395,49 @@ void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val)
395{ 395{
396 wl1271_write32(wl, wl1271_translate_addr(wl, addr), val); 396 wl1271_write32(wl, wl1271_translate_addr(wl, addr), val);
397} 397}
398
399void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
400{
401 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
402 addr = (addr >> 1) + 0x30000;
403 wl1271_reg_write32(wl, OCP_POR_CTR, addr);
404
405 /* write value to OCP_POR_WDATA */
406 wl1271_reg_write32(wl, OCP_DATA_WRITE, val);
407
408 /* write 1 to OCP_CMD */
409 wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_WRITE);
410}
411
412u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
413{
414 u32 val;
415 int timeout = OCP_CMD_LOOP;
416
417 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
418 addr = (addr >> 1) + 0x30000;
419 wl1271_reg_write32(wl, OCP_POR_CTR, addr);
420
421 /* write 2 to OCP_CMD */
422 wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_READ);
423
424 /* poll for data ready */
425 do {
426 val = wl1271_reg_read32(wl, OCP_DATA_READ);
427 timeout--;
428 } while (!(val & OCP_READY_MASK) && timeout);
429
430 if (!timeout) {
431 wl1271_warning("Top register access timed out.");
432 return 0xffff;
433 }
434
435 /* check data status and return if OK */
436 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
437 return val & 0xffff;
438 else {
439 wl1271_warning("Top register access returned error.");
440 return 0xffff;
441 }
442}
443
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h
index c58e02724d02..4f1608e99c29 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.h
@@ -71,6 +71,18 @@
71 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) 71 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
72#define HW_ACCESS_WSPI_INIT_CMD_MASK 0 72#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
73 73
74#define OCP_CMD_LOOP 32
75
76#define OCP_CMD_WRITE 0x1
77#define OCP_CMD_READ 0x2
78
79#define OCP_READY_MASK BIT(18)
80#define OCP_STATUS_MASK (BIT(16) | BIT(17))
81
82#define OCP_STATUS_NO_RESP 0x00000
83#define OCP_STATUS_OK 0x10000
84#define OCP_STATUS_REQ_FAILED 0x20000
85#define OCP_STATUS_RESP_ERROR 0x30000
74 86
75/* Raw target IO, address is not translated */ 87/* Raw target IO, address is not translated */
76void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, 88void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf,
@@ -92,6 +104,10 @@ void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
92u32 wl1271_reg_read32(struct wl1271 *wl, int addr); 104u32 wl1271_reg_read32(struct wl1271 *wl, int addr);
93void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val); 105void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val);
94 106
107/* Top Register IO */
108void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
109u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
110
95/* INIT and RESET words */ 111/* INIT and RESET words */
96void wl1271_spi_reset(struct wl1271 *wl); 112void wl1271_spi_reset(struct wl1271 *wl);
97void wl1271_spi_init(struct wl1271 *wl); 113void wl1271_spi_init(struct wl1271 *wl);