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 = "sdd_sagrad_1091_1098.bin", 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); 424