Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spi.c
Go to the documentation of this file.
1 /*
2  * This file is part of wl1251
3  *
4  * Copyright (C) 2008 Nokia Corporation
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * version 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301 USA
19  *
20  */
21 
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/module.h>
25 #include <linux/slab.h>
26 #include <linux/crc7.h>
27 #include <linux/spi/spi.h>
28 #include <linux/wl12xx.h>
29 
30 #include "wl1251.h"
31 #include "reg.h"
32 #include "spi.h"
33 
34 static irqreturn_t wl1251_irq(int irq, void *cookie)
35 {
36  struct wl1251 *wl;
37 
38  wl1251_debug(DEBUG_IRQ, "IRQ");
39 
40  wl = cookie;
41 
42  ieee80211_queue_work(wl->hw, &wl->irq_work);
43 
44  return IRQ_HANDLED;
45 }
46 
47 static struct spi_device *wl_to_spi(struct wl1251 *wl)
48 {
49  return wl->if_priv;
50 }
51 
52 static void wl1251_spi_reset(struct wl1251 *wl)
53 {
54  u8 *cmd;
55  struct spi_transfer t;
56  struct spi_message m;
57 
58  cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
59  if (!cmd) {
60  wl1251_error("could not allocate cmd for spi reset");
61  return;
62  }
63 
64  memset(&t, 0, sizeof(t));
65  spi_message_init(&m);
66 
67  memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
68 
69  t.tx_buf = cmd;
70  t.len = WSPI_INIT_CMD_LEN;
71  spi_message_add_tail(&t, &m);
72 
73  spi_sync(wl_to_spi(wl), &m);
74 
75  wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
76 
77  kfree(cmd);
78 }
79 
80 static void wl1251_spi_wake(struct wl1251 *wl)
81 {
83  struct spi_transfer t;
84  struct spi_message m;
85 
86  cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
87  if (!cmd) {
88  wl1251_error("could not allocate cmd for spi init");
89  return;
90  }
91 
92  memset(crc, 0, sizeof(crc));
93  memset(&t, 0, sizeof(t));
94  spi_message_init(&m);
95 
96  /*
97  * Set WSPI_INIT_COMMAND
98  * the data is being send from the MSB to LSB
99  */
100  cmd[2] = 0xff;
101  cmd[3] = 0xff;
103  cmd[0] = 0;
104  cmd[7] = 0;
105  cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
107 
109  cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
110  else
111  cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
112 
115 
116  crc[0] = cmd[1];
117  crc[1] = cmd[0];
118  crc[2] = cmd[7];
119  crc[3] = cmd[6];
120  crc[4] = cmd[5];
121 
122  cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
123  cmd[4] |= WSPI_INIT_CMD_END;
124 
125  t.tx_buf = cmd;
126  t.len = WSPI_INIT_CMD_LEN;
127  spi_message_add_tail(&t, &m);
128 
129  spi_sync(wl_to_spi(wl), &m);
130 
131  wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
132 
133  kfree(cmd);
134 }
135 
136 static void wl1251_spi_reset_wake(struct wl1251 *wl)
137 {
138  wl1251_spi_reset(wl);
139  wl1251_spi_wake(wl);
140 }
141 
142 static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
143  size_t len)
144 {
145  struct spi_transfer t[3];
146  struct spi_message m;
147  u8 *busy_buf;
148  u32 *cmd;
149 
150  cmd = &wl->buffer_cmd;
151  busy_buf = wl->buffer_busyword;
152 
153  *cmd = 0;
154  *cmd |= WSPI_CMD_READ;
156  *cmd |= addr & WSPI_CMD_BYTE_ADDR;
157 
158  spi_message_init(&m);
159  memset(t, 0, sizeof(t));
160 
161  t[0].tx_buf = cmd;
162  t[0].len = 4;
163  spi_message_add_tail(&t[0], &m);
164 
165  /* Busy and non busy words read */
166  t[1].rx_buf = busy_buf;
167  t[1].len = WL1251_BUSY_WORD_LEN;
168  spi_message_add_tail(&t[1], &m);
169 
170  t[2].rx_buf = buf;
171  t[2].len = len;
172  spi_message_add_tail(&t[2], &m);
173 
174  spi_sync(wl_to_spi(wl), &m);
175 
176  /* FIXME: check busy words */
177 
178  wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
179  wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
180 }
181 
182 static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
183  size_t len)
184 {
185  struct spi_transfer t[2];
186  struct spi_message m;
187  u32 *cmd;
188 
189  cmd = &wl->buffer_cmd;
190 
191  *cmd = 0;
192  *cmd |= WSPI_CMD_WRITE;
194  *cmd |= addr & WSPI_CMD_BYTE_ADDR;
195 
196  spi_message_init(&m);
197  memset(t, 0, sizeof(t));
198 
199  t[0].tx_buf = cmd;
200  t[0].len = sizeof(*cmd);
201  spi_message_add_tail(&t[0], &m);
202 
203  t[1].tx_buf = buf;
204  t[1].len = len;
205  spi_message_add_tail(&t[1], &m);
206 
207  spi_sync(wl_to_spi(wl), &m);
208 
209  wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
210  wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
211 }
212 
213 static void wl1251_spi_enable_irq(struct wl1251 *wl)
214 {
215  return enable_irq(wl->irq);
216 }
217 
218 static void wl1251_spi_disable_irq(struct wl1251 *wl)
219 {
220  return disable_irq(wl->irq);
221 }
222 
223 static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
224 {
225  if (wl->set_power)
226  wl->set_power(enable);
227 
228  return 0;
229 }
230 
231 static const struct wl1251_if_operations wl1251_spi_ops = {
232  .read = wl1251_spi_read,
233  .write = wl1251_spi_write,
234  .reset = wl1251_spi_reset_wake,
235  .enable_irq = wl1251_spi_enable_irq,
236  .disable_irq = wl1251_spi_disable_irq,
237  .power = wl1251_spi_set_power,
238 };
239 
240 static int __devinit wl1251_spi_probe(struct spi_device *spi)
241 {
242  struct wl12xx_platform_data *pdata;
243  struct ieee80211_hw *hw;
244  struct wl1251 *wl;
245  int ret;
246 
247  pdata = spi->dev.platform_data;
248  if (!pdata) {
249  wl1251_error("no platform data");
250  return -ENODEV;
251  }
252 
253  hw = wl1251_alloc_hw();
254  if (IS_ERR(hw))
255  return PTR_ERR(hw);
256 
257  wl = hw->priv;
258 
259  SET_IEEE80211_DEV(hw, &spi->dev);
260  dev_set_drvdata(&spi->dev, wl);
261  wl->if_priv = spi;
262  wl->if_ops = &wl1251_spi_ops;
263 
264  /* This is the only SPI value that we need to set here, the rest
265  * comes from the board-peripherals file */
266  spi->bits_per_word = 32;
267 
268  ret = spi_setup(spi);
269  if (ret < 0) {
270  wl1251_error("spi_setup failed");
271  goto out_free;
272  }
273 
274  wl->set_power = pdata->set_power;
275  if (!wl->set_power) {
276  wl1251_error("set power function missing in platform data");
277  return -ENODEV;
278  }
279 
280  wl->irq = spi->irq;
281  if (wl->irq < 0) {
282  wl1251_error("irq missing in platform data");
283  return -ENODEV;
284  }
285 
286  wl->use_eeprom = pdata->use_eeprom;
287 
288  irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
289  ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
290  if (ret < 0) {
291  wl1251_error("request_irq() failed: %d", ret);
292  goto out_free;
293  }
294 
296 
297  ret = wl1251_init_ieee80211(wl);
298  if (ret)
299  goto out_irq;
300 
301  return 0;
302 
303  out_irq:
304  free_irq(wl->irq, wl);
305 
306  out_free:
307  ieee80211_free_hw(hw);
308 
309  return ret;
310 }
311 
312 static int __devexit wl1251_spi_remove(struct spi_device *spi)
313 {
314  struct wl1251 *wl = dev_get_drvdata(&spi->dev);
315 
316  free_irq(wl->irq, wl);
317  wl1251_free_hw(wl);
318 
319  return 0;
320 }
321 
322 static struct spi_driver wl1251_spi_driver = {
323  .driver = {
324  .name = DRIVER_NAME,
325  .owner = THIS_MODULE,
326  },
327 
328  .probe = wl1251_spi_probe,
329  .remove = __devexit_p(wl1251_spi_remove),
330 };
331 
332 static int __init wl1251_spi_init(void)
333 {
334  int ret;
335 
336  ret = spi_register_driver(&wl1251_spi_driver);
337  if (ret < 0) {
338  wl1251_error("failed to register spi driver: %d", ret);
339  goto out;
340  }
341 
342 out:
343  return ret;
344 }
345 
346 static void __exit wl1251_spi_exit(void)
347 {
348  spi_unregister_driver(&wl1251_spi_driver);
349 
350  wl1251_notice("unloaded");
351 }
352 
353 module_init(wl1251_spi_init);
354 module_exit(wl1251_spi_exit);
355 
356 MODULE_LICENSE("GPL");
357 MODULE_AUTHOR("Kalle Valo <[email protected]>");
358 MODULE_ALIAS("spi:wl1251");