diff options
author | Bob Copeland <me@bobcopeland.com> | 2009-08-07 06:33:18 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-14 09:13:37 -0400 |
commit | 0d77e141331b25adf190ce30d69fe5744a69c5bd (patch) | |
tree | 1e62aa4ab8d08c0653443e2bf086ea55f04a8441 /drivers/net/wireless/wl12xx | |
parent | 08d9f57251841e4870cfd286e867ffcbef81d9a4 (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.c | 95 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_io.h | 15 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_spi.c | 124 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_spi.h | 15 |
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 | */ | ||
121 | void 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 | |||
26 | static inline u32 wl1251_read32(struct wl1251 *wl, int addr) | 37 | static 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); | |||
46 | u32 wl1251_reg_read32(struct wl1251 *wl, int addr); | 57 | u32 wl1251_reg_read32(struct wl1251 *wl, int addr); |
47 | void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val); | 58 | void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val); |
48 | 59 | ||
60 | void 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 | */ | ||
152 | int 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 | |||
242 | static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, | 118 | static 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 | ||
72 | int 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__ */ |