GNU Linux-libre 4.14.332-gnu1
[releases.git] / drivers / net / wireless / st / cw1200 / cw1200_sdio.c
1 /*
2  * Mac80211 SDIO driver for ST-Ericsson CW1200 device
3  *
4  * Copyright (c) 2010, ST-Ericsson
5  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/module.h>
13 #include <linux/interrupt.h>
14 #include <linux/gpio.h>
15 #include <linux/delay.h>
16 #include <linux/mmc/host.h>
17 #include <linux/mmc/sdio_func.h>
18 #include <linux/mmc/card.h>
19 #include <linux/mmc/sdio.h>
20 #include <net/mac80211.h>
21
22 #include "cw1200.h"
23 #include "hwbus.h"
24 #include <linux/platform_data/net-cw1200.h>
25 #include "hwio.h"
26
27 MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
28 MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SDIO driver");
29 MODULE_LICENSE("GPL");
30
31 #define SDIO_BLOCK_SIZE (512)
32
33 /* Default platform data for Sagrad modules */
34 static struct cw1200_platform_data_sdio sagrad_109x_evk_platform_data = {
35         .ref_clk = 38400,
36         .have_5ghz = false,
37         .sdd_file = "/*(DEBLOBBED)*/",
38 };
39
40 /* Allow platform data to be overridden */
41 static struct cw1200_platform_data_sdio *global_plat_data = &sagrad_109x_evk_platform_data;
42
43 void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata)
44 {
45         global_plat_data = pdata;
46 }
47
48 struct hwbus_priv {
49         struct sdio_func        *func;
50         struct cw1200_common    *core;
51         const struct cw1200_platform_data_sdio *pdata;
52 };
53
54 #ifndef SDIO_VENDOR_ID_STE
55 #define SDIO_VENDOR_ID_STE              0x0020
56 #endif
57
58 #ifndef SDIO_DEVICE_ID_STE_CW1200
59 #define SDIO_DEVICE_ID_STE_CW1200       0x2280
60 #endif
61
62 static const struct sdio_device_id cw1200_sdio_ids[] = {
63         { SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) },
64         { /* end: all zeroes */                 },
65 };
66 MODULE_DEVICE_TABLE(sdio, cw1200_sdio_ids);
67
68 /* hwbus_ops implemetation */
69
70 static int cw1200_sdio_memcpy_fromio(struct hwbus_priv *self,
71                                      unsigned int addr,
72                                      void *dst, int count)
73 {
74         return sdio_memcpy_fromio(self->func, dst, addr, count);
75 }
76
77 static int cw1200_sdio_memcpy_toio(struct hwbus_priv *self,
78                                    unsigned int addr,
79                                    const void *src, int count)
80 {
81         return sdio_memcpy_toio(self->func, addr, (void *)src, count);
82 }
83
84 static void cw1200_sdio_lock(struct hwbus_priv *self)
85 {
86         sdio_claim_host(self->func);
87 }
88
89 static void cw1200_sdio_unlock(struct hwbus_priv *self)
90 {
91         sdio_release_host(self->func);
92 }
93
94 static void cw1200_sdio_irq_handler(struct sdio_func *func)
95 {
96         struct hwbus_priv *self = sdio_get_drvdata(func);
97
98         /* note:  sdio_host already claimed here. */
99         if (self->core)
100                 cw1200_irq_handler(self->core);
101 }
102
103 static irqreturn_t cw1200_gpio_hardirq(int irq, void *dev_id)
104 {
105         return IRQ_WAKE_THREAD;
106 }
107
108 static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
109 {
110         struct hwbus_priv *self = dev_id;
111
112         if (self->core) {
113                 cw1200_sdio_lock(self);
114                 cw1200_irq_handler(self->core);
115                 cw1200_sdio_unlock(self);
116                 return IRQ_HANDLED;
117         } else {
118                 return IRQ_NONE;
119         }
120 }
121
122 static int cw1200_request_irq(struct hwbus_priv *self)
123 {
124         int ret;
125         u8 cccr;
126
127         cccr = sdio_f0_readb(self->func, SDIO_CCCR_IENx, &ret);
128         if (WARN_ON(ret))
129                 goto err;
130
131         /* Master interrupt enable ... */
132         cccr |= BIT(0);
133
134         /* ... for our function */
135         cccr |= BIT(self->func->num);
136
137         sdio_f0_writeb(self->func, cccr, SDIO_CCCR_IENx, &ret);
138         if (WARN_ON(ret))
139                 goto err;
140
141         ret = enable_irq_wake(self->pdata->irq);
142         if (WARN_ON(ret))
143                 goto err;
144
145         /* Request the IRQ */
146         ret =  request_threaded_irq(self->pdata->irq, cw1200_gpio_hardirq,
147                                     cw1200_gpio_irq,
148                                     IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
149                                     "cw1200_wlan_irq", self);
150         if (WARN_ON(ret))
151                 goto err;
152
153         return 0;
154
155 err:
156         return ret;
157 }
158
159 static int cw1200_sdio_irq_subscribe(struct hwbus_priv *self)
160 {
161         int ret = 0;
162
163         pr_debug("SW IRQ subscribe\n");
164         sdio_claim_host(self->func);
165         if (self->pdata->irq)
166                 ret = cw1200_request_irq(self);
167         else
168                 ret = sdio_claim_irq(self->func, cw1200_sdio_irq_handler);
169
170         sdio_release_host(self->func);
171         return ret;
172 }
173
174 static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self)
175 {
176         int ret = 0;
177
178         pr_debug("SW IRQ unsubscribe\n");
179
180         if (self->pdata->irq) {
181                 disable_irq_wake(self->pdata->irq);
182                 free_irq(self->pdata->irq, self);
183         } else {
184                 sdio_claim_host(self->func);
185                 ret = sdio_release_irq(self->func);
186                 sdio_release_host(self->func);
187         }
188         return ret;
189 }
190
191 static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
192 {
193         if (pdata->reset) {
194                 gpio_set_value(pdata->reset, 0);
195                 msleep(30); /* Min is 2 * CLK32K cycles */
196                 gpio_free(pdata->reset);
197         }
198
199         if (pdata->power_ctrl)
200                 pdata->power_ctrl(pdata, false);
201         if (pdata->clk_ctrl)
202                 pdata->clk_ctrl(pdata, false);
203
204         return 0;
205 }
206
207 static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
208 {
209         /* Ensure I/Os are pulled low */
210         if (pdata->reset) {
211                 gpio_request(pdata->reset, "cw1200_wlan_reset");
212                 gpio_direction_output(pdata->reset, 0);
213         }
214         if (pdata->powerup) {
215                 gpio_request(pdata->powerup, "cw1200_wlan_powerup");
216                 gpio_direction_output(pdata->powerup, 0);
217         }
218         if (pdata->reset || pdata->powerup)
219                 msleep(10); /* Settle time? */
220
221         /* Enable 3v3 and 1v8 to hardware */
222         if (pdata->power_ctrl) {
223                 if (pdata->power_ctrl(pdata, true)) {
224                         pr_err("power_ctrl() failed!\n");
225                         return -1;
226                 }
227         }
228
229         /* Enable CLK32K */
230         if (pdata->clk_ctrl) {
231                 if (pdata->clk_ctrl(pdata, true)) {
232                         pr_err("clk_ctrl() failed!\n");
233                         return -1;
234                 }
235                 msleep(10); /* Delay until clock is stable for 2 cycles */
236         }
237
238         /* Enable POWERUP signal */
239         if (pdata->powerup) {
240                 gpio_set_value(pdata->powerup, 1);
241                 msleep(250); /* or more..? */
242         }
243         /* Enable RSTn signal */
244         if (pdata->reset) {
245                 gpio_set_value(pdata->reset, 1);
246                 msleep(50); /* Or more..? */
247         }
248         return 0;
249 }
250
251 static size_t cw1200_sdio_align_size(struct hwbus_priv *self, size_t size)
252 {
253         if (self->pdata->no_nptb)
254                 size = round_up(size, SDIO_BLOCK_SIZE);
255         else
256                 size = sdio_align_size(self->func, size);
257
258         return size;
259 }
260
261 static int cw1200_sdio_pm(struct hwbus_priv *self, bool suspend)
262 {
263         int ret = 0;
264
265         if (self->pdata->irq)
266                 ret = irq_set_irq_wake(self->pdata->irq, suspend);
267         return ret;
268 }
269
270 static const struct hwbus_ops cw1200_sdio_hwbus_ops = {
271         .hwbus_memcpy_fromio    = cw1200_sdio_memcpy_fromio,
272         .hwbus_memcpy_toio      = cw1200_sdio_memcpy_toio,
273         .lock                   = cw1200_sdio_lock,
274         .unlock                 = cw1200_sdio_unlock,
275         .align_size             = cw1200_sdio_align_size,
276         .power_mgmt             = cw1200_sdio_pm,
277 };
278
279 /* Probe Function to be called by SDIO stack when device is discovered */
280 static int cw1200_sdio_probe(struct sdio_func *func,
281                              const struct sdio_device_id *id)
282 {
283         struct hwbus_priv *self;
284         int status;
285
286         pr_info("cw1200_wlan_sdio: Probe called\n");
287
288         /* We are only able to handle the wlan function */
289         if (func->num != 0x01)
290                 return -ENODEV;
291
292         self = kzalloc(sizeof(*self), GFP_KERNEL);
293         if (!self) {
294                 pr_err("Can't allocate SDIO hwbus_priv.\n");
295                 return -ENOMEM;
296         }
297
298         func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
299
300         self->pdata = global_plat_data; /* FIXME */
301         self->func = func;
302         sdio_set_drvdata(func, self);
303         sdio_claim_host(func);
304         sdio_enable_func(func);
305         sdio_release_host(func);
306
307         status = cw1200_sdio_irq_subscribe(self);
308
309         status = cw1200_core_probe(&cw1200_sdio_hwbus_ops,
310                                    self, &func->dev, &self->core,
311                                    self->pdata->ref_clk,
312                                    self->pdata->macaddr,
313                                    self->pdata->sdd_file,
314                                    self->pdata->have_5ghz);
315         if (status) {
316                 cw1200_sdio_irq_unsubscribe(self);
317                 sdio_claim_host(func);
318                 sdio_disable_func(func);
319                 sdio_release_host(func);
320                 sdio_set_drvdata(func, NULL);
321                 kfree(self);
322         }
323
324         return status;
325 }
326
327 /* Disconnect Function to be called by SDIO stack when
328  * device is disconnected
329  */
330 static void cw1200_sdio_disconnect(struct sdio_func *func)
331 {
332         struct hwbus_priv *self = sdio_get_drvdata(func);
333
334         if (self) {
335                 cw1200_sdio_irq_unsubscribe(self);
336                 if (self->core) {
337                         cw1200_core_release(self->core);
338                         self->core = NULL;
339                 }
340                 sdio_claim_host(func);
341                 sdio_disable_func(func);
342                 sdio_release_host(func);
343                 sdio_set_drvdata(func, NULL);
344                 kfree(self);
345         }
346 }
347
348 #ifdef CONFIG_PM
349 static int cw1200_sdio_suspend(struct device *dev)
350 {
351         int ret;
352         struct sdio_func *func = dev_to_sdio_func(dev);
353         struct hwbus_priv *self = sdio_get_drvdata(func);
354
355         if (!cw1200_can_suspend(self->core))
356                 return -EAGAIN;
357
358         /* Notify SDIO that CW1200 will remain powered during suspend */
359         ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
360         if (ret)
361                 pr_err("Error setting SDIO pm flags: %i\n", ret);
362
363         return ret;
364 }
365
366 static int cw1200_sdio_resume(struct device *dev)
367 {
368         return 0;
369 }
370
371 static const struct dev_pm_ops cw1200_pm_ops = {
372         .suspend = cw1200_sdio_suspend,
373         .resume = cw1200_sdio_resume,
374 };
375 #endif
376
377 static struct sdio_driver sdio_driver = {
378         .name           = "cw1200_wlan_sdio",
379         .id_table       = cw1200_sdio_ids,
380         .probe          = cw1200_sdio_probe,
381         .remove         = cw1200_sdio_disconnect,
382 #ifdef CONFIG_PM
383         .drv = {
384                 .pm = &cw1200_pm_ops,
385         }
386 #endif
387 };
388
389 /* Init Module function -> Called by insmod */
390 static int __init cw1200_sdio_init(void)
391 {
392         const struct cw1200_platform_data_sdio *pdata;
393         int ret;
394
395         /* FIXME -- this won't support multiple devices */
396         pdata = global_plat_data;
397
398         if (cw1200_sdio_on(pdata)) {
399                 ret = -1;
400                 goto err;
401         }
402
403         ret = sdio_register_driver(&sdio_driver);
404         if (ret)
405                 goto err;
406
407         return 0;
408
409 err:
410         cw1200_sdio_off(pdata);
411         return ret;
412 }
413
414 /* Called at Driver Unloading */
415 static void __exit cw1200_sdio_exit(void)
416 {
417         const struct cw1200_platform_data_sdio *pdata;
418
419         /* FIXME -- this won't support multiple devices */
420         pdata = global_plat_data;
421         sdio_unregister_driver(&sdio_driver);
422         cw1200_sdio_off(pdata);
423 }
424
425
426 module_init(cw1200_sdio_init);
427 module_exit(cw1200_sdio_exit);