blob: 75efe54e495f0b8d8b556a54b01eb29b8b2ea62c [file] [log] [blame]
Solomon Peachya910e4a2013-05-24 20:04:38 -04001/*
2 * Mac80211 SPI driver for ST-Ericsson CW1200 device
3 *
4 * Copyright (c) 2011, Sagrad Inc.
5 * Author: Solomon Peachy <speachy@sagrad.com>
6 *
7 * Based on cw1200_sdio.c
8 * Copyright (c) 2010, ST-Ericsson
9 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
Solomon Peachya910e4a2013-05-24 20:04:38 -040016#include <linux/module.h>
17#include <linux/gpio.h>
18#include <linux/delay.h>
19#include <linux/spinlock.h>
20#include <linux/interrupt.h>
21#include <net/mac80211.h>
22
23#include <linux/spi/spi.h>
24#include <linux/device.h>
25
26#include "cw1200.h"
Solomon Peachy911373c2013-06-01 08:08:42 -040027#include "hwbus.h"
Solomon Peachya910e4a2013-05-24 20:04:38 -040028#include <linux/cw1200_platform.h>
29#include "hwio.h"
30
31MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
32MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SPI driver");
33MODULE_LICENSE("GPL");
34MODULE_ALIAS("spi:cw1200_wlan_spi");
35
36/* #define SPI_DEBUG */
37
Solomon Peachy911373c2013-06-01 08:08:42 -040038struct hwbus_priv {
Solomon Peachya910e4a2013-05-24 20:04:38 -040039 struct spi_device *func;
40 struct cw1200_common *core;
41 const struct cw1200_platform_data_spi *pdata;
42 spinlock_t lock; /* Serialize all bus operations */
43 int claimed;
44};
45
46#define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2)
47#define SET_WRITE 0x7FFF /* usage: and operation */
48#define SET_READ 0x8000 /* usage: or operation */
49
50/*
51 Notes on byte ordering:
52 LE: B0 B1 B2 B3
53 BE: B3 B2 B1 B0
54
55 Hardware expects 32-bit data to be written as 16-bit BE words:
56
57 B1 B0 B3 B2
58
59*/
60
Solomon Peachy911373c2013-06-01 08:08:42 -040061static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
Solomon Peachya910e4a2013-05-24 20:04:38 -040062 unsigned int addr,
63 void *dst, int count)
64{
65 int ret, i;
66 uint16_t regaddr;
67 struct spi_message m;
68
69 struct spi_transfer t_addr = {
70 .tx_buf = &regaddr,
71 .len = sizeof(regaddr),
72 };
73 struct spi_transfer t_msg = {
74 .rx_buf = dst,
75 .len = count,
76 };
77
78 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
79 regaddr |= SET_READ;
80 regaddr |= (count>>1);
81 regaddr = cpu_to_le16(regaddr);
82
83#ifdef SPI_DEBUG
84 pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr,
85 le16_to_cpu(regaddr));
86#endif
87
88#if defined(__LITTLE_ENDIAN)
89 /* We have to byteswap if the SPI bus is limited to 8b operation */
90 if (self->func->bits_per_word == 8)
91#endif
92 regaddr = swab16(regaddr);
93
94 spi_message_init(&m);
95 spi_message_add_tail(&t_addr, &m);
96 spi_message_add_tail(&t_msg, &m);
97 ret = spi_sync(self->func, &m);
98
99#ifdef SPI_DEBUG
100 pr_info("READ : ");
101 for (i = 0; i < t_addr.len; i++)
102 printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
103 printk(" : ");
104 for (i = 0; i < t_msg.len; i++)
105 printk("%02x ", ((u8 *)t_msg.rx_buf)[i]);
106 printk("\n");
107#endif
108
109#if defined(__LITTLE_ENDIAN)
110 /* We have to byteswap if the SPI bus is limited to 8b operation */
111 if (self->func->bits_per_word == 8)
112#endif
113 {
114 uint16_t *buf = (uint16_t *)dst;
115 for (i = 0; i < ((count + 1) >> 1); i++)
116 buf[i] = swab16(buf[i]);
117 }
118
119 return ret;
120}
121
Solomon Peachy911373c2013-06-01 08:08:42 -0400122static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
Solomon Peachya910e4a2013-05-24 20:04:38 -0400123 unsigned int addr,
124 const void *src, int count)
125{
126 int rval, i;
127 uint16_t regaddr;
128 struct spi_transfer t_addr = {
129 .tx_buf = &regaddr,
130 .len = sizeof(regaddr),
131 };
132 struct spi_transfer t_msg = {
133 .tx_buf = src,
134 .len = count,
135 };
136 struct spi_message m;
137
138 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
139 regaddr &= SET_WRITE;
140 regaddr |= (count>>1);
141 regaddr = cpu_to_le16(regaddr);
142
143#ifdef SPI_DEBUG
144 pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr,
145 le16_to_cpu(regaddr));
146#endif
147
148#if defined(__LITTLE_ENDIAN)
149 /* We have to byteswap if the SPI bus is limited to 8b operation */
150 if (self->func->bits_per_word == 8)
151#endif
152 {
153 uint16_t *buf = (uint16_t *)src;
154 regaddr = swab16(regaddr);
155 for (i = 0; i < ((count + 1) >> 1); i++)
156 buf[i] = swab16(buf[i]);
157 }
158
159#ifdef SPI_DEBUG
160 pr_info("WRITE: ");
161 for (i = 0; i < t_addr.len; i++)
162 printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
163 printk(" : ");
164 for (i = 0; i < t_msg.len; i++)
165 printk("%02x ", ((u8 *)t_msg.tx_buf)[i]);
166 printk("\n");
167#endif
168
169 spi_message_init(&m);
170 spi_message_add_tail(&t_addr, &m);
171 spi_message_add_tail(&t_msg, &m);
172 rval = spi_sync(self->func, &m);
173
174#ifdef SPI_DEBUG
175 pr_info("WROTE: %d\n", m.actual_length);
176#endif
177
178#if defined(__LITTLE_ENDIAN)
179 /* We have to byteswap if the SPI bus is limited to 8b operation */
180 if (self->func->bits_per_word == 8)
181#endif
182 {
183 uint16_t *buf = (uint16_t *)src;
184 for (i = 0; i < ((count + 1) >> 1); i++)
185 buf[i] = swab16(buf[i]);
186 }
187 return rval;
188}
189
Solomon Peachy911373c2013-06-01 08:08:42 -0400190static void cw1200_spi_lock(struct hwbus_priv *self)
Solomon Peachya910e4a2013-05-24 20:04:38 -0400191{
192 unsigned long flags;
193
194 might_sleep();
195
196 spin_lock_irqsave(&self->lock, flags);
197 while (1) {
198 set_current_state(TASK_UNINTERRUPTIBLE);
199 if (!self->claimed)
200 break;
201 spin_unlock_irqrestore(&self->lock, flags);
202 schedule();
203 spin_lock_irqsave(&self->lock, flags);
204 }
205 set_current_state(TASK_RUNNING);
206 self->claimed = 1;
207 spin_unlock_irqrestore(&self->lock, flags);
208
209 return;
210}
211
Solomon Peachy911373c2013-06-01 08:08:42 -0400212static void cw1200_spi_unlock(struct hwbus_priv *self)
Solomon Peachya910e4a2013-05-24 20:04:38 -0400213{
214 unsigned long flags;
215
216 spin_lock_irqsave(&self->lock, flags);
217 self->claimed = 0;
218 spin_unlock_irqrestore(&self->lock, flags);
219 return;
220}
221
222static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
223{
Solomon Peachy911373c2013-06-01 08:08:42 -0400224 struct hwbus_priv *self = dev_id;
Solomon Peachya910e4a2013-05-24 20:04:38 -0400225
226 if (self->core) {
227 cw1200_irq_handler(self->core);
228 return IRQ_HANDLED;
229 } else {
230 return IRQ_NONE;
231 }
232}
233
Solomon Peachy911373c2013-06-01 08:08:42 -0400234static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
Solomon Peachya910e4a2013-05-24 20:04:38 -0400235{
236 int ret;
237
238 pr_debug("SW IRQ subscribe\n");
239
240 ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler,
241 IRQF_TRIGGER_HIGH,
242 "cw1200_wlan_irq", self);
243 if (WARN_ON(ret < 0))
244 goto exit;
245
246 ret = enable_irq_wake(self->func->irq);
247 if (WARN_ON(ret))
248 goto free_irq;
249
250 return 0;
251
252free_irq:
253 free_irq(self->func->irq, self);
254exit:
255 return ret;
256}
257
Solomon Peachy911373c2013-06-01 08:08:42 -0400258static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
Solomon Peachya910e4a2013-05-24 20:04:38 -0400259{
260 int ret = 0;
261
262 pr_debug("SW IRQ unsubscribe\n");
263 disable_irq_wake(self->func->irq);
264 free_irq(self->func->irq, self);
265
266 return ret;
267}
268
269static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
270{
271 const struct resource *reset = pdata->reset;
272
273 if (reset) {
274 gpio_set_value(reset->start, 0);
275 msleep(30); /* Min is 2 * CLK32K cycles */
276 gpio_free(reset->start);
277 }
278
279 if (pdata->power_ctrl)
280 pdata->power_ctrl(pdata, false);
281 if (pdata->clk_ctrl)
282 pdata->clk_ctrl(pdata, false);
283
284 return 0;
285}
286
287static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
288{
289 const struct resource *reset = pdata->reset;
290 const struct resource *powerup = pdata->reset;
291
292 /* Ensure I/Os are pulled low */
293 if (reset) {
294 gpio_request(reset->start, reset->name);
295 gpio_direction_output(reset->start, 0);
296 }
297 if (powerup) {
298 gpio_request(powerup->start, powerup->name);
299 gpio_direction_output(powerup->start, 0);
300 }
301 if (reset || powerup)
302 msleep(10); /* Settle time? */
303
304 /* Enable 3v3 and 1v8 to hardware */
305 if (pdata->power_ctrl) {
306 if (pdata->power_ctrl(pdata, true)) {
307 pr_err("power_ctrl() failed!\n");
308 return -1;
309 }
310 }
311
312 /* Enable CLK32K */
313 if (pdata->clk_ctrl) {
314 if (pdata->clk_ctrl(pdata, true)) {
315 pr_err("clk_ctrl() failed!\n");
316 return -1;
317 }
318 msleep(10); /* Delay until clock is stable for 2 cycles */
319 }
320
321 /* Enable POWERUP signal */
322 if (powerup) {
323 gpio_set_value(powerup->start, 1);
324 msleep(250); /* or more..? */
325 }
326 /* Enable RSTn signal */
327 if (reset) {
328 gpio_set_value(reset->start, 1);
329 msleep(50); /* Or more..? */
330 }
331 return 0;
332}
333
Solomon Peachy911373c2013-06-01 08:08:42 -0400334static size_t cw1200_spi_align_size(struct hwbus_priv *self, size_t size)
Solomon Peachya910e4a2013-05-24 20:04:38 -0400335{
336 return size & 1 ? size + 1 : size;
337}
338
Solomon Peachy911373c2013-06-01 08:08:42 -0400339static int cw1200_spi_pm(struct hwbus_priv *self, bool suspend)
Solomon Peachya910e4a2013-05-24 20:04:38 -0400340{
341 return irq_set_irq_wake(self->func->irq, suspend);
342}
343
Solomon Peachy911373c2013-06-01 08:08:42 -0400344static struct hwbus_ops cw1200_spi_hwbus_ops = {
345 .hwbus_memcpy_fromio = cw1200_spi_memcpy_fromio,
346 .hwbus_memcpy_toio = cw1200_spi_memcpy_toio,
Solomon Peachya910e4a2013-05-24 20:04:38 -0400347 .lock = cw1200_spi_lock,
348 .unlock = cw1200_spi_unlock,
349 .align_size = cw1200_spi_align_size,
350 .power_mgmt = cw1200_spi_pm,
351};
352
353/* Probe Function to be called by SPI stack when device is discovered */
354static int cw1200_spi_probe(struct spi_device *func)
355{
356 const struct cw1200_platform_data_spi *plat_data =
357 func->dev.platform_data;
Solomon Peachy911373c2013-06-01 08:08:42 -0400358 struct hwbus_priv *self;
Solomon Peachya910e4a2013-05-24 20:04:38 -0400359 int status;
360
361 /* Sanity check speed */
362 if (func->max_speed_hz > 52000000)
363 func->max_speed_hz = 52000000;
364 if (func->max_speed_hz < 1000000)
365 func->max_speed_hz = 1000000;
366
367 /* Fix up transfer size */
368 if (plat_data->spi_bits_per_word)
369 func->bits_per_word = plat_data->spi_bits_per_word;
370 if (!func->bits_per_word)
371 func->bits_per_word = 16;
372
373 /* And finally.. */
374 func->mode = SPI_MODE_0;
375
376 pr_info("cw1200_wlan_spi: Probe called (CS %d M %d BPW %d CLK %d)\n",
377 func->chip_select, func->mode, func->bits_per_word,
378 func->max_speed_hz);
379
380 if (cw1200_spi_on(plat_data)) {
381 pr_err("spi_on() failed!\n");
382 return -1;
383 }
384
385 if (spi_setup(func)) {
386 pr_err("spi_setup() failed!\n");
387 return -1;
388 }
389
390 self = kzalloc(sizeof(*self), GFP_KERNEL);
391 if (!self) {
Solomon Peachy911373c2013-06-01 08:08:42 -0400392 pr_err("Can't allocate SPI hwbus_priv.");
Solomon Peachya910e4a2013-05-24 20:04:38 -0400393 return -ENOMEM;
394 }
395
396 self->pdata = plat_data;
397 self->func = func;
398 spin_lock_init(&self->lock);
399
400 spi_set_drvdata(func, self);
401
402 status = cw1200_spi_irq_subscribe(self);
403
Solomon Peachy911373c2013-06-01 08:08:42 -0400404 status = cw1200_core_probe(&cw1200_spi_hwbus_ops,
Solomon Peachya910e4a2013-05-24 20:04:38 -0400405 self, &func->dev, &self->core,
406 self->pdata->ref_clk,
407 self->pdata->macaddr,
408 self->pdata->sdd_file,
409 self->pdata->have_5ghz);
410
411 if (status) {
412 cw1200_spi_irq_unsubscribe(self);
413 cw1200_spi_off(plat_data);
414 kfree(self);
415 }
416
417 return status;
418}
419
420/* Disconnect Function to be called by SPI stack when device is disconnected */
421static int cw1200_spi_disconnect(struct spi_device *func)
422{
Solomon Peachy911373c2013-06-01 08:08:42 -0400423 struct hwbus_priv *self = spi_get_drvdata(func);
Solomon Peachya910e4a2013-05-24 20:04:38 -0400424
425 if (self) {
426 cw1200_spi_irq_unsubscribe(self);
427 if (self->core) {
428 cw1200_core_release(self->core);
429 self->core = NULL;
430 }
431 kfree(self);
432 }
433 cw1200_spi_off(func->dev.platform_data);
434
435 return 0;
436}
437
Solomon Peachy4e17b872013-05-29 22:22:05 -0400438#ifdef CONFIG_PM
Solomon Peachya910e4a2013-05-24 20:04:38 -0400439static int cw1200_spi_suspend(struct device *dev, pm_message_t state)
440{
Solomon Peachy911373c2013-06-01 08:08:42 -0400441 struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
Solomon Peachya910e4a2013-05-24 20:04:38 -0400442
443 if (!cw1200_can_suspend(self->core))
444 return -EAGAIN;
445
446 /* XXX notify host that we have to keep CW1200 powered on? */
447 return 0;
448}
449
450static int cw1200_spi_resume(struct device *dev)
451{
452 return 0;
453}
Solomon Peachy4e17b872013-05-29 22:22:05 -0400454#endif
Solomon Peachya910e4a2013-05-24 20:04:38 -0400455
456static struct spi_driver spi_driver = {
457 .probe = cw1200_spi_probe,
458 .remove = cw1200_spi_disconnect,
459 .driver = {
460 .name = "cw1200_wlan_spi",
461 .bus = &spi_bus_type,
462 .owner = THIS_MODULE,
Solomon Peachy4e17b872013-05-29 22:22:05 -0400463#ifdef CONFIG_PM
Solomon Peachya910e4a2013-05-24 20:04:38 -0400464 .suspend = cw1200_spi_suspend,
465 .resume = cw1200_spi_resume,
Solomon Peachy4e17b872013-05-29 22:22:05 -0400466#endif
Solomon Peachya910e4a2013-05-24 20:04:38 -0400467 },
468};
469
Wei Yongjund071c042013-05-30 19:42:54 +0800470module_spi_driver(spi_driver);