diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2009-10-12 08:08:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-27 16:48:04 -0400 |
commit | e8768eeb5993bf9695adb4afe4118b7fd5e307a3 (patch) | |
tree | 5148ff8752d786125c208008d50e01d33e4791c7 | |
parent | 732a1ad93e820768bb14732b8365493dbd69ecc8 (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.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_boot.h | 15 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_spi.c | 46 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_spi.h | 16 |
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 | ||
420 | static int wl1271_boot_write_irq_polarity(struct wl1271 *wl) | 420 | static 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 | |||
399 | void 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 | |||
412 | u16 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 */ |
76 | void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, | 88 | void 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, | |||
92 | u32 wl1271_reg_read32(struct wl1271 *wl, int addr); | 104 | u32 wl1271_reg_read32(struct wl1271 *wl, int addr); |
93 | void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val); | 105 | void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val); |
94 | 106 | ||
107 | /* Top Register IO */ | ||
108 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); | ||
109 | u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); | ||
110 | |||
95 | /* INIT and RESET words */ | 111 | /* INIT and RESET words */ |
96 | void wl1271_spi_reset(struct wl1271 *wl); | 112 | void wl1271_spi_reset(struct wl1271 *wl); |
97 | void wl1271_spi_init(struct wl1271 *wl); | 113 | void wl1271_spi_init(struct wl1271 *wl); |