Merge branch 'drm-ttm-unmappable' into drm-core-next
[pandora-kernel.git] / drivers / net / wireless / wl12xx / wl1271_spi.c
1 /*
2  * This file is part of wl1271
3  *
4  * Copyright (C) 2008-2009 Nokia Corporation
5  *
6  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 #include <linux/module.h>
25 #include <linux/platform_device.h>
26 #include <linux/crc7.h>
27 #include <linux/spi/spi.h>
28 #include <linux/slab.h>
29
30 #include "wl1271.h"
31 #include "wl12xx_80211.h"
32 #include "wl1271_spi.h"
33
34
35 void wl1271_spi_reset(struct wl1271 *wl)
36 {
37         u8 *cmd;
38         struct spi_transfer t;
39         struct spi_message m;
40
41         cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
42         if (!cmd) {
43                 wl1271_error("could not allocate cmd for spi reset");
44                 return;
45         }
46
47         memset(&t, 0, sizeof(t));
48         spi_message_init(&m);
49
50         memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
51
52         t.tx_buf = cmd;
53         t.len = WSPI_INIT_CMD_LEN;
54         spi_message_add_tail(&t, &m);
55
56         spi_sync(wl->spi, &m);
57
58         wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
59 }
60
61 void wl1271_spi_init(struct wl1271 *wl)
62 {
63         u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
64         struct spi_transfer t;
65         struct spi_message m;
66
67         cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
68         if (!cmd) {
69                 wl1271_error("could not allocate cmd for spi init");
70                 return;
71         }
72
73         memset(crc, 0, sizeof(crc));
74         memset(&t, 0, sizeof(t));
75         spi_message_init(&m);
76
77         /*
78          * Set WSPI_INIT_COMMAND
79          * the data is being send from the MSB to LSB
80          */
81         cmd[2] = 0xff;
82         cmd[3] = 0xff;
83         cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
84         cmd[0] = 0;
85         cmd[7] = 0;
86         cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
87         cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
88
89         if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
90                 cmd[5] |=  WSPI_INIT_CMD_DIS_FIXEDBUSY;
91         else
92                 cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
93
94         cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
95                 | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
96
97         crc[0] = cmd[1];
98         crc[1] = cmd[0];
99         crc[2] = cmd[7];
100         crc[3] = cmd[6];
101         crc[4] = cmd[5];
102
103         cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
104         cmd[4] |= WSPI_INIT_CMD_END;
105
106         t.tx_buf = cmd;
107         t.len = WSPI_INIT_CMD_LEN;
108         spi_message_add_tail(&t, &m);
109
110         spi_sync(wl->spi, &m);
111
112         wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
113 }
114
115 #define WL1271_BUSY_WORD_TIMEOUT 1000
116
117 /* FIXME: Check busy words, removed due to SPI bug */
118 #if 0
119 static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
120 {
121         struct spi_transfer t[1];
122         struct spi_message m;
123         u32 *busy_buf;
124         int num_busy_bytes = 0;
125
126         wl1271_info("spi read BUSY!");
127
128         /*
129          * Look for the non-busy word in the read buffer, and if found,
130          * read in the remaining data into the buffer.
131          */
132         busy_buf = (u32 *)buf;
133         for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
134                 num_busy_bytes += sizeof(u32);
135                 if (*busy_buf & 0x1) {
136                         spi_message_init(&m);
137                         memset(t, 0, sizeof(t));
138                         memmove(buf, busy_buf, len - num_busy_bytes);
139                         t[0].rx_buf = buf + (len - num_busy_bytes);
140                         t[0].len = num_busy_bytes;
141                         spi_message_add_tail(&t[0], &m);
142                         spi_sync(wl->spi, &m);
143                         return;
144                 }
145         }
146
147         /*
148          * Read further busy words from SPI until a non-busy word is
149          * encountered, then read the data itself into the buffer.
150          */
151         wl1271_info("spi read BUSY-polling needed!");
152
153         num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
154         busy_buf = wl->buffer_busyword;
155         while (num_busy_bytes) {
156                 num_busy_bytes--;
157                 spi_message_init(&m);
158                 memset(t, 0, sizeof(t));
159                 t[0].rx_buf = busy_buf;
160                 t[0].len = sizeof(u32);
161                 spi_message_add_tail(&t[0], &m);
162                 spi_sync(wl->spi, &m);
163
164                 if (*busy_buf & 0x1) {
165                         spi_message_init(&m);
166                         memset(t, 0, sizeof(t));
167                         t[0].rx_buf = buf;
168                         t[0].len = len;
169                         spi_message_add_tail(&t[0], &m);
170                         spi_sync(wl->spi, &m);
171                         return;
172                 }
173         }
174
175         /* The SPI bus is unresponsive, the read failed. */
176         memset(buf, 0, len);
177         wl1271_error("SPI read busy-word timeout!\n");
178 }
179 #endif
180
181 void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
182                          size_t len, bool fixed)
183 {
184         struct spi_transfer t[3];
185         struct spi_message m;
186         u32 *busy_buf;
187         u32 *cmd;
188
189         cmd = &wl->buffer_cmd;
190         busy_buf = wl->buffer_busyword;
191
192         *cmd = 0;
193         *cmd |= WSPI_CMD_READ;
194         *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
195         *cmd |= addr & WSPI_CMD_BYTE_ADDR;
196
197         if (fixed)
198                 *cmd |= WSPI_CMD_FIXED;
199
200         spi_message_init(&m);
201         memset(t, 0, sizeof(t));
202
203         t[0].tx_buf = cmd;
204         t[0].len = 4;
205         spi_message_add_tail(&t[0], &m);
206
207         /* Busy and non busy words read */
208         t[1].rx_buf = busy_buf;
209         t[1].len = WL1271_BUSY_WORD_LEN;
210         spi_message_add_tail(&t[1], &m);
211
212         t[2].rx_buf = buf;
213         t[2].len = len;
214         spi_message_add_tail(&t[2], &m);
215
216         spi_sync(wl->spi, &m);
217
218         /* FIXME: Check busy words, removed due to SPI bug */
219         /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1))
220            wl1271_spi_read_busy(wl, buf, len); */
221
222         wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
223         wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
224 }
225
226 void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
227                           size_t len, bool fixed)
228 {
229         struct spi_transfer t[2];
230         struct spi_message m;
231         u32 *cmd;
232
233         cmd = &wl->buffer_cmd;
234
235         *cmd = 0;
236         *cmd |= WSPI_CMD_WRITE;
237         *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
238         *cmd |= addr & WSPI_CMD_BYTE_ADDR;
239
240         if (fixed)
241                 *cmd |= WSPI_CMD_FIXED;
242
243         spi_message_init(&m);
244         memset(t, 0, sizeof(t));
245
246         t[0].tx_buf = cmd;
247         t[0].len = sizeof(*cmd);
248         spi_message_add_tail(&t[0], &m);
249
250         t[1].tx_buf = buf;
251         t[1].len = len;
252         spi_message_add_tail(&t[1], &m);
253
254         spi_sync(wl->spi, &m);
255
256         wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
257         wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
258 }