1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * This file is part of wl1271 4 * 5 * Copyright (C) 2009-2010 Nokia Corporation 6 * 7 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 8 */ 9 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> 22 #include <linux/of.h> 23 #include <linux/of_irq.h> 24 25 #include "wlcore.h" 26 #include "wl12xx_80211.h" 27 #include "io.h" 28 29 static bool dump = false; 30 31 struct wl12xx_sdio_glue { 32 struct device *dev; 33 struct platform_device *core; 34 }; 35 36 static const struct sdio_device_id wl1271_devices[] = { 37 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, 38 {} 39 }; 40 MODULE_DEVICE_TABLE(sdio, wl1271_devices); 41 42 static void wl1271_sdio_set_block_size(struct device *child, 43 unsigned int blksz) 44 { 45 struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); 46 struct sdio_func *func = dev_to_sdio_func(glue->dev); 47 48 sdio_claim_host(func); 49 sdio_set_block_size(func, blksz); 50 sdio_release_host(func); 51 } 52 53 static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr, 54 void *buf, size_t len, bool fixed) 55 { 56 int ret; 57 struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); 58 struct sdio_func *func = dev_to_sdio_func(glue->dev); 59 60 sdio_claim_host(func); 61 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]); 66 } else { 67 if (fixed) 68 ret = sdio_readsb(func, buf, addr, len); 69 else 70 ret = sdio_memcpy_fromio(func, buf, addr, len); 71 72 dev_dbg(child->parent, "sdio read 53 addr 0x%x, %zu bytes\n", 73 addr, len); 74 } 75 76 sdio_release_host(func); 77 78 if (WARN_ON(ret)) 79 dev_err(child->parent, "sdio read failed (%d)\n", ret); 80 81 if (unlikely(dump)) { 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, 85 buf, len, false); 86 } 87 88 return ret; 89 } 90 91 static int __must_check wl12xx_sdio_raw_write(struct device *child, int addr, 92 void *buf, size_t len, bool fixed) 93 { 94 int ret; 95 struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); 96 struct sdio_func *func = dev_to_sdio_func(glue->dev); 97 98 sdio_claim_host(func); 99 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, 104 buf, len, false); 105 } 106 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]); 111 } else { 112 dev_dbg(child->parent, "sdio write 53 addr 0x%x, %zu bytes\n", 113 addr, len); 114 115 if (fixed) 116 ret = sdio_writesb(func, addr, buf, len); 117 else 118 ret = sdio_memcpy_toio(func, addr, buf, len); 119 } 120 121 sdio_release_host(func); 122 123 if (WARN_ON(ret)) 124 dev_err(child->parent, "sdio write failed (%d)\n", ret); 125 126 return ret; 127 } 128 129 static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) 130 { 131 int ret; 132 struct sdio_func *func = dev_to_sdio_func(glue->dev); 133 struct mmc_card *card = func->card; 134 135 ret = pm_runtime_get_sync(&card->dev); 136 if (ret < 0) { 137 pm_runtime_put_noidle(&card->dev); 138 dev_err(glue->dev, "%s: failed to get_sync(%d)\n", 139 __func__, ret); 140 141 return ret; 142 } 143 144 sdio_claim_host(func); 145 /* 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. 148 */ 149 mmc_hw_reset(card->host); 150 151 sdio_enable_func(func); 152 sdio_release_host(func); 153 154 return 0; 155 } 156 157 static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) 158 { 159 struct sdio_func *func = dev_to_sdio_func(glue->dev); 160 struct mmc_card *card = func->card; 161 162 sdio_claim_host(func); 163 sdio_disable_func(func); 164 sdio_release_host(func); 165 166 /* Let runtime PM know the card is powered off */ 167 pm_runtime_put(&card->dev); 168 return 0; 169 } 170 171 static int wl12xx_sdio_set_power(struct device *child, bool enable) 172 { 173 struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); 174 175 if (enable) 176 return wl12xx_sdio_power_on(glue); 177 else 178 return wl12xx_sdio_power_off(glue); 179 } 180 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, 186 }; 187 188 #ifdef CONFIG_OF 189 190 static const struct wilink_family_data wl127x_data = { 191 .name = "wl127x", 192 .nvs_name = "ti-connectivity/wl127x-nvs.bin", 193 }; 194 195 static const struct wilink_family_data wl128x_data = { 196 .name = "wl128x", 197 .nvs_name = "ti-connectivity/wl128x-nvs.bin", 198 }; 199 200 static const struct wilink_family_data wl18xx_data = { 201 .name = "wl18xx", 202 .cfg_name = "ti-connectivity/wl18xx-conf.bin", 203 .nvs_name = "ti-connectivity/wl1271-nvs.bin", 204 }; 205 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 }, 218 { } 219 }; 220 221 static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq, 222 struct wlcore_platdev_data *pdev_data) 223 { 224 struct device_node *np = dev->of_node; 225 const struct of_device_id *of_id; 226 227 of_id = of_match_node(wlcore_sdio_of_match_table, np); 228 if (!of_id) 229 return -ENODEV; 230 231 pdev_data->family = of_id->data; 232 233 *irq = irq_of_parse_and_map(np, 0); 234 if (!*irq) { 235 dev_err(dev, "No irq in platform data\n"); 236 return -EINVAL; 237 } 238 239 *wakeirq = irq_of_parse_and_map(np, 1); 240 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); 246 247 return 0; 248 } 249 #else 250 static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq, 251 struct wlcore_platdev_data *pdev_data) 252 { 253 return -ENODATA; 254 } 255 #endif 256 257 static int wl1271_probe(struct sdio_func *func, 258 const struct sdio_device_id *id) 259 { 260 struct wlcore_platdev_data *pdev_data; 261 struct wl12xx_sdio_glue *glue; 262 struct resource res[2]; 263 mmc_pm_flag_t mmcflags; 264 int ret = -ENOMEM; 265 int irq, wakeirq, num_irqs; 266 const char *chip_family; 267 268 /* We are only able to handle the wlan function */ 269 if (func->num != 0x02) 270 return -ENODEV; 271 272 pdev_data = devm_kzalloc(&func->dev, sizeof(*pdev_data), GFP_KERNEL); 273 if (!pdev_data) 274 return -ENOMEM; 275 276 pdev_data->if_ops = &sdio_ops; 277 278 glue = devm_kzalloc(&func->dev, sizeof(*glue), GFP_KERNEL); 279 if (!glue) 280 return -ENOMEM; 281 282 glue->dev = &func->dev; 283 284 /* Grab access to FN0 for ELP reg. */ 285 func->card->quirks |= MMC_QUIRK_LENIENT_FN0; 286 287 /* Use block mode for transferring over one block size of data */ 288 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 289 290 ret = wlcore_probe_of(&func->dev, &irq, &wakeirq, pdev_data); 291 if (ret) 292 goto out; 293 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); 297 298 if (mmcflags & MMC_PM_KEEP_POWER) 299 pdev_data->pwr_in_suspend = true; 300 301 sdio_set_drvdata(func, glue); 302 303 /* Tell PM core that we don't need the card to be powered now */ 304 pm_runtime_put_noidle(&func->dev); 305 306 /* 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. 311 */ 312 if (func->card->cccr.sdio_vsn == SDIO_SDIO_REV_3_00) 313 chip_family = "wl18xx"; 314 else 315 chip_family = "wl12xx"; 316 317 glue->core = platform_device_alloc(chip_family, PLATFORM_DEVID_AUTO); 318 if (!glue->core) { 319 dev_err(glue->dev, "can't allocate platform_device"); 320 ret = -ENOMEM; 321 goto out; 322 } 323 324 glue->core->dev.parent = &func->dev; 325 326 memset(res, 0x00, sizeof(res)); 327 328 res[0].start = irq; 329 res[0].flags = IORESOURCE_IRQ | 330 irqd_get_trigger_type(irq_get_irq_data(irq)); 331 res[0].name = "irq"; 332 333 334 if (wakeirq > 0) { 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"; 339 num_irqs = 2; 340 } else { 341 num_irqs = 1; 342 } 343 ret = platform_device_add_resources(glue->core, res, num_irqs); 344 if (ret) { 345 dev_err(glue->dev, "can't add resources\n"); 346 goto out_dev_put; 347 } 348 349 ret = platform_device_add_data(glue->core, pdev_data, 350 sizeof(*pdev_data)); 351 if (ret) { 352 dev_err(glue->dev, "can't add platform data\n"); 353 goto out_dev_put; 354 } 355 356 ret = platform_device_add(glue->core); 357 if (ret) { 358 dev_err(glue->dev, "can't add platform device\n"); 359 goto out_dev_put; 360 } 361 return 0; 362 363 out_dev_put: 364 platform_device_put(glue->core); 365 366 out: 367 return ret; 368 } 369 370 static void wl1271_remove(struct sdio_func *func) 371 { 372 struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); 373 374 /* Undo decrement done above in wl1271_probe */ 375 pm_runtime_get_noresume(&func->dev); 376 377 platform_device_unregister(glue->core); 378 } 379 380 #ifdef CONFIG_PM 381 static int wl1271_suspend(struct device *dev) 382 { 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; 389 int ret = 0; 390 391 if (!wl) { 392 dev_err(dev, "no wilink module was probed\n"); 393 goto out; 394 } 395 396 dev_dbg(dev, "wl1271 suspend. wow_enabled: %d\n", 397 wl->wow_enabled); 398 399 /* check whether sdio should keep power */ 400 if (wl->wow_enabled) { 401 sdio_flags = sdio_get_host_pm_caps(func); 402 403 if (!(sdio_flags & MMC_PM_KEEP_POWER)) { 404 dev_err(dev, "can't keep power while host " 405 "is suspended\n"); 406 ret = -EINVAL; 407 goto out; 408 } 409 410 /* keep power while host suspended */ 411 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); 412 if (ret) { 413 dev_err(dev, "error while trying to keep power\n"); 414 goto out; 415 } 416 } 417 out: 418 return ret; 419 } 420 421 static int wl1271_resume(struct device *dev) 422 { 423 dev_dbg(dev, "wl1271 resume\n"); 424 425 return 0; 426 } 427 428 static const struct dev_pm_ops wl1271_sdio_pm_ops = { 429 .suspend = wl1271_suspend, 430 .resume = wl1271_resume, 431 }; 432 #endif 433 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, 439 #ifdef CONFIG_PM 440 .drv = { 441 .pm = &wl1271_sdio_pm_ops, 442 }, 443 #endif 444 }; 445 446 static int __init wl1271_init(void) 447 { 448 return sdio_register_driver(&wl1271_sdio_driver); 449 } 450 451 static void __exit wl1271_exit(void) 452 { 453 sdio_unregister_driver(&wl1271_sdio_driver); 454 } 455 456 module_init(wl1271_init); 457 module_exit(wl1271_exit); 458 459 module_param(dump, bool, 0600); 460 MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); 461 462 MODULE_LICENSE("GPL"); 463 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); 464 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 465