• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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