linux/drivers/net/wireless/ti/wl1251/spi.c
<<
>>
Prefs
   1/*
   2 * This file is part of wl1251
   3 *
   4 * Copyright (C) 2008 Nokia Corporation
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * version 2 as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  18 * 02110-1301 USA
  19 *
  20 */
  21
  22#include <linux/interrupt.h>
  23#include <linux/irq.h>
  24#include <linux/module.h>
  25#include <linux/slab.h>
  26#include <linux/swab.h>
  27#include <linux/crc7.h>
  28#include <linux/spi/spi.h>
  29#include <linux/wl12xx.h>
  30#include <linux/gpio.h>
  31#include <linux/of.h>
  32#include <linux/of_gpio.h>
  33#include <linux/regulator/consumer.h>
  34
  35#include "wl1251.h"
  36#include "reg.h"
  37#include "spi.h"
  38
  39static irqreturn_t wl1251_irq(int irq, void *cookie)
  40{
  41        struct wl1251 *wl;
  42
  43        wl1251_debug(DEBUG_IRQ, "IRQ");
  44
  45        wl = cookie;
  46
  47        ieee80211_queue_work(wl->hw, &wl->irq_work);
  48
  49        return IRQ_HANDLED;
  50}
  51
  52static struct spi_device *wl_to_spi(struct wl1251 *wl)
  53{
  54        return wl->if_priv;
  55}
  56
  57static void wl1251_spi_reset(struct wl1251 *wl)
  58{
  59        u8 *cmd;
  60        struct spi_transfer t;
  61        struct spi_message m;
  62
  63        cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
  64        if (!cmd) {
  65                wl1251_error("could not allocate cmd for spi reset");
  66                return;
  67        }
  68
  69        memset(&t, 0, sizeof(t));
  70        spi_message_init(&m);
  71
  72        memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
  73
  74        t.tx_buf = cmd;
  75        t.len = WSPI_INIT_CMD_LEN;
  76        spi_message_add_tail(&t, &m);
  77
  78        spi_sync(wl_to_spi(wl), &m);
  79
  80        wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
  81
  82        kfree(cmd);
  83}
  84
  85static void wl1251_spi_wake(struct wl1251 *wl)
  86{
  87        struct spi_transfer t;
  88        struct spi_message m;
  89        u8 *cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
  90
  91        if (!cmd) {
  92                wl1251_error("could not allocate cmd for spi init");
  93                return;
  94        }
  95
  96        memset(&t, 0, sizeof(t));
  97        spi_message_init(&m);
  98
  99        /* Set WSPI_INIT_COMMAND
 100         * the data is being send from the MSB to LSB
 101         */
 102        cmd[0] = 0xff;
 103        cmd[1] = 0xff;
 104        cmd[2] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
 105        cmd[3] = 0;
 106        cmd[4] = 0;
 107        cmd[5] = HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
 108        cmd[5] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
 109
 110        cmd[6] = WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
 111                | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
 112
 113        if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
 114                cmd[6] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
 115        else
 116                cmd[6] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
 117
 118        cmd[7] = crc7_be(0, cmd+2, WSPI_INIT_CMD_CRC_LEN) | WSPI_INIT_CMD_END;
 119        /*
 120         * The above is the logical order; it must actually be stored
 121         * in the buffer byte-swapped.
 122         */
 123        __swab32s((u32 *)cmd);
 124        __swab32s((u32 *)cmd+1);
 125
 126        t.tx_buf = cmd;
 127        t.len = WSPI_INIT_CMD_LEN;
 128        spi_message_add_tail(&t, &m);
 129
 130        spi_sync(wl_to_spi(wl), &m);
 131
 132        wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
 133
 134        kfree(cmd);
 135}
 136
 137static void wl1251_spi_reset_wake(struct wl1251 *wl)
 138{
 139        wl1251_spi_reset(wl);
 140        wl1251_spi_wake(wl);
 141}
 142
 143static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
 144                            size_t len)
 145{
 146        struct spi_transfer t[3];
 147        struct spi_message m;
 148        u8 *busy_buf;
 149        u32 *cmd;
 150
 151        cmd = &wl->buffer_cmd;
 152        busy_buf = wl->buffer_busyword;
 153
 154        *cmd = 0;
 155        *cmd |= WSPI_CMD_READ;
 156        *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
 157        *cmd |= addr & WSPI_CMD_BYTE_ADDR;
 158
 159        spi_message_init(&m);
 160        memset(t, 0, sizeof(t));
 161
 162        t[0].tx_buf = cmd;
 163        t[0].len = 4;
 164        spi_message_add_tail(&t[0], &m);
 165
 166        /* Busy and non busy words read */
 167        t[1].rx_buf = busy_buf;
 168        t[1].len = WL1251_BUSY_WORD_LEN;
 169        spi_message_add_tail(&t[1], &m);
 170
 171        t[2].rx_buf = buf;
 172        t[2].len = len;
 173        spi_message_add_tail(&t[2], &m);
 174
 175        spi_sync(wl_to_spi(wl), &m);
 176
 177        /* FIXME: check busy words */
 178
 179        wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
 180        wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
 181}
 182
 183static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
 184                             size_t len)
 185{
 186        struct spi_transfer t[2];
 187        struct spi_message m;
 188        u32 *cmd;
 189
 190        cmd = &wl->buffer_cmd;
 191
 192        *cmd = 0;
 193        *cmd |= WSPI_CMD_WRITE;
 194        *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
 195        *cmd |= addr & WSPI_CMD_BYTE_ADDR;
 196
 197        spi_message_init(&m);
 198        memset(t, 0, sizeof(t));
 199
 200        t[0].tx_buf = cmd;
 201        t[0].len = sizeof(*cmd);
 202        spi_message_add_tail(&t[0], &m);
 203
 204        t[1].tx_buf = buf;
 205        t[1].len = len;
 206        spi_message_add_tail(&t[1], &m);
 207
 208        spi_sync(wl_to_spi(wl), &m);
 209
 210        wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
 211        wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
 212}
 213
 214static void wl1251_spi_enable_irq(struct wl1251 *wl)
 215{
 216        return enable_irq(wl->irq);
 217}
 218
 219static void wl1251_spi_disable_irq(struct wl1251 *wl)
 220{
 221        return disable_irq(wl->irq);
 222}
 223
 224static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
 225{
 226        if (gpio_is_valid(wl->power_gpio))
 227                gpio_set_value(wl->power_gpio, enable);
 228
 229        return 0;
 230}
 231
 232static const struct wl1251_if_operations wl1251_spi_ops = {
 233        .read = wl1251_spi_read,
 234        .write = wl1251_spi_write,
 235        .reset = wl1251_spi_reset_wake,
 236        .enable_irq = wl1251_spi_enable_irq,
 237        .disable_irq = wl1251_spi_disable_irq,
 238        .power = wl1251_spi_set_power,
 239};
 240
 241static int wl1251_spi_probe(struct spi_device *spi)
 242{
 243        struct wl1251_platform_data *pdata = dev_get_platdata(&spi->dev);
 244        struct device_node *np = spi->dev.of_node;
 245        struct ieee80211_hw *hw;
 246        struct wl1251 *wl;
 247        int ret;
 248
 249        if (!np && !pdata) {
 250                wl1251_error("no platform data");
 251                return -ENODEV;
 252        }
 253
 254        hw = wl1251_alloc_hw();
 255        if (IS_ERR(hw))
 256                return PTR_ERR(hw);
 257
 258        wl = hw->priv;
 259
 260        SET_IEEE80211_DEV(hw, &spi->dev);
 261        spi_set_drvdata(spi, wl);
 262        wl->if_priv = spi;
 263        wl->if_ops = &wl1251_spi_ops;
 264
 265        /* This is the only SPI value that we need to set here, the rest
 266         * comes from the board-peripherals file
 267         */
 268        spi->bits_per_word = 32;
 269
 270        ret = spi_setup(spi);
 271        if (ret < 0) {
 272                wl1251_error("spi_setup failed");
 273                goto out_free;
 274        }
 275
 276        if (np) {
 277                wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom");
 278                wl->power_gpio = of_get_named_gpio(np, "ti,power-gpio", 0);
 279        } else if (pdata) {
 280                wl->power_gpio = pdata->power_gpio;
 281                wl->use_eeprom = pdata->use_eeprom;
 282        }
 283
 284        if (wl->power_gpio == -EPROBE_DEFER) {
 285                ret = -EPROBE_DEFER;
 286                goto out_free;
 287        }
 288
 289        if (gpio_is_valid(wl->power_gpio)) {
 290                ret = devm_gpio_request_one(&spi->dev, wl->power_gpio,
 291                                        GPIOF_OUT_INIT_LOW, "wl1251 power");
 292                if (ret) {
 293                        wl1251_error("Failed to request gpio: %d\n", ret);
 294                        goto out_free;
 295                }
 296        } else {
 297                wl1251_error("set power gpio missing in platform data");
 298                ret = -ENODEV;
 299                goto out_free;
 300        }
 301
 302        wl->irq = spi->irq;
 303        if (wl->irq < 0) {
 304                wl1251_error("irq missing in platform data");
 305                ret = -ENODEV;
 306                goto out_free;
 307        }
 308
 309        irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
 310        ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0,
 311                                                        DRIVER_NAME, wl);
 312        if (ret < 0) {
 313                wl1251_error("request_irq() failed: %d", ret);
 314                goto out_free;
 315        }
 316
 317        irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
 318
 319        wl->vio = devm_regulator_get(&spi->dev, "vio");
 320        if (IS_ERR(wl->vio)) {
 321                ret = PTR_ERR(wl->vio);
 322                wl1251_error("vio regulator missing: %d", ret);
 323                goto out_free;
 324        }
 325
 326        ret = regulator_enable(wl->vio);
 327        if (ret)
 328                goto out_free;
 329
 330        ret = wl1251_init_ieee80211(wl);
 331        if (ret)
 332                goto disable_regulator;
 333
 334        return 0;
 335
 336disable_regulator:
 337        regulator_disable(wl->vio);
 338out_free:
 339        ieee80211_free_hw(hw);
 340
 341        return ret;
 342}
 343
 344static int wl1251_spi_remove(struct spi_device *spi)
 345{
 346        struct wl1251 *wl = spi_get_drvdata(spi);
 347
 348        wl1251_free_hw(wl);
 349        regulator_disable(wl->vio);
 350
 351        return 0;
 352}
 353
 354static struct spi_driver wl1251_spi_driver = {
 355        .driver = {
 356                .name           = DRIVER_NAME,
 357                .owner          = THIS_MODULE,
 358        },
 359
 360        .probe          = wl1251_spi_probe,
 361        .remove         = wl1251_spi_remove,
 362};
 363
 364module_spi_driver(wl1251_spi_driver);
 365
 366MODULE_LICENSE("GPL");
 367MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
 368MODULE_ALIAS("spi:wl1251");
 369