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