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