Merge tag 'imx-soc-3.13' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/soc
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / cw1200 / hwio.c
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 }