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