aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorBob Copeland <me@bobcopeland.com>2009-08-07 06:33:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:13:37 -0400
commit0d77e141331b25adf190ce30d69fe5744a69c5bd (patch)
tree1e62aa4ab8d08c0653443e2bf086ea55f04a8441 /drivers/net/wireless/wl12xx
parent08d9f57251841e4870cfd286e867ffcbef81d9a4 (diff)
wl1251: make wl1251_set_partition bus agnostic
The same partition setting code can be used for both SPI and SDIO modes, if we remove the spi-specific commands and use the more generic buffer write routines. Do that and move it to io.c since it deals with register/memory address offsets. Signed-off-by: Bob Copeland <me@bobcopeland.com> Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_io.c95
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_io.h15
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.c124
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.h15
4 files changed, 110 insertions, 139 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c
index bc957858b9f..db2cfbfb1e4 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.c
+++ b/drivers/net/wireless/wl12xx/wl1251_io.c
@@ -84,3 +84,98 @@ void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
84{ 84{
85 wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val); 85 wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
86} 86}
87
88/* Set the partitions to access the chip addresses.
89 *
90 * There are two VIRTUAL partitions (the memory partition and the
91 * registers partition), which are mapped to two different areas of the
92 * PHYSICAL (hardware) memory. This function also makes other checks to
93 * ensure that the partitions are not overlapping. In the diagram below, the
94 * memory partition comes before the register partition, but the opposite is
95 * also supported.
96 *
97 * PHYSICAL address
98 * space
99 *
100 * | |
101 * ...+----+--> mem_start
102 * VIRTUAL address ... | |
103 * space ... | | [PART_0]
104 * ... | |
105 * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
106 * | | ... | |
107 * |MEM | ... | |
108 * | | ... | |
109 * part_size <--+----+... | | {unused area)
110 * | | ... | |
111 * |REG | ... | |
112 * part_size | | ... | |
113 * + <--+----+... ...+----+--> reg_start
114 * reg_size ... | |
115 * ... | | [PART_1]
116 * ... | |
117 * ...+----+--> reg_start + reg_size
118 * | |
119 *
120 */
121void wl1251_set_partition(struct wl1251 *wl,
122 u32 mem_start, u32 mem_size,
123 u32 reg_start, u32 reg_size)
124{
125 struct wl1251_partition partition[2];
126
127 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
128 mem_start, mem_size);
129 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
130 reg_start, reg_size);
131
132 /* Make sure that the two partitions together don't exceed the
133 * address range */
134 if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
135 wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
136 " address range. Truncating partition[0].");
137 mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
138 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
139 mem_start, mem_size);
140 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
141 reg_start, reg_size);
142 }
143
144 if ((mem_start < reg_start) &&
145 ((mem_start + mem_size) > reg_start)) {
146 /* Guarantee that the memory partition doesn't overlap the
147 * registers partition */
148 wl1251_debug(DEBUG_SPI, "End of partition[0] is "
149 "overlapping partition[1]. Adjusted.");
150 mem_size = reg_start - mem_start;
151 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
152 mem_start, mem_size);
153 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
154 reg_start, reg_size);
155 } else if ((reg_start < mem_start) &&
156 ((reg_start + reg_size) > mem_start)) {
157 /* Guarantee that the register partition doesn't overlap the
158 * memory partition */
159 wl1251_debug(DEBUG_SPI, "End of partition[1] is"
160 " overlapping partition[0]. Adjusted.");
161 reg_size = mem_start - reg_start;
162 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
163 mem_start, mem_size);
164 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
165 reg_start, reg_size);
166 }
167
168 partition[0].start = mem_start;
169 partition[0].size = mem_size;
170 partition[1].start = reg_start;
171 partition[1].size = reg_size;
172
173 wl->physical_mem_addr = mem_start;
174 wl->physical_reg_addr = reg_start;
175
176 wl->virtual_mem_addr = 0;
177 wl->virtual_reg_addr = mem_size;
178
179 wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition,
180 sizeof(partition));
181}
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
index 1fa2ab18a9e..b89d2ac62ef 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ b/drivers/net/wireless/wl12xx/wl1251_io.h
@@ -23,6 +23,17 @@
23 23
24#include "wl1251.h" 24#include "wl1251.h"
25 25
26#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
27
28#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0
29#define HW_ACCESS_PART0_START_ADDR 0x1FFC4
30#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8
31#define HW_ACCESS_PART1_START_ADDR 0x1FFCC
32
33#define HW_ACCESS_REGISTER_SIZE 4
34
35#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
36
26static inline u32 wl1251_read32(struct wl1251 *wl, int addr) 37static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
27{ 38{
28 u32 response; 39 u32 response;
@@ -46,4 +57,8 @@ void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
46u32 wl1251_reg_read32(struct wl1251 *wl, int addr); 57u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
47void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val); 58void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
48 59
60void wl1251_set_partition(struct wl1251 *wl,
61 u32 part_start, u32 part_size,
62 u32 reg_start, u32 reg_size);
63
49#endif 64#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 61a0852b4ee..ceb237b4e57 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -115,130 +115,6 @@ static void wl1251_spi_reset_wake(struct wl1251 *wl)
115 wl1251_spi_init(wl); 115 wl1251_spi_init(wl);
116} 116}
117 117
118
119/* Set the SPI partitions to access the chip addresses
120 *
121 * There are two VIRTUAL (SPI) partitions (the memory partition and the
122 * registers partition), which are mapped to two different areas of the
123 * PHYSICAL (hardware) memory. This function also makes other checks to
124 * ensure that the partitions are not overlapping. In the diagram below, the
125 * memory partition comes before the register partition, but the opposite is
126 * also supported.
127 *
128 * PHYSICAL address
129 * space
130 *
131 * | |
132 * ...+----+--> mem_start
133 * VIRTUAL address ... | |
134 * space ... | | [PART_0]
135 * ... | |
136 * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
137 * | | ... | |
138 * |MEM | ... | |
139 * | | ... | |
140 * part_size <--+----+... | | {unused area)
141 * | | ... | |
142 * |REG | ... | |
143 * part_size | | ... | |
144 * + <--+----+... ...+----+--> reg_start
145 * reg_size ... | |
146 * ... | | [PART_1]
147 * ... | |
148 * ...+----+--> reg_start + reg_size
149 * | |
150 *
151 */
152int wl1251_set_partition(struct wl1251 *wl,
153 u32 mem_start, u32 mem_size,
154 u32 reg_start, u32 reg_size)
155{
156 struct wl1251_partition *partition;
157 struct spi_transfer t;
158 struct spi_message m;
159 size_t len, cmd_len;
160 u32 *cmd;
161 int addr;
162
163 cmd_len = sizeof(u32) + 2 * sizeof(struct wl1251_partition);
164 cmd = kzalloc(cmd_len, GFP_KERNEL);
165 if (!cmd)
166 return -ENOMEM;
167
168 spi_message_init(&m);
169 memset(&t, 0, sizeof(t));
170
171 partition = (struct wl1251_partition *) (cmd + 1);
172 addr = HW_ACCESS_PART0_SIZE_ADDR;
173 len = 2 * sizeof(struct wl1251_partition);
174
175 *cmd |= WSPI_CMD_WRITE;
176 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
177 *cmd |= addr & WSPI_CMD_BYTE_ADDR;
178
179 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
180 mem_start, mem_size);
181 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
182 reg_start, reg_size);
183
184 /* Make sure that the two partitions together don't exceed the
185 * address range */
186 if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
187 wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
188 " address range. Truncating partition[0].");
189 mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
190 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
191 mem_start, mem_size);
192 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
193 reg_start, reg_size);
194 }
195
196 if ((mem_start < reg_start) &&
197 ((mem_start + mem_size) > reg_start)) {
198 /* Guarantee that the memory partition doesn't overlap the
199 * registers partition */
200 wl1251_debug(DEBUG_SPI, "End of partition[0] is "
201 "overlapping partition[1]. Adjusted.");
202 mem_size = reg_start - mem_start;
203 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
204 mem_start, mem_size);
205 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
206 reg_start, reg_size);
207 } else if ((reg_start < mem_start) &&
208 ((reg_start + reg_size) > mem_start)) {
209 /* Guarantee that the register partition doesn't overlap the
210 * memory partition */
211 wl1251_debug(DEBUG_SPI, "End of partition[1] is"
212 " overlapping partition[0]. Adjusted.");
213 reg_size = mem_start - reg_start;
214 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
215 mem_start, mem_size);
216 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
217 reg_start, reg_size);
218 }
219
220 partition[0].start = mem_start;
221 partition[0].size = mem_size;
222 partition[1].start = reg_start;
223 partition[1].size = reg_size;
224
225 wl->physical_mem_addr = mem_start;
226 wl->physical_reg_addr = reg_start;
227
228 wl->virtual_mem_addr = 0;
229 wl->virtual_reg_addr = mem_size;
230
231 t.tx_buf = cmd;
232 t.len = cmd_len;
233 spi_message_add_tail(&t, &m);
234
235 spi_sync(wl->spi, &m);
236
237 kfree(cmd);
238
239 return 0;
240}
241
242static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, 118static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
243 size_t len) 119 size_t len)
244{ 120{
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
index 7c6da21cb00..cb0c228dbc6 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.h
@@ -29,17 +29,6 @@
29#include "wl1251_acx.h" 29#include "wl1251_acx.h"
30#include "reg.h" 30#include "reg.h"
31 31
32#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
33
34#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0
35#define HW_ACCESS_PART0_START_ADDR 0x1FFC4
36#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8
37#define HW_ACCESS_PART1_START_ADDR 0x1FFCC
38
39#define HW_ACCESS_REGISTER_SIZE 4
40
41#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
42
43#define WSPI_CMD_READ 0x40000000 32#define WSPI_CMD_READ 0x40000000
44#define WSPI_CMD_WRITE 0x00000000 33#define WSPI_CMD_WRITE 0x00000000
45#define WSPI_CMD_FIXED 0x20000000 34#define WSPI_CMD_FIXED 0x20000000
@@ -69,8 +58,4 @@
69 ((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32)) 58 ((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32))
70#define HW_ACCESS_WSPI_INIT_CMD_MASK 0 59#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
71 60
72int wl1251_set_partition(struct wl1251 *wl,
73 u32 part_start, u32 part_size,
74 u32 reg_start, u32 reg_size);
75
76#endif /* __WL1251_SPI_H__ */ 61#endif /* __WL1251_SPI_H__ */