1 // SPDX-License-Identifier: GPL-2.0-only
3 * This file is part of wl1271
5 * Copyright (C) 2009-2010 Nokia Corporation
7 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
10 #include <linux/irq.h>
11 #include <linux/module.h>
12 #include <linux/vmalloc.h>
13 #include <linux/platform_device.h>
14 #include <linux/mmc/sdio.h>
15 #include <linux/mmc/sdio_func.h>
16 #include <linux/mmc/sdio_ids.h>
17 #include <linux/mmc/card.h>
18 #include <linux/mmc/host.h>
19 #include <linux/gpio.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/printk.h>
23 #include <linux/of_irq.h>
26 #include "wl12xx_80211.h"
29 static bool dump
= false;
31 struct wl12xx_sdio_glue
{
33 struct platform_device
*core
;
36 static const struct sdio_device_id wl1271_devices
[] = {
37 { SDIO_DEVICE(SDIO_VENDOR_ID_TI
, SDIO_DEVICE_ID_TI_WL1271
) },
40 MODULE_DEVICE_TABLE(sdio
, wl1271_devices
);
42 static void wl1271_sdio_set_block_size(struct device
*child
,
45 struct wl12xx_sdio_glue
*glue
= dev_get_drvdata(child
->parent
);
46 struct sdio_func
*func
= dev_to_sdio_func(glue
->dev
);
48 sdio_claim_host(func
);
49 sdio_set_block_size(func
, blksz
);
50 sdio_release_host(func
);
53 static int __must_check
wl12xx_sdio_raw_read(struct device
*child
, int addr
,
54 void *buf
, size_t len
, bool fixed
)
57 struct wl12xx_sdio_glue
*glue
= dev_get_drvdata(child
->parent
);
58 struct sdio_func
*func
= dev_to_sdio_func(glue
->dev
);
60 sdio_claim_host(func
);
62 if (unlikely(addr
== HW_ACCESS_ELP_CTRL_REG
)) {
63 ((u8
*)buf
)[0] = sdio_f0_readb(func
, addr
, &ret
);
64 dev_dbg(child
->parent
, "sdio read 52 addr 0x%x, byte 0x%02x\n",
65 addr
, ((u8
*)buf
)[0]);
68 ret
= sdio_readsb(func
, buf
, addr
, len
);
70 ret
= sdio_memcpy_fromio(func
, buf
, addr
, len
);
72 dev_dbg(child
->parent
, "sdio read 53 addr 0x%x, %zu bytes\n",
76 sdio_release_host(func
);
79 dev_err(child
->parent
, "sdio read failed (%d)\n", ret
);
82 printk(KERN_DEBUG
"wlcore_sdio: READ from 0x%04x\n", addr
);
83 print_hex_dump(KERN_DEBUG
, "wlcore_sdio: READ ",
84 DUMP_PREFIX_OFFSET
, 16, 1,
91 static int __must_check
wl12xx_sdio_raw_write(struct device
*child
, int addr
,
92 void *buf
, size_t len
, bool fixed
)
95 struct wl12xx_sdio_glue
*glue
= dev_get_drvdata(child
->parent
);
96 struct sdio_func
*func
= dev_to_sdio_func(glue
->dev
);
98 sdio_claim_host(func
);
100 if (unlikely(dump
)) {
101 printk(KERN_DEBUG
"wlcore_sdio: WRITE to 0x%04x\n", addr
);
102 print_hex_dump(KERN_DEBUG
, "wlcore_sdio: WRITE ",
103 DUMP_PREFIX_OFFSET
, 16, 1,
107 if (unlikely(addr
== HW_ACCESS_ELP_CTRL_REG
)) {
108 sdio_f0_writeb(func
, ((u8
*)buf
)[0], addr
, &ret
);
109 dev_dbg(child
->parent
, "sdio write 52 addr 0x%x, byte 0x%02x\n",
110 addr
, ((u8
*)buf
)[0]);
112 dev_dbg(child
->parent
, "sdio write 53 addr 0x%x, %zu bytes\n",
116 ret
= sdio_writesb(func
, addr
, buf
, len
);
118 ret
= sdio_memcpy_toio(func
, addr
, buf
, len
);
121 sdio_release_host(func
);
124 dev_err(child
->parent
, "sdio write failed (%d)\n", ret
);
129 static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue
*glue
)
132 struct sdio_func
*func
= dev_to_sdio_func(glue
->dev
);
133 struct mmc_card
*card
= func
->card
;
135 ret
= pm_runtime_get_sync(&card
->dev
);
137 pm_runtime_put_noidle(&card
->dev
);
138 dev_err(glue
->dev
, "%s: failed to get_sync(%d)\n",
144 sdio_claim_host(func
);
146 * To guarantee that the SDIO card is power cycled, as required to make
147 * the FW programming to succeed, let's do a brute force HW reset.
149 mmc_hw_reset(card
->host
);
151 sdio_enable_func(func
);
152 sdio_release_host(func
);
157 static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue
*glue
)
159 struct sdio_func
*func
= dev_to_sdio_func(glue
->dev
);
160 struct mmc_card
*card
= func
->card
;
162 sdio_claim_host(func
);
163 sdio_disable_func(func
);
164 sdio_release_host(func
);
166 /* Let runtime PM know the card is powered off */
167 pm_runtime_put(&card
->dev
);
171 static int wl12xx_sdio_set_power(struct device
*child
, bool enable
)
173 struct wl12xx_sdio_glue
*glue
= dev_get_drvdata(child
->parent
);
176 return wl12xx_sdio_power_on(glue
);
178 return wl12xx_sdio_power_off(glue
);
181 static struct wl1271_if_operations sdio_ops
= {
182 .read
= wl12xx_sdio_raw_read
,
183 .write
= wl12xx_sdio_raw_write
,
184 .power
= wl12xx_sdio_set_power
,
185 .set_block_size
= wl1271_sdio_set_block_size
,
190 static const struct wilink_family_data wl127x_data
= {
192 .nvs_name
= "ti-connectivity/wl127x-nvs.bin",
195 static const struct wilink_family_data wl128x_data
= {
197 .nvs_name
= "ti-connectivity/wl128x-nvs.bin",
200 static const struct wilink_family_data wl18xx_data
= {
202 .cfg_name
= "ti-connectivity/wl18xx-conf.bin",
203 .nvs_name
= "ti-connectivity/wl1271-nvs.bin",
206 static const struct of_device_id wlcore_sdio_of_match_table
[] = {
207 { .compatible
= "ti,wl1271", .data
= &wl127x_data
},
208 { .compatible
= "ti,wl1273", .data
= &wl127x_data
},
209 { .compatible
= "ti,wl1281", .data
= &wl128x_data
},
210 { .compatible
= "ti,wl1283", .data
= &wl128x_data
},
211 { .compatible
= "ti,wl1285", .data
= &wl128x_data
},
212 { .compatible
= "ti,wl1801", .data
= &wl18xx_data
},
213 { .compatible
= "ti,wl1805", .data
= &wl18xx_data
},
214 { .compatible
= "ti,wl1807", .data
= &wl18xx_data
},
215 { .compatible
= "ti,wl1831", .data
= &wl18xx_data
},
216 { .compatible
= "ti,wl1835", .data
= &wl18xx_data
},
217 { .compatible
= "ti,wl1837", .data
= &wl18xx_data
},
221 static int wlcore_probe_of(struct device
*dev
, int *irq
, int *wakeirq
,
222 struct wlcore_platdev_data
*pdev_data
)
224 struct device_node
*np
= dev
->of_node
;
225 const struct of_device_id
*of_id
;
227 of_id
= of_match_node(wlcore_sdio_of_match_table
, np
);
231 pdev_data
->family
= of_id
->data
;
233 *irq
= irq_of_parse_and_map(np
, 0);
235 dev_err(dev
, "No irq in platform data\n");
239 *wakeirq
= irq_of_parse_and_map(np
, 1);
241 /* optional clock frequency params */
242 of_property_read_u32(np
, "ref-clock-frequency",
243 &pdev_data
->ref_clock_freq
);
244 of_property_read_u32(np
, "tcxo-clock-frequency",
245 &pdev_data
->tcxo_clock_freq
);
250 static int wlcore_probe_of(struct device
*dev
, int *irq
, int *wakeirq
,
251 struct wlcore_platdev_data
*pdev_data
)
257 static int wl1271_probe(struct sdio_func
*func
,
258 const struct sdio_device_id
*id
)
260 struct wlcore_platdev_data
*pdev_data
;
261 struct wl12xx_sdio_glue
*glue
;
262 struct resource res
[2];
263 mmc_pm_flag_t mmcflags
;
265 int irq
, wakeirq
, num_irqs
;
266 const char *chip_family
;
268 /* We are only able to handle the wlan function */
269 if (func
->num
!= 0x02)
272 pdev_data
= devm_kzalloc(&func
->dev
, sizeof(*pdev_data
), GFP_KERNEL
);
276 pdev_data
->if_ops
= &sdio_ops
;
278 glue
= devm_kzalloc(&func
->dev
, sizeof(*glue
), GFP_KERNEL
);
282 glue
->dev
= &func
->dev
;
284 /* Grab access to FN0 for ELP reg. */
285 func
->card
->quirks
|= MMC_QUIRK_LENIENT_FN0
;
287 /* Use block mode for transferring over one block size of data */
288 func
->card
->quirks
|= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE
;
290 ret
= wlcore_probe_of(&func
->dev
, &irq
, &wakeirq
, pdev_data
);
294 /* if sdio can keep power while host is suspended, enable wow */
295 mmcflags
= sdio_get_host_pm_caps(func
);
296 dev_dbg(glue
->dev
, "sdio PM caps = 0x%x\n", mmcflags
);
298 if (mmcflags
& MMC_PM_KEEP_POWER
)
299 pdev_data
->pwr_in_suspend
= true;
301 sdio_set_drvdata(func
, glue
);
303 /* Tell PM core that we don't need the card to be powered now */
304 pm_runtime_put_noidle(&func
->dev
);
307 * Due to a hardware bug, we can't differentiate wl18xx from
308 * wl12xx, because both report the same device ID. The only
309 * way to differentiate is by checking the SDIO revision,
310 * which is 3.00 on the wl18xx chips.
312 if (func
->card
->cccr
.sdio_vsn
== SDIO_SDIO_REV_3_00
)
313 chip_family
= "wl18xx";
315 chip_family
= "wl12xx";
317 glue
->core
= platform_device_alloc(chip_family
, PLATFORM_DEVID_AUTO
);
319 dev_err(glue
->dev
, "can't allocate platform_device");
324 glue
->core
->dev
.parent
= &func
->dev
;
326 memset(res
, 0x00, sizeof(res
));
329 res
[0].flags
= IORESOURCE_IRQ
|
330 irqd_get_trigger_type(irq_get_irq_data(irq
));
335 res
[1].start
= wakeirq
;
336 res
[1].flags
= IORESOURCE_IRQ
|
337 irqd_get_trigger_type(irq_get_irq_data(wakeirq
));
338 res
[1].name
= "wakeirq";
343 ret
= platform_device_add_resources(glue
->core
, res
, num_irqs
);
345 dev_err(glue
->dev
, "can't add resources\n");
349 ret
= platform_device_add_data(glue
->core
, pdev_data
,
352 dev_err(glue
->dev
, "can't add platform data\n");
356 ret
= platform_device_add(glue
->core
);
358 dev_err(glue
->dev
, "can't add platform device\n");
364 platform_device_put(glue
->core
);
370 static void wl1271_remove(struct sdio_func
*func
)
372 struct wl12xx_sdio_glue
*glue
= sdio_get_drvdata(func
);
374 /* Undo decrement done above in wl1271_probe */
375 pm_runtime_get_noresume(&func
->dev
);
377 platform_device_unregister(glue
->core
);
381 static int wl1271_suspend(struct device
*dev
)
383 /* Tell MMC/SDIO core it's OK to power down the card
384 * (if it isn't already), but not to remove it completely */
385 struct sdio_func
*func
= dev_to_sdio_func(dev
);
386 struct wl12xx_sdio_glue
*glue
= sdio_get_drvdata(func
);
387 struct wl1271
*wl
= platform_get_drvdata(glue
->core
);
388 mmc_pm_flag_t sdio_flags
;
392 dev_err(dev
, "no wilink module was probed\n");
396 dev_dbg(dev
, "wl1271 suspend. wow_enabled: %d\n",
399 /* check whether sdio should keep power */
400 if (wl
->wow_enabled
) {
401 sdio_flags
= sdio_get_host_pm_caps(func
);
403 if (!(sdio_flags
& MMC_PM_KEEP_POWER
)) {
404 dev_err(dev
, "can't keep power while host "
410 /* keep power while host suspended */
411 ret
= sdio_set_host_pm_flags(func
, MMC_PM_KEEP_POWER
);
413 dev_err(dev
, "error while trying to keep power\n");
421 static int wl1271_resume(struct device
*dev
)
423 dev_dbg(dev
, "wl1271 resume\n");
428 static const struct dev_pm_ops wl1271_sdio_pm_ops
= {
429 .suspend
= wl1271_suspend
,
430 .resume
= wl1271_resume
,
434 static struct sdio_driver wl1271_sdio_driver
= {
435 .name
= "wl1271_sdio",
436 .id_table
= wl1271_devices
,
437 .probe
= wl1271_probe
,
438 .remove
= wl1271_remove
,
441 .pm
= &wl1271_sdio_pm_ops
,
446 static int __init
wl1271_init(void)
448 return sdio_register_driver(&wl1271_sdio_driver
);
451 static void __exit
wl1271_exit(void)
453 sdio_unregister_driver(&wl1271_sdio_driver
);
456 module_init(wl1271_init
);
457 module_exit(wl1271_exit
);
459 module_param(dump
, bool, 0600);
460 MODULE_PARM_DESC(dump
, "Enable sdio read/write dumps.");
462 MODULE_LICENSE("GPL");
463 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
464 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");