xref: /openbmc/linux/drivers/net/wireless/st/cw1200/hwio.c (revision 23c2b932)
1 /*
2  * Low-level device IO routines for ST-Ericsson CW1200 drivers
3  *
4  * Copyright (c) 2010, ST-Ericsson
5  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6  *
7  * Based on:
8  * ST-Ericsson UMAC CW1200 driver, which is
9  * Copyright (c) 2010, ST-Ericsson
10  * Author: Ajitpal Singh <ajitpal.singh@lockless.no>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16 
17 #include <linux/types.h>
18 
19 #include "cw1200.h"
20 #include "hwio.h"
21 #include "hwbus.h"
22 
23  /* Sdio addr is 4*spi_addr */
24 #define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
25 #define SDIO_ADDR17BIT(buf_id, mpf, rfu, reg_id_ofs) \
26 				((((buf_id)    & 0x1F) << 7) \
27 				| (((mpf)        & 1) << 6) \
28 				| (((rfu)        & 1) << 5) \
29 				| (((reg_id_ofs) & 0x1F) << 0))
30 #define MAX_RETRY		3
31 
32 
33 static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
34 			     void *buf, size_t buf_len, int buf_id)
35 {
36 	u16 addr_sdio;
37 	u32 sdio_reg_addr_17bit;
38 
39 	/* Check if buffer is aligned to 4 byte boundary */
40 	if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
41 		pr_err("buffer is not aligned.\n");
42 		return -EINVAL;
43 	}
44 
45 	/* Convert to SDIO Register Address */
46 	addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
47 	sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
48 
49 	return priv->hwbus_ops->hwbus_memcpy_fromio(priv->hwbus_priv,
50 						  sdio_reg_addr_17bit,
51 						  buf, buf_len);
52 }
53 
54 static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
55 				const void *buf, size_t buf_len, int buf_id)
56 {
57 	u16 addr_sdio;
58 	u32 sdio_reg_addr_17bit;
59 
60 	/* Convert to SDIO Register Address */
61 	addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
62 	sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
63 
64 	return priv->hwbus_ops->hwbus_memcpy_toio(priv->hwbus_priv,
65 						sdio_reg_addr_17bit,
66 						buf, buf_len);
67 }
68 
69 static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
70 					u16 addr, u32 *val)
71 {
72 	__le32 tmp;
73 	int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
74 	*val = le32_to_cpu(tmp);
75 	return i;
76 }
77 
78 static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
79 					u16 addr, u32 val)
80 {
81 	__le32 tmp = cpu_to_le32(val);
82 	return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
83 }
84 
85 static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
86 					u16 addr, u16 *val)
87 {
88 	__le16 tmp;
89 	int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
90 	*val = le16_to_cpu(tmp);
91 	return i;
92 }
93 
94 static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
95 					u16 addr, u16 val)
96 {
97 	__le16 tmp = cpu_to_le16(val);
98 	return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
99 }
100 
101 int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
102 			size_t buf_len)
103 {
104 	int ret;
105 	priv->hwbus_ops->lock(priv->hwbus_priv);
106 	ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
107 	priv->hwbus_ops->unlock(priv->hwbus_priv);
108 	return ret;
109 }
110 
111 int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
112 			size_t buf_len)
113 {
114 	int ret;
115 	priv->hwbus_ops->lock(priv->hwbus_priv);
116 	ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
117 	priv->hwbus_ops->unlock(priv->hwbus_priv);
118 	return ret;
119 }
120 
121 int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
122 {
123 	int ret, retry = 1;
124 	int buf_id_rx = priv->buf_id_rx;
125 
126 	priv->hwbus_ops->lock(priv->hwbus_priv);
127 
128 	while (retry <= MAX_RETRY) {
129 		ret = __cw1200_reg_read(priv,
130 					ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
131 					buf_len, buf_id_rx + 1);
132 		if (!ret) {
133 			buf_id_rx = (buf_id_rx + 1) & 3;
134 			priv->buf_id_rx = buf_id_rx;
135 			break;
136 		} else {
137 			retry++;
138 			mdelay(1);
139 			pr_err("error :[%d]\n", ret);
140 		}
141 	}
142 
143 	priv->hwbus_ops->unlock(priv->hwbus_priv);
144 	return ret;
145 }
146 
147 int cw1200_data_write(struct cw1200_common *priv, const void *buf,
148 			size_t buf_len)
149 {
150 	int ret, retry = 1;
151 	int buf_id_tx = priv->buf_id_tx;
152 
153 	priv->hwbus_ops->lock(priv->hwbus_priv);
154 
155 	while (retry <= MAX_RETRY) {
156 		ret = __cw1200_reg_write(priv,
157 					 ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
158 					 buf_len, buf_id_tx);
159 		if (!ret) {
160 			buf_id_tx = (buf_id_tx + 1) & 31;
161 			priv->buf_id_tx = buf_id_tx;
162 			break;
163 		} else {
164 			retry++;
165 			mdelay(1);
166 			pr_err("error :[%d]\n", ret);
167 		}
168 	}
169 
170 	priv->hwbus_ops->unlock(priv->hwbus_priv);
171 	return ret;
172 }
173 
174 int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
175 			 size_t buf_len, u32 prefetch, u16 port_addr)
176 {
177 	u32 val32 = 0;
178 	int i, ret;
179 
180 	if ((buf_len / 2) >= 0x1000) {
181 		pr_err("Can't read more than 0xfff words.\n");
182 		return -EINVAL;
183 	}
184 
185 	priv->hwbus_ops->lock(priv->hwbus_priv);
186 	/* Write address */
187 	ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
188 	if (ret < 0) {
189 		pr_err("Can't write address register.\n");
190 		goto out;
191 	}
192 
193 	/* Read CONFIG Register Value - We will read 32 bits */
194 	ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
195 	if (ret < 0) {
196 		pr_err("Can't read config register.\n");
197 		goto out;
198 	}
199 
200 	/* Set PREFETCH bit */
201 	ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID,
202 					val32 | prefetch);
203 	if (ret < 0) {
204 		pr_err("Can't write prefetch bit.\n");
205 		goto out;
206 	}
207 
208 	/* Check for PRE-FETCH bit to be cleared */
209 	for (i = 0; i < 20; i++) {
210 		ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
211 		if (ret < 0) {
212 			pr_err("Can't check prefetch bit.\n");
213 			goto out;
214 		}
215 		if (!(val32 & prefetch))
216 			break;
217 
218 		mdelay(i);
219 	}
220 
221 	if (val32 & prefetch) {
222 		pr_err("Prefetch bit is not cleared.\n");
223 		goto out;
224 	}
225 
226 	/* Read data port */
227 	ret = __cw1200_reg_read(priv, port_addr, buf, buf_len, 0);
228 	if (ret < 0) {
229 		pr_err("Can't read data port.\n");
230 		goto out;
231 	}
232 
233 out:
234 	priv->hwbus_ops->unlock(priv->hwbus_priv);
235 	return ret;
236 }
237 
238 int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
239 			size_t buf_len)
240 {
241 	int ret;
242 
243 	if ((buf_len / 2) >= 0x1000) {
244 		pr_err("Can't write more than 0xfff words.\n");
245 		return -EINVAL;
246 	}
247 
248 	priv->hwbus_ops->lock(priv->hwbus_priv);
249 
250 	/* Write address */
251 	ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
252 	if (ret < 0) {
253 		pr_err("Can't write address register.\n");
254 		goto out;
255 	}
256 
257 	/* Write data port */
258 	ret = __cw1200_reg_write(priv, ST90TDS_SRAM_DPORT_REG_ID,
259 					buf, buf_len, 0);
260 	if (ret < 0) {
261 		pr_err("Can't write data port.\n");
262 		goto out;
263 	}
264 
265 out:
266 	priv->hwbus_ops->unlock(priv->hwbus_priv);
267 	return ret;
268 }
269 
270 int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
271 {
272 	u32 val32;
273 	u16 val16;
274 	int ret;
275 
276 	if (HIF_8601_SILICON == priv->hw_type) {
277 		ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
278 		if (ret < 0) {
279 			pr_err("Can't read config register.\n");
280 			return ret;
281 		}
282 
283 		if (enable)
284 			val32 |= ST90TDS_CONF_IRQ_RDY_ENABLE;
285 		else
286 			val32 &= ~ST90TDS_CONF_IRQ_RDY_ENABLE;
287 
288 		ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val32);
289 		if (ret < 0) {
290 			pr_err("Can't write config register.\n");
291 			return ret;
292 		}
293 	} else {
294 		ret = __cw1200_reg_read_16(priv, ST90TDS_CONFIG_REG_ID, &val16);
295 		if (ret < 0) {
296 			pr_err("Can't read control register.\n");
297 			return ret;
298 		}
299 
300 		if (enable)
301 			val16 |= ST90TDS_CONT_IRQ_RDY_ENABLE;
302 		else
303 			val16 &= ~ST90TDS_CONT_IRQ_RDY_ENABLE;
304 
305 		ret = __cw1200_reg_write_16(priv, ST90TDS_CONFIG_REG_ID, val16);
306 		if (ret < 0) {
307 			pr_err("Can't write control register.\n");
308 			return ret;
309 		}
310 	}
311 	return 0;
312 }
313