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 #ifndef SDIO_VENDOR_ID_TI 30 #define SDIO_VENDOR_ID_TI 0x0097 31 #endif 32 33 #ifndef SDIO_DEVICE_ID_TI_WL1271 34 #define SDIO_DEVICE_ID_TI_WL1271 0x4076 35 #endif 36 37 static bool dump = false; 38 39 struct wl12xx_sdio_glue { 40 struct device *dev; 41 struct platform_device *core; 42 }; 43 44 static const struct sdio_device_id wl1271_devices[] = { 45 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, 46 {} 47 }; 48 MODULE_DEVICE_TABLE(sdio, wl1271_devices); 49 50 static void wl1271_sdio_set_block_size(struct device *child, 51 unsigned int blksz) 52 { 53 struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); 54 struct sdio_func *func = dev_to_sdio_func(glue->dev); 55 56 sdio_claim_host(func); 57 sdio_set_block_size(func, blksz); 58 sdio_release_host(func); 59 } 60 61 static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr, 62 void *buf, size_t len, bool fixed) 63 { 64 int ret; 65 struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); 66 struct sdio_func *func = dev_to_sdio_func(glue->dev); 67 68 sdio_claim_host(func); 69 70 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { 71 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); 72 dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n", 73 addr, ((u8 *)buf)[0]); 74 } else { 75 if (fixed) 76 ret = sdio_readsb(func, buf, addr, len); 77 else 78 ret = sdio_memcpy_fromio(func, buf, addr, len); 79 80 dev_dbg(child->parent, "sdio read 53 addr 0x%x, %zu bytes\n", 81 addr, len); 82 } 83 84 sdio_release_host(func); 85 86 if (WARN_ON(ret)) 87 dev_err(child->parent, "sdio read failed (%d)\n", ret); 88 89 if (unlikely(dump)) { 90 printk(KERN_DEBUG "wlcore_sdio: READ from 0x%04x\n", addr); 91 print_hex_dump(KERN_DEBUG, "wlcore_sdio: READ ", 92 DUMP_PREFIX_OFFSET, 16, 1, 93 buf, len, false); 94 } 95 96 return ret; 97 } 98 99 static int __must_check wl12xx_sdio_raw_write(struct device *child, int addr, 100 void *buf, size_t len, bool fixed) 101 { 102 int ret; 103 struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); 104 struct sdio_func *func = dev_to_sdio_func(glue->dev); 105 106 sdio_claim_host(func); 107 108 if (unlikely(dump)) { 109 printk(KERN_DEBUG "wlcore_sdio: WRITE to 0x%04x\n", addr); 110 print_hex_dump(KERN_DEBUG, "wlcore_sdio: WRITE ", 111 DUMP_PREFIX_OFFSET, 16, 1, 112 buf, len, false); 113 } 114 115 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { 116 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); 117 dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n", 118 addr, ((u8 *)buf)[0]); 119 } else { 120 dev_dbg(child->parent, "sdio write 53 addr 0x%x, %zu bytes\n", 121 addr, len); 122 123 if (fixed) 124 ret = sdio_writesb(func, addr, buf, len); 125 else 126 ret = sdio_memcpy_toio(func, addr, buf, len); 127 } 128 129 sdio_release_host(func); 130 131 if (WARN_ON(ret)) 132 dev_err(child->parent, "sdio write failed (%d)\n", ret); 133 134 return ret; 135 } 136 137 static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) 138 { 139 int ret; 140 struct sdio_func *func = dev_to_sdio_func(glue->dev); 141 struct mmc_card *card = func->card; 142 143 ret = pm_runtime_get_sync(&card->dev); 144 if (ret < 0) { 145 pm_runtime_put_noidle(&card->dev); 146 dev_err(glue->dev, "%s: failed to get_sync(%d)\n", 147 __func__, ret); 148 149 return ret; 150 } 151 152 sdio_claim_host(func); 153 /* 154 * To guarantee that the SDIO card is power cycled, as required to make 155 * the FW programming to succeed, let's do a brute force HW reset. 156 */ 157 mmc_hw_reset(card->host); 158 159 sdio_enable_func(func); 160 sdio_release_host(func); 161 162 return 0; 163 } 164 165 static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) 166 { 167 struct sdio_func *func = dev_to_sdio_func(glue->dev); 168 struct mmc_card *card = func->card; 169 170 sdio_claim_host(func); 171 sdio_disable_func(func); 172 sdio_release_host(func); 173 174 /* Let runtime PM know the card is powered off */ 175 pm_runtime_put(&card->dev); 176 return 0; 177 } 178 179 static int wl12xx_sdio_set_power(struct device *child, bool enable) 180 { 181 struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); 182 183 if (enable) 184 return wl12xx_sdio_power_on(glue); 185 else 186 return wl12xx_sdio_power_off(glue); 187 } 188 189 static struct wl1271_if_operations sdio_ops = { 190 .read = wl12xx_sdio_raw_read, 191 .write = wl12xx_sdio_raw_write, 192 .power = wl12xx_sdio_set_power, 193 .set_block_size = wl1271_sdio_set_block_size, 194 }; 195 196 #ifdef CONFIG_OF 197 198 static const struct wilink_family_data wl127x_data = { 199 .name = "wl127x", 200 .nvs_name = "ti-connectivity/wl127x-nvs.bin", 201 }; 202 203 static const struct wilink_family_data wl128x_data = { 204 .name = "wl128x", 205 .nvs_name = "ti-connectivity/wl128x-nvs.bin", 206 }; 207 208 static const struct wilink_family_data wl18xx_data = { 209 .name = "wl18xx", 210 .cfg_name = "ti-connectivity/wl18xx-conf.bin", 211 .nvs_name = "ti-connectivity/wl1271-nvs.bin", 212 }; 213 214 static const struct of_device_id wlcore_sdio_of_match_table[] = { 215 { .compatible = "ti,wl1271", .data = &wl127x_data }, 216 { .compatible = "ti,wl1273", .data = &wl127x_data }, 217 { .compatible = "ti,wl1281", .data = &wl128x_data }, 218 { .compatible = "ti,wl1283", .data = &wl128x_data }, 219 { .compatible = "ti,wl1285", .data = &wl128x_data }, 220 { .compatible = "ti,wl1801", .data = &wl18xx_data }, 221 { .compatible = "ti,wl1805", .data = &wl18xx_data }, 222 { .compatible = "ti,wl1807", .data = &wl18xx_data }, 223 { .compatible = "ti,wl1831", .data = &wl18xx_data }, 224 { .compatible = "ti,wl1835", .data = &wl18xx_data }, 225 { .compatible = "ti,wl1837", .data = &wl18xx_data }, 226 { } 227 }; 228 229 static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq, 230 struct wlcore_platdev_data *pdev_data) 231 { 232 struct device_node *np = dev->of_node; 233 const struct of_device_id *of_id; 234 235 of_id = of_match_node(wlcore_sdio_of_match_table, np); 236 if (!of_id) 237 return -ENODEV; 238 239 pdev_data->family = of_id->data; 240 241 *irq = irq_of_parse_and_map(np, 0); 242 if (!*irq) { 243 dev_err(dev, "No irq in platform data\n"); 244 return -EINVAL; 245 } 246 247 *wakeirq = irq_of_parse_and_map(np, 1); 248 249 /* optional clock frequency params */ 250 of_property_read_u32(np, "ref-clock-frequency", 251 &pdev_data->ref_clock_freq); 252 of_property_read_u32(np, "tcxo-clock-frequency", 253 &pdev_data->tcxo_clock_freq); 254 255 return 0; 256 } 257 #else 258 static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq, 259 struct wlcore_platdev_data *pdev_data) 260 { 261 return -ENODATA; 262 } 263 #endif 264 265 static int wl1271_probe(struct sdio_func *func, 266 const struct sdio_device_id *id) 267 { 268 struct wlcore_platdev_data *pdev_data; 269 struct wl12xx_sdio_glue *glue; 270 struct resource res[2]; 271 mmc_pm_flag_t mmcflags; 272 int ret = -ENOMEM; 273 int irq, wakeirq, num_irqs; 274 const char *chip_family; 275 276 /* We are only able to handle the wlan function */ 277 if (func->num != 0x02) 278 return -ENODEV; 279 280 pdev_data = devm_kzalloc(&func->dev, sizeof(*pdev_data), GFP_KERNEL); 281 if (!pdev_data) 282 return -ENOMEM; 283 284 pdev_data->if_ops = &sdio_ops; 285 286 glue = devm_kzalloc(&func->dev, sizeof(*glue), GFP_KERNEL); 287 if (!glue) 288 return -ENOMEM; 289 290 glue->dev = &func->dev; 291 292 /* Grab access to FN0 for ELP reg. */ 293 func->card->quirks |= MMC_QUIRK_LENIENT_FN0; 294 295 /* Use block mode for transferring over one block size of data */ 296 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 297 298 ret = wlcore_probe_of(&func->dev, &irq, &wakeirq, pdev_data); 299 if (ret) 300 goto out; 301 302 /* if sdio can keep power while host is suspended, enable wow */ 303 mmcflags = sdio_get_host_pm_caps(func); 304 dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags); 305 306 if (mmcflags & MMC_PM_KEEP_POWER) 307 pdev_data->pwr_in_suspend = true; 308 309 sdio_set_drvdata(func, glue); 310 311 /* Tell PM core that we don't need the card to be powered now */ 312 pm_runtime_put_noidle(&func->dev); 313 314 /* 315 * Due to a hardware bug, we can't differentiate wl18xx from 316 * wl12xx, because both report the same device ID. The only 317 * way to differentiate is by checking the SDIO revision, 318 * which is 3.00 on the wl18xx chips. 319 */ 320 if (func->card->cccr.sdio_vsn == SDIO_SDIO_REV_3_00) 321 chip_family = "wl18xx"; 322 else 323 chip_family = "wl12xx"; 324 325 glue->core = platform_device_alloc(chip_family, PLATFORM_DEVID_AUTO); 326 if (!glue->core) { 327 dev_err(glue->dev, "can't allocate platform_device"); 328 ret = -ENOMEM; 329 goto out; 330 } 331 332 glue->core->dev.parent = &func->dev; 333 334 memset(res, 0x00, sizeof(res)); 335 336 res[0].start = irq; 337 res[0].flags = IORESOURCE_IRQ | 338 irqd_get_trigger_type(irq_get_irq_data(irq)); 339 res[0].name = "irq"; 340 341 342 if (wakeirq > 0) { 343 res[1].start = wakeirq; 344 res[1].flags = IORESOURCE_IRQ | 345 irqd_get_trigger_type(irq_get_irq_data(wakeirq)); 346 res[1].name = "wakeirq"; 347 num_irqs = 2; 348 } else { 349 num_irqs = 1; 350 } 351 ret = platform_device_add_resources(glue->core, res, num_irqs); 352 if (ret) { 353 dev_err(glue->dev, "can't add resources\n"); 354 goto out_dev_put; 355 } 356 357 ret = platform_device_add_data(glue->core, pdev_data, 358 sizeof(*pdev_data)); 359 if (ret) { 360 dev_err(glue->dev, "can't add platform data\n"); 361 goto out_dev_put; 362 } 363 364 ret = platform_device_add(glue->core); 365 if (ret) { 366 dev_err(glue->dev, "can't add platform device\n"); 367 goto out_dev_put; 368 } 369 return 0; 370 371 out_dev_put: 372 platform_device_put(glue->core); 373 374 out: 375 return ret; 376 } 377 378 static void wl1271_remove(struct sdio_func *func) 379 { 380 struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); 381 382 /* Undo decrement done above in wl1271_probe */ 383 pm_runtime_get_noresume(&func->dev); 384 385 platform_device_unregister(glue->core); 386 } 387 388 #ifdef CONFIG_PM 389 static int wl1271_suspend(struct device *dev) 390 { 391 /* Tell MMC/SDIO core it's OK to power down the card 392 * (if it isn't already), but not to remove it completely */ 393 struct sdio_func *func = dev_to_sdio_func(dev); 394 struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); 395 struct wl1271 *wl = platform_get_drvdata(glue->core); 396 mmc_pm_flag_t sdio_flags; 397 int ret = 0; 398 399 if (!wl) { 400 dev_err(dev, "no wilink module was probed\n"); 401 goto out; 402 } 403 404 dev_dbg(dev, "wl1271 suspend. wow_enabled: %d\n", 405 wl->wow_enabled); 406 407 /* check whether sdio should keep power */ 408 if (wl->wow_enabled) { 409 sdio_flags = sdio_get_host_pm_caps(func); 410 411 if (!(sdio_flags & MMC_PM_KEEP_POWER)) { 412 dev_err(dev, "can't keep power while host " 413 "is suspended\n"); 414 ret = -EINVAL; 415 goto out; 416 } 417 418 /* keep power while host suspended */ 419 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); 420 if (ret) { 421 dev_err(dev, "error while trying to keep power\n"); 422 goto out; 423 } 424 } 425 out: 426 return ret; 427 } 428 429 static int wl1271_resume(struct device *dev) 430 { 431 dev_dbg(dev, "wl1271 resume\n"); 432 433 return 0; 434 } 435 436 static const struct dev_pm_ops wl1271_sdio_pm_ops = { 437 .suspend = wl1271_suspend, 438 .resume = wl1271_resume, 439 }; 440 #endif 441 442 static struct sdio_driver wl1271_sdio_driver = { 443 .name = "wl1271_sdio", 444 .id_table = wl1271_devices, 445 .probe = wl1271_probe, 446 .remove = wl1271_remove, 447 #ifdef CONFIG_PM 448 .drv = { 449 .pm = &wl1271_sdio_pm_ops, 450 }, 451 #endif 452 }; 453 454 static int __init wl1271_init(void) 455 { 456 return sdio_register_driver(&wl1271_sdio_driver); 457 } 458 459 static void __exit wl1271_exit(void) 460 { 461 sdio_unregister_driver(&wl1271_sdio_driver); 462 } 463 464 module_init(wl1271_init); 465 module_exit(wl1271_exit); 466 467 module_param(dump, bool, 0600); 468 MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); 469 470 MODULE_LICENSE("GPL"); 471 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); 472 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 473