linux/drivers/net/wireless/ti/wl1251/sdio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * wl12xx SDIO routines
   4 *
   5 * Copyright (C) 2005 Texas Instruments Incorporated
   6 * Copyright (C) 2008 Google Inc
   7 * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
   8 */
   9#include <linux/interrupt.h>
  10#include <linux/module.h>
  11#include <linux/mod_devicetable.h>
  12#include <linux/mmc/sdio_func.h>
  13#include <linux/mmc/sdio_ids.h>
  14#include <linux/platform_device.h>
  15#include <linux/wl12xx.h>
  16#include <linux/irq.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/gpio.h>
  19
  20#include "wl1251.h"
  21
  22#ifndef SDIO_VENDOR_ID_TI
  23#define SDIO_VENDOR_ID_TI               0x104c
  24#endif
  25
  26#ifndef SDIO_DEVICE_ID_TI_WL1251
  27#define SDIO_DEVICE_ID_TI_WL1251        0x9066
  28#endif
  29
  30struct wl1251_sdio {
  31        struct sdio_func *func;
  32        u32 elp_val;
  33};
  34
  35static struct sdio_func *wl_to_func(struct wl1251 *wl)
  36{
  37        struct wl1251_sdio *wl_sdio = wl->if_priv;
  38        return wl_sdio->func;
  39}
  40
  41static void wl1251_sdio_interrupt(struct sdio_func *func)
  42{
  43        struct wl1251 *wl = sdio_get_drvdata(func);
  44
  45        wl1251_debug(DEBUG_IRQ, "IRQ");
  46
  47        /* FIXME should be synchronous for sdio */
  48        ieee80211_queue_work(wl->hw, &wl->irq_work);
  49}
  50
  51static const struct sdio_device_id wl1251_devices[] = {
  52        { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) },
  53        {}
  54};
  55MODULE_DEVICE_TABLE(sdio, wl1251_devices);
  56
  57
  58static void wl1251_sdio_read(struct wl1251 *wl, int addr,
  59                             void *buf, size_t len)
  60{
  61        int ret;
  62        struct sdio_func *func = wl_to_func(wl);
  63
  64        sdio_claim_host(func);
  65        ret = sdio_memcpy_fromio(func, buf, addr, len);
  66        if (ret)
  67                wl1251_error("sdio read failed (%d)", ret);
  68        sdio_release_host(func);
  69}
  70
  71static void wl1251_sdio_write(struct wl1251 *wl, int addr,
  72                              void *buf, size_t len)
  73{
  74        int ret;
  75        struct sdio_func *func = wl_to_func(wl);
  76
  77        sdio_claim_host(func);
  78        ret = sdio_memcpy_toio(func, addr, buf, len);
  79        if (ret)
  80                wl1251_error("sdio write failed (%d)", ret);
  81        sdio_release_host(func);
  82}
  83
  84static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
  85{
  86        int ret = 0;
  87        struct wl1251_sdio *wl_sdio = wl->if_priv;
  88        struct sdio_func *func = wl_sdio->func;
  89
  90        /*
  91         * The hardware only supports RAW (read after write) access for
  92         * reading, regular sdio_readb won't work here (it interprets
  93         * the unused bits of CMD52 as write data even if we send read
  94         * request).
  95         */
  96        sdio_claim_host(func);
  97        *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret);
  98        sdio_release_host(func);
  99
 100        if (ret)
 101                wl1251_error("sdio_readb failed (%d)", ret);
 102}
 103
 104static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
 105{
 106        int ret = 0;
 107        struct wl1251_sdio *wl_sdio = wl->if_priv;
 108        struct sdio_func *func = wl_sdio->func;
 109
 110        sdio_claim_host(func);
 111        sdio_writeb(func, val, addr, &ret);
 112        sdio_release_host(func);
 113
 114        if (ret)
 115                wl1251_error("sdio_writeb failed (%d)", ret);
 116        else
 117                wl_sdio->elp_val = val;
 118}
 119
 120static void wl1251_sdio_reset(struct wl1251 *wl)
 121{
 122}
 123
 124static void wl1251_sdio_enable_irq(struct wl1251 *wl)
 125{
 126        struct sdio_func *func = wl_to_func(wl);
 127
 128        sdio_claim_host(func);
 129        sdio_claim_irq(func, wl1251_sdio_interrupt);
 130        sdio_release_host(func);
 131}
 132
 133static void wl1251_sdio_disable_irq(struct wl1251 *wl)
 134{
 135        struct sdio_func *func = wl_to_func(wl);
 136
 137        sdio_claim_host(func);
 138        sdio_release_irq(func);
 139        sdio_release_host(func);
 140}
 141
 142/* Interrupts when using dedicated WLAN_IRQ pin */
 143static irqreturn_t wl1251_line_irq(int irq, void *cookie)
 144{
 145        struct wl1251 *wl = cookie;
 146
 147        ieee80211_queue_work(wl->hw, &wl->irq_work);
 148
 149        return IRQ_HANDLED;
 150}
 151
 152static void wl1251_enable_line_irq(struct wl1251 *wl)
 153{
 154        return enable_irq(wl->irq);
 155}
 156
 157static void wl1251_disable_line_irq(struct wl1251 *wl)
 158{
 159        return disable_irq(wl->irq);
 160}
 161
 162static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
 163{
 164        struct sdio_func *func = wl_to_func(wl);
 165        int ret;
 166
 167        if (enable) {
 168                /*
 169                 * Power is controlled by runtime PM, but we still call board
 170                 * callback in case it wants to do any additional setup,
 171                 * for example enabling clock buffer for the module.
 172                 */
 173                if (gpio_is_valid(wl->power_gpio))
 174                        gpio_set_value(wl->power_gpio, true);
 175
 176
 177                ret = pm_runtime_get_sync(&func->dev);
 178                if (ret < 0) {
 179                        pm_runtime_put_sync(&func->dev);
 180                        goto out;
 181                }
 182
 183                sdio_claim_host(func);
 184                sdio_enable_func(func);
 185                sdio_release_host(func);
 186        } else {
 187                sdio_claim_host(func);
 188                sdio_disable_func(func);
 189                sdio_release_host(func);
 190
 191                ret = pm_runtime_put_sync(&func->dev);
 192                if (ret < 0)
 193                        goto out;
 194
 195                if (gpio_is_valid(wl->power_gpio))
 196                        gpio_set_value(wl->power_gpio, false);
 197        }
 198
 199out:
 200        return ret;
 201}
 202
 203static struct wl1251_if_operations wl1251_sdio_ops = {
 204        .read = wl1251_sdio_read,
 205        .write = wl1251_sdio_write,
 206        .write_elp = wl1251_sdio_write_elp,
 207        .read_elp = wl1251_sdio_read_elp,
 208        .reset = wl1251_sdio_reset,
 209        .power = wl1251_sdio_set_power,
 210};
 211
 212static int wl1251_sdio_probe(struct sdio_func *func,
 213                             const struct sdio_device_id *id)
 214{
 215        int ret;
 216        struct wl1251 *wl;
 217        struct ieee80211_hw *hw;
 218        struct wl1251_sdio *wl_sdio;
 219        const struct wl1251_platform_data *wl1251_board_data;
 220
 221        hw = wl1251_alloc_hw();
 222        if (IS_ERR(hw))
 223                return PTR_ERR(hw);
 224
 225        wl = hw->priv;
 226
 227        wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL);
 228        if (wl_sdio == NULL) {
 229                ret = -ENOMEM;
 230                goto out_free_hw;
 231        }
 232
 233        sdio_claim_host(func);
 234        ret = sdio_enable_func(func);
 235        if (ret)
 236                goto release;
 237
 238        sdio_set_block_size(func, 512);
 239        sdio_release_host(func);
 240
 241        SET_IEEE80211_DEV(hw, &func->dev);
 242        wl_sdio->func = func;
 243        wl->if_priv = wl_sdio;
 244        wl->if_ops = &wl1251_sdio_ops;
 245
 246        wl1251_board_data = wl1251_get_platform_data();
 247        if (!IS_ERR(wl1251_board_data)) {
 248                wl->power_gpio = wl1251_board_data->power_gpio;
 249                wl->irq = wl1251_board_data->irq;
 250                wl->use_eeprom = wl1251_board_data->use_eeprom;
 251        }
 252
 253        if (gpio_is_valid(wl->power_gpio)) {
 254                ret = devm_gpio_request(&func->dev, wl->power_gpio,
 255                                                                "wl1251 power");
 256                if (ret) {
 257                        wl1251_error("Failed to request gpio: %d\n", ret);
 258                        goto disable;
 259                }
 260        }
 261
 262        if (wl->irq) {
 263                irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
 264                ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
 265                if (ret < 0) {
 266                        wl1251_error("request_irq() failed: %d", ret);
 267                        goto disable;
 268                }
 269
 270                irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
 271
 272                wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
 273                wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
 274
 275                wl1251_info("using dedicated interrupt line");
 276        } else {
 277                wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
 278                wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
 279
 280                wl1251_info("using SDIO interrupt");
 281        }
 282
 283        ret = wl1251_init_ieee80211(wl);
 284        if (ret)
 285                goto out_free_irq;
 286
 287        sdio_set_drvdata(func, wl);
 288
 289        /* Tell PM core that we don't need the card to be powered now */
 290        pm_runtime_put_noidle(&func->dev);
 291
 292        return ret;
 293
 294out_free_irq:
 295        if (wl->irq)
 296                free_irq(wl->irq, wl);
 297disable:
 298        sdio_claim_host(func);
 299        sdio_disable_func(func);
 300release:
 301        sdio_release_host(func);
 302        kfree(wl_sdio);
 303out_free_hw:
 304        wl1251_free_hw(wl);
 305        return ret;
 306}
 307
 308static void wl1251_sdio_remove(struct sdio_func *func)
 309{
 310        struct wl1251 *wl = sdio_get_drvdata(func);
 311        struct wl1251_sdio *wl_sdio = wl->if_priv;
 312
 313        /* Undo decrement done above in wl1251_probe */
 314        pm_runtime_get_noresume(&func->dev);
 315
 316        if (wl->irq)
 317                free_irq(wl->irq, wl);
 318        wl1251_free_hw(wl);
 319        kfree(wl_sdio);
 320
 321        sdio_claim_host(func);
 322        sdio_release_irq(func);
 323        sdio_disable_func(func);
 324        sdio_release_host(func);
 325}
 326
 327static int wl1251_suspend(struct device *dev)
 328{
 329        /*
 330         * Tell MMC/SDIO core it's OK to power down the card
 331         * (if it isn't already), but not to remove it completely.
 332         */
 333        return 0;
 334}
 335
 336static int wl1251_resume(struct device *dev)
 337{
 338        return 0;
 339}
 340
 341static const struct dev_pm_ops wl1251_sdio_pm_ops = {
 342        .suspend        = wl1251_suspend,
 343        .resume         = wl1251_resume,
 344};
 345
 346static struct sdio_driver wl1251_sdio_driver = {
 347        .name           = "wl1251_sdio",
 348        .id_table       = wl1251_devices,
 349        .probe          = wl1251_sdio_probe,
 350        .remove         = wl1251_sdio_remove,
 351        .drv.pm         = &wl1251_sdio_pm_ops,
 352};
 353
 354static int __init wl1251_sdio_init(void)
 355{
 356        int err;
 357
 358        err = sdio_register_driver(&wl1251_sdio_driver);
 359        if (err)
 360                wl1251_error("failed to register sdio driver: %d", err);
 361        return err;
 362}
 363
 364static void __exit wl1251_sdio_exit(void)
 365{
 366        sdio_unregister_driver(&wl1251_sdio_driver);
 367        wl1251_notice("unloaded");
 368}
 369
 370module_init(wl1251_sdio_init);
 371module_exit(wl1251_sdio_exit);
 372
 373MODULE_LICENSE("GPL");
 374MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
 375