Commit | Line | Data |
---|---|---|
521a5b21 TP |
1 | /* |
2 | * This file is part of wl1271 | |
3 | * | |
4 | * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. | |
5 | * Copyright (C) 2008-2010 Nokia Corporation | |
6 | * | |
7 | * Contact: Luciano Coelho <luciano.coelho@nokia.com> | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License | |
11 | * version 2 as published by the Free Software Foundation. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | |
21 | * 02110-1301 USA | |
22 | * | |
23 | */ | |
24 | ||
00d20100 SL |
25 | #ifndef __IO_H__ |
26 | #define __IO_H__ | |
521a5b21 | 27 | |
a6b7a407 | 28 | #include <linux/irqreturn.h> |
760d969f TP |
29 | |
30 | #define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 | |
31 | ||
32 | #define HW_PARTITION_REGISTERS_ADDR 0x1FFC0 | |
33 | #define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR) | |
34 | #define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4) | |
35 | #define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8) | |
36 | #define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12) | |
37 | #define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16) | |
38 | #define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20) | |
39 | #define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24) | |
40 | ||
41 | #define HW_ACCESS_REGISTER_SIZE 4 | |
42 | ||
43 | #define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 | |
44 | ||
521a5b21 TP |
45 | struct wl1271; |
46 | ||
dd5512eb | 47 | void wlcore_disable_interrupts(struct wl1271 *wl); |
b666bb7f | 48 | void wlcore_disable_interrupts_nosync(struct wl1271 *wl); |
dd5512eb | 49 | void wlcore_enable_interrupts(struct wl1271 *wl); |
c24ec83b | 50 | void wlcore_synchronize_interrupts(struct wl1271 *wl); |
54f7e503 | 51 | |
9b280722 TP |
52 | void wl1271_io_reset(struct wl1271 *wl); |
53 | void wl1271_io_init(struct wl1271 *wl); | |
25a43d78 | 54 | int wlcore_translate_addr(struct wl1271 *wl, int addr); |
521a5b21 | 55 | |
b42f91ba | 56 | /* Raw target IO, address is not translated */ |
f1a26e63 IY |
57 | static inline int __must_check wlcore_raw_write(struct wl1271 *wl, int addr, |
58 | void *buf, size_t len, | |
59 | bool fixed) | |
b42f91ba | 60 | { |
1d23396d AN |
61 | int ret; |
62 | ||
51ae14d0 BB |
63 | if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags) || |
64 | WARN_ON((test_bit(WL1271_FLAG_IN_ELP, &wl->flags) && | |
65 | addr != HW_ACCESS_ELP_CTRL_REG))) | |
1d23396d AN |
66 | return -EIO; |
67 | ||
68 | ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed); | |
4cc53383 | 69 | if (ret && wl->state != WLCORE_STATE_OFF) |
4455556d | 70 | set_bit(WL1271_FLAG_IO_FAILED, &wl->flags); |
1d23396d AN |
71 | |
72 | return ret; | |
b42f91ba | 73 | } |
7b048c52 | 74 | |
f1a26e63 IY |
75 | static inline int __must_check wlcore_raw_read(struct wl1271 *wl, int addr, |
76 | void *buf, size_t len, | |
77 | bool fixed) | |
b42f91ba | 78 | { |
1d23396d AN |
79 | int ret; |
80 | ||
51ae14d0 BB |
81 | if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags) || |
82 | WARN_ON((test_bit(WL1271_FLAG_IN_ELP, &wl->flags) && | |
83 | addr != HW_ACCESS_ELP_CTRL_REG))) | |
1d23396d AN |
84 | return -EIO; |
85 | ||
86 | ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed); | |
4cc53383 | 87 | if (ret && wl->state != WLCORE_STATE_OFF) |
4455556d | 88 | set_bit(WL1271_FLAG_IO_FAILED, &wl->flags); |
1d23396d AN |
89 | |
90 | return ret; | |
b42f91ba | 91 | } |
7b048c52 | 92 | |
f1a26e63 IY |
93 | static inline int __must_check wlcore_raw_read_data(struct wl1271 *wl, int reg, |
94 | void *buf, size_t len, | |
95 | bool fixed) | |
00782136 | 96 | { |
8b7c0fc3 | 97 | return wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed); |
00782136 LC |
98 | } |
99 | ||
f1a26e63 IY |
100 | static inline int __must_check wlcore_raw_write_data(struct wl1271 *wl, int reg, |
101 | void *buf, size_t len, | |
102 | bool fixed) | |
00782136 | 103 | { |
8b7c0fc3 | 104 | return wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed); |
00782136 LC |
105 | } |
106 | ||
f1a26e63 IY |
107 | static inline int __must_check wlcore_raw_read32(struct wl1271 *wl, int addr, |
108 | u32 *val) | |
7b048c52 | 109 | { |
6134323f IY |
110 | int ret; |
111 | ||
2e07d028 IY |
112 | ret = wlcore_raw_read(wl, addr, wl->buffer_32, |
113 | sizeof(*wl->buffer_32), false); | |
6134323f IY |
114 | if (ret < 0) |
115 | return ret; | |
116 | ||
117 | if (val) | |
2e07d028 | 118 | *val = le32_to_cpu(*wl->buffer_32); |
7b048c52 | 119 | |
6134323f | 120 | return 0; |
7b048c52 TP |
121 | } |
122 | ||
f1a26e63 IY |
123 | static inline int __must_check wlcore_raw_write32(struct wl1271 *wl, int addr, |
124 | u32 val) | |
7b048c52 | 125 | { |
2e07d028 IY |
126 | *wl->buffer_32 = cpu_to_le32(val); |
127 | return wlcore_raw_write(wl, addr, wl->buffer_32, | |
128 | sizeof(*wl->buffer_32), false); | |
7b048c52 | 129 | } |
2d5e82b8 | 130 | |
f1a26e63 IY |
131 | static inline int __must_check wlcore_read(struct wl1271 *wl, int addr, |
132 | void *buf, size_t len, bool fixed) | |
b42f91ba TP |
133 | { |
134 | int physical; | |
135 | ||
25a43d78 | 136 | physical = wlcore_translate_addr(wl, addr); |
b42f91ba | 137 | |
045b9b5f | 138 | return wlcore_raw_read(wl, physical, buf, len, fixed); |
b42f91ba TP |
139 | } |
140 | ||
f1a26e63 IY |
141 | static inline int __must_check wlcore_write(struct wl1271 *wl, int addr, |
142 | void *buf, size_t len, bool fixed) | |
b42f91ba TP |
143 | { |
144 | int physical; | |
145 | ||
25a43d78 | 146 | physical = wlcore_translate_addr(wl, addr); |
b42f91ba | 147 | |
eb96f841 | 148 | return wlcore_raw_write(wl, physical, buf, len, fixed); |
b42f91ba TP |
149 | } |
150 | ||
f1a26e63 IY |
151 | static inline int __must_check wlcore_write_data(struct wl1271 *wl, int reg, |
152 | void *buf, size_t len, | |
153 | bool fixed) | |
00782136 | 154 | { |
eb96f841 | 155 | return wlcore_write(wl, wl->rtable[reg], buf, len, fixed); |
00782136 LC |
156 | } |
157 | ||
f1a26e63 IY |
158 | static inline int __must_check wlcore_read_data(struct wl1271 *wl, int reg, |
159 | void *buf, size_t len, | |
160 | bool fixed) | |
00782136 | 161 | { |
045b9b5f | 162 | return wlcore_read(wl, wl->rtable[reg], buf, len, fixed); |
00782136 LC |
163 | } |
164 | ||
f1a26e63 IY |
165 | static inline int __must_check wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr, |
166 | void *buf, size_t len, | |
167 | bool fixed) | |
95dac04f IY |
168 | { |
169 | int physical; | |
170 | int addr; | |
171 | ||
c83cb803 IC |
172 | /* Convert from FW internal address which is chip arch dependent */ |
173 | addr = wl->ops->convert_hwaddr(wl, hwaddr); | |
95dac04f | 174 | |
25a43d78 | 175 | physical = wlcore_translate_addr(wl, addr); |
95dac04f | 176 | |
2b800407 | 177 | return wlcore_raw_read(wl, physical, buf, len, fixed); |
95dac04f IY |
178 | } |
179 | ||
f1a26e63 IY |
180 | static inline int __must_check wlcore_read32(struct wl1271 *wl, int addr, |
181 | u32 *val) | |
b42f91ba | 182 | { |
6134323f | 183 | return wlcore_raw_read32(wl, wlcore_translate_addr(wl, addr), val); |
b42f91ba TP |
184 | } |
185 | ||
f1a26e63 IY |
186 | static inline int __must_check wlcore_write32(struct wl1271 *wl, int addr, |
187 | u32 val) | |
b42f91ba | 188 | { |
b0f0ad39 | 189 | return wlcore_raw_write32(wl, wlcore_translate_addr(wl, addr), val); |
b42f91ba TP |
190 | } |
191 | ||
f1a26e63 IY |
192 | static inline int __must_check wlcore_read_reg(struct wl1271 *wl, int reg, |
193 | u32 *val) | |
00782136 | 194 | { |
6134323f IY |
195 | return wlcore_raw_read32(wl, |
196 | wlcore_translate_addr(wl, wl->rtable[reg]), | |
197 | val); | |
00782136 LC |
198 | } |
199 | ||
f1a26e63 IY |
200 | static inline int __must_check wlcore_write_reg(struct wl1271 *wl, int reg, |
201 | u32 val) | |
00782136 | 202 | { |
b0f0ad39 IY |
203 | return wlcore_raw_write32(wl, |
204 | wlcore_translate_addr(wl, wl->rtable[reg]), | |
205 | val); | |
00782136 LC |
206 | } |
207 | ||
becd551c TP |
208 | static inline void wl1271_power_off(struct wl1271 *wl) |
209 | { | |
645865fc IY |
210 | int ret; |
211 | ||
212 | if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags)) | |
213 | return; | |
214 | ||
215 | ret = wl->if_ops->power(wl->dev, false); | |
216 | if (!ret) | |
217 | clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); | |
becd551c TP |
218 | } |
219 | ||
2cc78ff7 | 220 | static inline int wl1271_power_on(struct wl1271 *wl) |
becd551c | 221 | { |
a390e85c | 222 | int ret = wl->if_ops->power(wl->dev, true); |
2cc78ff7 OBC |
223 | if (ret == 0) |
224 | set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); | |
225 | ||
226 | return ret; | |
becd551c TP |
227 | } |
228 | ||
b0f0ad39 IY |
229 | int wlcore_set_partition(struct wl1271 *wl, |
230 | const struct wlcore_partition_set *p); | |
b42f91ba | 231 | |
4b32a2c9 FB |
232 | bool wl1271_set_block_size(struct wl1271 *wl); |
233 | ||
2d5e82b8 TP |
234 | /* Functions from wl1271_main.c */ |
235 | ||
ae47c45f | 236 | int wl1271_tx_dummy_packet(struct wl1271 *wl); |
2d5e82b8 | 237 | |
521a5b21 | 238 | #endif |