1 /*
2 * Hardware I/O implementation for XRadio drivers
3 *
4 * Copyright (c) 2013
5 * Xradio Technology Co., Ltd. <www.xradiotech.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12 #include <linux/types.h>
13
14 #include "xradio.h"
15 #include "hwio.h"
16 #include "sbus.h"
17
18
__xradio_read(struct xradio_common * hw_priv,u16 addr,void * buf,size_t buf_len,int buf_id)19 static int __xradio_read(struct xradio_common *hw_priv, u16 addr,
20 void *buf, size_t buf_len, int buf_id)
21 {
22 u16 addr_sdio;
23 u32 sdio_reg_addr_17bit ;
24
25 #if (CHECK_ADDR_LEN)
26 /* Check if buffer is aligned to 4 byte boundary */
27 if (SYS_WARN(((unsigned long)buf & 3) && (buf_len > 4))) {
28 sbus_printk(XRADIO_DBG_ERROR, "%s: buffer is not aligned.\n",
29 __func__);
30 return -EINVAL;
31 }
32 #endif
33
34 /* Convert to SDIO Register Address */
35 addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
36 sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
37 SYS_BUG(!hw_priv->sbus_ops);
38 return hw_priv->sbus_ops->sbus_data_read(hw_priv->sbus_priv,
39 sdio_reg_addr_17bit,
40 buf, buf_len);
41 }
42
__xradio_write(struct xradio_common * hw_priv,u16 addr,const void * buf,size_t buf_len,int buf_id)43 static int __xradio_write(struct xradio_common *hw_priv, u16 addr,
44 const void *buf, size_t buf_len, int buf_id)
45 {
46 u16 addr_sdio;
47 u32 sdio_reg_addr_17bit ;
48
49 #if (CHECK_ADDR_LEN)
50 /* Check if buffer is aligned to 4 byte boundary */
51 if (SYS_WARN(((unsigned long)buf & 3) && (buf_len > 4))) {
52 sbus_printk(XRADIO_DBG_ERROR, "%s: buffer is not aligned.\n",
53 __func__);
54 return -EINVAL;
55 }
56 #endif
57
58 /* Convert to SDIO Register Address */
59 addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
60 sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
61
62 SYS_BUG(!hw_priv->sbus_ops);
63 return hw_priv->sbus_ops->sbus_data_write(hw_priv->sbus_priv,
64 sdio_reg_addr_17bit,
65 buf, buf_len);
66 }
67
__xradio_read_reg32(struct xradio_common * hw_priv,u16 addr,u32 * val)68 static inline int __xradio_read_reg32(struct xradio_common *hw_priv,
69 u16 addr, u32 *val)
70 {
71 int ret = 0;
72
73 *hw_priv->sbus_priv->val32_r = 0;
74 ret = __xradio_read(hw_priv, addr, hw_priv->sbus_priv->val32_r, sizeof(u32), 0);
75 *val = *hw_priv->sbus_priv->val32_r;
76
77 return ret;
78 }
79
__xradio_write_reg32(struct xradio_common * hw_priv,u16 addr,u32 val)80 static inline int __xradio_write_reg32(struct xradio_common *hw_priv,
81 u16 addr, u32 val)
82 {
83 int ret = 0;
84
85 *hw_priv->sbus_priv->val32_w = val;
86 ret = __xradio_write(hw_priv, addr, hw_priv->sbus_priv->val32_w, sizeof(u32), 0);
87 *hw_priv->sbus_priv->val32_w = 0;
88
89 return ret;
90 }
91
xradio_reg_read(struct xradio_common * hw_priv,u16 addr,void * buf,size_t buf_len)92 int xradio_reg_read(struct xradio_common *hw_priv, u16 addr,
93 void *buf, size_t buf_len)
94 {
95 int ret;
96 SYS_BUG(!hw_priv->sbus_ops);
97 hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
98 *hw_priv->sbus_priv->val32_r = 0;
99 ret = __xradio_read(hw_priv, addr, hw_priv->sbus_priv->val32_r, buf_len, 0);
100 *(u32 *)buf = *hw_priv->sbus_priv->val32_r;
101 hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
102 return ret;
103 }
104
xradio_reg_write(struct xradio_common * hw_priv,u16 addr,const void * buf,size_t buf_len)105 int xradio_reg_write(struct xradio_common *hw_priv, u16 addr,
106 const void *buf, size_t buf_len)
107 {
108 int ret;
109 SYS_BUG(!hw_priv->sbus_ops);
110 hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
111 *hw_priv->sbus_priv->val32_w = *(u32 *)buf;
112 ret = __xradio_write(hw_priv, addr, hw_priv->sbus_priv->val32_w, buf_len, 0);
113 *hw_priv->sbus_priv->val32_w = 0;
114 hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
115 return ret;
116 }
117
xradio_reg_bit_operate(struct xradio_common * hw_priv,u16 addr,u32 set,u32 clr)118 int xradio_reg_bit_operate(struct xradio_common *hw_priv, u16 addr, u32 set, u32 clr)
119 {
120 int ret;
121 u32 val32;
122 SYS_BUG(!hw_priv->sbus_ops);
123 hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
124 ret = __xradio_read_reg32(hw_priv, addr, &val32);
125
126 if (ret < 0 && 1 == addr) { //means control reg read failed
127 ret = __xradio_read_reg32(hw_priv, addr, &val32);
128 printk(KERN_ERR"[SDIO-DCE] read control reg agian and val is 0x%x\n", val32);
129 }
130
131 if (ret < 0) {
132 sbus_printk(XRADIO_DBG_ERROR, "%s: Can't read reg.\n", __func__);
133 goto out;
134 }
135 val32 &= ~clr;
136 val32 |= set;
137 ret = __xradio_write_reg32(hw_priv, addr, val32);
138 if (ret < 0) {
139 sbus_printk(XRADIO_DBG_ERROR, "%s: Can't write reg.\n", __func__);
140 }
141 out:
142 hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
143 return ret;
144 }
145
xradio_data_read(struct xradio_common * hw_priv,void * buf,size_t buf_len)146 int xradio_data_read(struct xradio_common *hw_priv, void *buf, size_t buf_len)
147 {
148 int ret, retry = 1;
149 SYS_BUG(!hw_priv->sbus_ops);
150 hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
151 {
152 int buf_id_rx = hw_priv->buf_id_rx;
153 while (retry <= MAX_RETRY) {
154 ret = __xradio_read(hw_priv, HIF_IN_OUT_QUEUE_REG_ID, buf,
155 buf_len, buf_id_rx + 1);
156 if (!ret) {
157 buf_id_rx = (buf_id_rx + 1) & 3;
158 hw_priv->buf_id_rx = buf_id_rx;
159 break;
160 } else {
161 retry++;
162 mdelay(1);
163 sbus_printk(XRADIO_DBG_ERROR, "%s, error :[%d]\n",
164 __func__, ret);
165 }
166 }
167 }
168 hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
169 return ret;
170 }
171
xradio_data_write(struct xradio_common * hw_priv,const void * buf,size_t buf_len)172 int xradio_data_write(struct xradio_common *hw_priv, const void *buf,
173 size_t buf_len)
174 {
175 int ret, retry = 1;
176 SYS_BUG(!hw_priv->sbus_ops);
177 hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
178 {
179 int buf_id_tx = hw_priv->buf_id_tx;
180 while (retry <= MAX_RETRY) {
181 ret = __xradio_write(hw_priv, HIF_IN_OUT_QUEUE_REG_ID, buf,
182 buf_len, buf_id_tx);
183 if (!ret) {
184 buf_id_tx = (buf_id_tx + 1) & 31;
185 hw_priv->buf_id_tx = buf_id_tx;
186 break;
187 } else {
188 retry++;
189 mdelay(1);
190 sbus_printk(XRADIO_DBG_ERROR, "%s, error :[%d]\n",
191 __func__, ret);
192 }
193 }
194 }
195 hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
196 return ret;
197 }
198
xradio_indirect_read(struct xradio_common * hw_priv,u32 addr,void * buf,size_t buf_len,u32 prefetch,u16 port_addr)199 int xradio_indirect_read(struct xradio_common *hw_priv, u32 addr, void *buf,
200 size_t buf_len, u32 prefetch, u16 port_addr)
201 {
202 u32 val32 = 0;
203 int i, ret;
204
205 if ((buf_len / 2) >= 0x1000) {
206 sbus_printk(XRADIO_DBG_ERROR,
207 "%s: Can't read more than 0xfff words.\n",
208 __func__);
209 return -EINVAL;
210 goto out;
211 }
212
213 hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
214 /* Write address */
215 ret = __xradio_write_reg32(hw_priv, HIF_SRAM_BASE_ADDR_REG_ID, addr);
216 if (ret < 0) {
217 sbus_printk(XRADIO_DBG_ERROR,
218 "%s: Can't write address register.\n", __func__);
219 goto out;
220 }
221
222 /* Read CONFIG Register Value - We will read 32 bits */
223 ret = __xradio_read_reg32(hw_priv, HIF_CONFIG_REG_ID, &val32);
224 if (ret < 0) {
225 sbus_printk(XRADIO_DBG_ERROR,
226 "%s: Can't read config register.\n", __func__);
227 goto out;
228 }
229
230 /* Set PREFETCH bit */
231 ret = __xradio_write_reg32(hw_priv, HIF_CONFIG_REG_ID, val32 | prefetch);
232 if (ret < 0) {
233 sbus_printk(XRADIO_DBG_ERROR,
234 "%s: Can't write prefetch bit.\n", __func__);
235 goto out;
236 }
237
238 /* Check for PRE-FETCH bit to be cleared */
239 for (i = 0; i < 20; i++) {
240 ret = __xradio_read_reg32(hw_priv, HIF_CONFIG_REG_ID, &val32);
241 if (ret < 0) {
242 sbus_printk(XRADIO_DBG_ERROR,
243 "%s: Can't check prefetch bit.\n", __func__);
244 goto out;
245 }
246 if (!(val32 & prefetch))
247 break;
248 mdelay(i);
249 }
250
251 if (val32 & prefetch) {
252 sbus_printk(XRADIO_DBG_ERROR,
253 "%s: Prefetch bit is not cleared.\n", __func__);
254 goto out;
255 }
256
257 /* Read data port */
258 if (buf_len == sizeof(u32)) {
259 *hw_priv->sbus_priv->val32_r = 0;
260 ret = __xradio_read(hw_priv, port_addr, hw_priv->sbus_priv->val32_r, buf_len, 0);
261 *(u32 *)buf = *hw_priv->sbus_priv->val32_r;
262 } else {
263 ret = __xradio_read(hw_priv, port_addr, buf, buf_len, 0);
264 }
265 if (ret < 0) {
266 sbus_printk(XRADIO_DBG_ERROR,
267 "%s: Can't read data port.\n", __func__);
268 goto out;
269 }
270
271 out:
272 hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
273 return ret;
274 }
275
xradio_apb_write(struct xradio_common * hw_priv,u32 addr,const void * buf,size_t buf_len)276 int xradio_apb_write(struct xradio_common *hw_priv, u32 addr, const void *buf,
277 size_t buf_len)
278 {
279 int ret;
280
281 if ((buf_len / 2) >= 0x1000) {
282 sbus_printk(XRADIO_DBG_ERROR,
283 "%s: Can't wrire more than 0xfff words.\n", __func__);
284 return -EINVAL;
285 }
286
287 hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
288
289 /* Write address */
290 ret = __xradio_write_reg32(hw_priv, HIF_SRAM_BASE_ADDR_REG_ID, addr);
291 if (ret < 0) {
292 sbus_printk(XRADIO_DBG_ERROR,
293 "%s: Can't write address register.\n", __func__);
294 goto out;
295 }
296
297 /* Write data port */
298 if (buf_len == sizeof(u32)) {
299 memcpy(hw_priv->sbus_priv->val32_w, buf, sizeof(u32));
300 ret = __xradio_write(hw_priv, HIF_SRAM_DPORT_REG_ID,
301 hw_priv->sbus_priv->val32_w, buf_len, 0);
302 memset(hw_priv->sbus_priv->val32_w, 0, sizeof(u32));
303 } else {
304 ret = __xradio_write(hw_priv, HIF_SRAM_DPORT_REG_ID, buf, buf_len, 0);
305 }
306
307 if (ret < 0) {
308 sbus_printk(XRADIO_DBG_ERROR, "%s: Can't write data port.\n",
309 __func__);
310 goto out;
311 }
312
313 out:
314 hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
315 return ret;
316 }
317
xradio_ahb_write(struct xradio_common * hw_priv,u32 addr,const void * buf,size_t buf_len)318 int xradio_ahb_write(struct xradio_common *hw_priv, u32 addr, const void *buf,
319 size_t buf_len)
320 {
321 int ret;
322
323 if ((buf_len / 2) >= 0x1000) {
324 sbus_printk(XRADIO_DBG_ERROR,
325 "%s: Can't wrire more than 0xfff words.\n",
326 __func__);
327 return -EINVAL;
328 }
329
330 hw_priv->sbus_ops->lock(hw_priv->sbus_priv);
331
332 /* Write address */
333 ret = __xradio_write_reg32(hw_priv, HIF_SRAM_BASE_ADDR_REG_ID, addr);
334 if (ret < 0) {
335 sbus_printk(XRADIO_DBG_ERROR,
336 "%s: Can't write address register.\n", __func__);
337 goto out;
338 }
339
340 /* Write data port */
341 if (buf_len == sizeof(u32)) {
342 memcpy(hw_priv->sbus_priv->val32_w, buf, sizeof(u32));
343 ret = __xradio_write(hw_priv, HIF_AHB_DPORT_REG_ID,
344 hw_priv->sbus_priv->val32_w, buf_len, 0);
345 memset(hw_priv->sbus_priv->val32_w, 0, sizeof(u32));
346 } else {
347 ret = __xradio_write(hw_priv, HIF_AHB_DPORT_REG_ID, buf, buf_len, 0);
348 }
349
350 if (ret < 0) {
351 sbus_printk(XRADIO_DBG_ERROR,
352 "%s: Can't write data port.\n", __func__);
353 goto out;
354 }
355
356 out:
357 hw_priv->sbus_ops->unlock(hw_priv->sbus_priv);
358 return ret;
359 }
360