linux/drivers/net/ieee802154/cc2520.c
<<
>>
Prefs
   1/* Driver for TI CC2520 802.15.4 Wireless-PAN Networking controller
   2 *
   3 * Copyright (C) 2014 Varka Bhadram <varkab@cdac.in>
   4 *                    Md.Jamal Mohiuddin <mjmohiuddin@cdac.in>
   5 *                    P Sowjanya <sowjanyap@cdac.in>
   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 as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 */
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/gpio.h>
  16#include <linux/delay.h>
  17#include <linux/spi/spi.h>
  18#include <linux/spi/cc2520.h>
  19#include <linux/workqueue.h>
  20#include <linux/interrupt.h>
  21#include <linux/skbuff.h>
  22#include <linux/pinctrl/consumer.h>
  23#include <linux/of_gpio.h>
  24#include <linux/ieee802154.h>
  25
  26#include <net/mac802154.h>
  27#include <net/cfg802154.h>
  28
  29#define SPI_COMMAND_BUFFER      3
  30#define HIGH                    1
  31#define LOW                     0
  32#define STATE_IDLE              0
  33#define RSSI_VALID              0
  34#define RSSI_OFFSET             78
  35
  36#define CC2520_RAM_SIZE         640
  37#define CC2520_FIFO_SIZE        128
  38
  39#define CC2520RAM_TXFIFO        0x100
  40#define CC2520RAM_RXFIFO        0x180
  41#define CC2520RAM_IEEEADDR      0x3EA
  42#define CC2520RAM_PANID         0x3F2
  43#define CC2520RAM_SHORTADDR     0x3F4
  44
  45#define CC2520_FREG_MASK        0x3F
  46
  47/* status byte values */
  48#define CC2520_STATUS_XOSC32M_STABLE    (1 << 7)
  49#define CC2520_STATUS_RSSI_VALID        (1 << 6)
  50#define CC2520_STATUS_TX_UNDERFLOW      (1 << 3)
  51
  52/* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
  53#define CC2520_MINCHANNEL               11
  54#define CC2520_MAXCHANNEL               26
  55#define CC2520_CHANNEL_SPACING          5
  56
  57/* command strobes */
  58#define CC2520_CMD_SNOP                 0x00
  59#define CC2520_CMD_IBUFLD               0x02
  60#define CC2520_CMD_SIBUFEX              0x03
  61#define CC2520_CMD_SSAMPLECCA           0x04
  62#define CC2520_CMD_SRES                 0x0f
  63#define CC2520_CMD_MEMORY_MASK          0x0f
  64#define CC2520_CMD_MEMORY_READ          0x10
  65#define CC2520_CMD_MEMORY_WRITE         0x20
  66#define CC2520_CMD_RXBUF                0x30
  67#define CC2520_CMD_RXBUFCP              0x38
  68#define CC2520_CMD_RXBUFMOV             0x32
  69#define CC2520_CMD_TXBUF                0x3A
  70#define CC2520_CMD_TXBUFCP              0x3E
  71#define CC2520_CMD_RANDOM               0x3C
  72#define CC2520_CMD_SXOSCON              0x40
  73#define CC2520_CMD_STXCAL               0x41
  74#define CC2520_CMD_SRXON                0x42
  75#define CC2520_CMD_STXON                0x43
  76#define CC2520_CMD_STXONCCA             0x44
  77#define CC2520_CMD_SRFOFF               0x45
  78#define CC2520_CMD_SXOSCOFF             0x46
  79#define CC2520_CMD_SFLUSHRX             0x47
  80#define CC2520_CMD_SFLUSHTX             0x48
  81#define CC2520_CMD_SACK                 0x49
  82#define CC2520_CMD_SACKPEND             0x4A
  83#define CC2520_CMD_SNACK                0x4B
  84#define CC2520_CMD_SRXMASKBITSET        0x4C
  85#define CC2520_CMD_SRXMASKBITCLR        0x4D
  86#define CC2520_CMD_RXMASKAND            0x4E
  87#define CC2520_CMD_RXMASKOR             0x4F
  88#define CC2520_CMD_MEMCP                0x50
  89#define CC2520_CMD_MEMCPR               0x52
  90#define CC2520_CMD_MEMXCP               0x54
  91#define CC2520_CMD_MEMXWR               0x56
  92#define CC2520_CMD_BCLR                 0x58
  93#define CC2520_CMD_BSET                 0x59
  94#define CC2520_CMD_CTR_UCTR             0x60
  95#define CC2520_CMD_CBCMAC               0x64
  96#define CC2520_CMD_UCBCMAC              0x66
  97#define CC2520_CMD_CCM                  0x68
  98#define CC2520_CMD_UCCM                 0x6A
  99#define CC2520_CMD_ECB                  0x70
 100#define CC2520_CMD_ECBO                 0x72
 101#define CC2520_CMD_ECBX                 0x74
 102#define CC2520_CMD_INC                  0x78
 103#define CC2520_CMD_ABORT                0x7F
 104#define CC2520_CMD_REGISTER_READ        0x80
 105#define CC2520_CMD_REGISTER_WRITE       0xC0
 106
 107/* status registers */
 108#define CC2520_CHIPID                   0x40
 109#define CC2520_VERSION                  0x42
 110#define CC2520_EXTCLOCK                 0x44
 111#define CC2520_MDMCTRL0                 0x46
 112#define CC2520_MDMCTRL1                 0x47
 113#define CC2520_FREQEST                  0x48
 114#define CC2520_RXCTRL                   0x4A
 115#define CC2520_FSCTRL                   0x4C
 116#define CC2520_FSCAL0                   0x4E
 117#define CC2520_FSCAL1                   0x4F
 118#define CC2520_FSCAL2                   0x50
 119#define CC2520_FSCAL3                   0x51
 120#define CC2520_AGCCTRL0                 0x52
 121#define CC2520_AGCCTRL1                 0x53
 122#define CC2520_AGCCTRL2                 0x54
 123#define CC2520_AGCCTRL3                 0x55
 124#define CC2520_ADCTEST0                 0x56
 125#define CC2520_ADCTEST1                 0x57
 126#define CC2520_ADCTEST2                 0x58
 127#define CC2520_MDMTEST0                 0x5A
 128#define CC2520_MDMTEST1                 0x5B
 129#define CC2520_DACTEST0                 0x5C
 130#define CC2520_DACTEST1                 0x5D
 131#define CC2520_ATEST                    0x5E
 132#define CC2520_DACTEST2                 0x5F
 133#define CC2520_PTEST0                   0x60
 134#define CC2520_PTEST1                   0x61
 135#define CC2520_RESERVED                 0x62
 136#define CC2520_DPUBIST                  0x7A
 137#define CC2520_ACTBIST                  0x7C
 138#define CC2520_RAMBIST                  0x7E
 139
 140/* frame registers */
 141#define CC2520_FRMFILT0                 0x00
 142#define CC2520_FRMFILT1                 0x01
 143#define CC2520_SRCMATCH                 0x02
 144#define CC2520_SRCSHORTEN0              0x04
 145#define CC2520_SRCSHORTEN1              0x05
 146#define CC2520_SRCSHORTEN2              0x06
 147#define CC2520_SRCEXTEN0                0x08
 148#define CC2520_SRCEXTEN1                0x09
 149#define CC2520_SRCEXTEN2                0x0A
 150#define CC2520_FRMCTRL0                 0x0C
 151#define CC2520_FRMCTRL1                 0x0D
 152#define CC2520_RXENABLE0                0x0E
 153#define CC2520_RXENABLE1                0x0F
 154#define CC2520_EXCFLAG0                 0x10
 155#define CC2520_EXCFLAG1                 0x11
 156#define CC2520_EXCFLAG2                 0x12
 157#define CC2520_EXCMASKA0                0x14
 158#define CC2520_EXCMASKA1                0x15
 159#define CC2520_EXCMASKA2                0x16
 160#define CC2520_EXCMASKB0                0x18
 161#define CC2520_EXCMASKB1                0x19
 162#define CC2520_EXCMASKB2                0x1A
 163#define CC2520_EXCBINDX0                0x1C
 164#define CC2520_EXCBINDX1                0x1D
 165#define CC2520_EXCBINDY0                0x1E
 166#define CC2520_EXCBINDY1                0x1F
 167#define CC2520_GPIOCTRL0                0x20
 168#define CC2520_GPIOCTRL1                0x21
 169#define CC2520_GPIOCTRL2                0x22
 170#define CC2520_GPIOCTRL3                0x23
 171#define CC2520_GPIOCTRL4                0x24
 172#define CC2520_GPIOCTRL5                0x25
 173#define CC2520_GPIOPOLARITY             0x26
 174#define CC2520_GPIOCTRL                 0x28
 175#define CC2520_DPUCON                   0x2A
 176#define CC2520_DPUSTAT                  0x2C
 177#define CC2520_FREQCTRL                 0x2E
 178#define CC2520_FREQTUNE                 0x2F
 179#define CC2520_TXPOWER                  0x30
 180#define CC2520_TXCTRL                   0x31
 181#define CC2520_FSMSTAT0                 0x32
 182#define CC2520_FSMSTAT1                 0x33
 183#define CC2520_FIFOPCTRL                0x34
 184#define CC2520_FSMCTRL                  0x35
 185#define CC2520_CCACTRL0                 0x36
 186#define CC2520_CCACTRL1                 0x37
 187#define CC2520_RSSI                     0x38
 188#define CC2520_RSSISTAT                 0x39
 189#define CC2520_RXFIRST                  0x3C
 190#define CC2520_RXFIFOCNT                0x3E
 191#define CC2520_TXFIFOCNT                0x3F
 192
 193/* Driver private information */
 194struct cc2520_private {
 195        struct spi_device *spi;         /* SPI device structure */
 196        struct ieee802154_hw *hw;       /* IEEE-802.15.4 device */
 197        u8 *buf;                        /* SPI TX/Rx data buffer */
 198        struct mutex buffer_mutex;      /* SPI buffer mutex */
 199        bool is_tx;                     /* Flag for sync b/w Tx and Rx */
 200        int fifo_pin;                   /* FIFO GPIO pin number */
 201        struct work_struct fifop_irqwork;/* Workqueue for FIFOP */
 202        spinlock_t lock;                /* Lock for is_tx*/
 203        struct completion tx_complete;  /* Work completion for Tx */
 204};
 205
 206/* Generic Functions */
 207static int
 208cc2520_cmd_strobe(struct cc2520_private *priv, u8 cmd)
 209{
 210        int ret;
 211        u8 status = 0xff;
 212        struct spi_message msg;
 213        struct spi_transfer xfer = {
 214                .len = 0,
 215                .tx_buf = priv->buf,
 216                .rx_buf = priv->buf,
 217        };
 218
 219        spi_message_init(&msg);
 220        spi_message_add_tail(&xfer, &msg);
 221
 222        mutex_lock(&priv->buffer_mutex);
 223        priv->buf[xfer.len++] = cmd;
 224        dev_vdbg(&priv->spi->dev,
 225                 "command strobe buf[0] = %02x\n",
 226                 priv->buf[0]);
 227
 228        ret = spi_sync(priv->spi, &msg);
 229        if (!ret)
 230                status = priv->buf[0];
 231        dev_vdbg(&priv->spi->dev,
 232                 "buf[0] = %02x\n", priv->buf[0]);
 233        mutex_unlock(&priv->buffer_mutex);
 234
 235        return ret;
 236}
 237
 238static int
 239cc2520_get_status(struct cc2520_private *priv, u8 *status)
 240{
 241        int ret;
 242        struct spi_message msg;
 243        struct spi_transfer xfer = {
 244                .len = 0,
 245                .tx_buf = priv->buf,
 246                .rx_buf = priv->buf,
 247        };
 248
 249        spi_message_init(&msg);
 250        spi_message_add_tail(&xfer, &msg);
 251
 252        mutex_lock(&priv->buffer_mutex);
 253        priv->buf[xfer.len++] = CC2520_CMD_SNOP;
 254        dev_vdbg(&priv->spi->dev,
 255                 "get status command buf[0] = %02x\n", priv->buf[0]);
 256
 257        ret = spi_sync(priv->spi, &msg);
 258        if (!ret)
 259                *status = priv->buf[0];
 260        dev_vdbg(&priv->spi->dev,
 261                 "buf[0] = %02x\n", priv->buf[0]);
 262        mutex_unlock(&priv->buffer_mutex);
 263
 264        return ret;
 265}
 266
 267static int
 268cc2520_write_register(struct cc2520_private *priv, u8 reg, u8 value)
 269{
 270        int status;
 271        struct spi_message msg;
 272        struct spi_transfer xfer = {
 273                .len = 0,
 274                .tx_buf = priv->buf,
 275                .rx_buf = priv->buf,
 276        };
 277
 278        spi_message_init(&msg);
 279        spi_message_add_tail(&xfer, &msg);
 280
 281        mutex_lock(&priv->buffer_mutex);
 282
 283        if (reg <= CC2520_FREG_MASK) {
 284                priv->buf[xfer.len++] = CC2520_CMD_REGISTER_WRITE | reg;
 285                priv->buf[xfer.len++] = value;
 286        } else {
 287                priv->buf[xfer.len++] = CC2520_CMD_MEMORY_WRITE;
 288                priv->buf[xfer.len++] = reg;
 289                priv->buf[xfer.len++] = value;
 290        }
 291        status = spi_sync(priv->spi, &msg);
 292        if (msg.status)
 293                status = msg.status;
 294
 295        mutex_unlock(&priv->buffer_mutex);
 296
 297        return status;
 298}
 299
 300static int
 301cc2520_write_ram(struct cc2520_private *priv, u16 reg, u8 len, u8 *data)
 302{
 303        int status;
 304        struct spi_message msg;
 305        struct spi_transfer xfer_head = {
 306                .len        = 0,
 307                .tx_buf        = priv->buf,
 308                .rx_buf        = priv->buf,
 309        };
 310
 311        struct spi_transfer xfer_buf = {
 312                .len = len,
 313                .tx_buf = data,
 314        };
 315
 316        mutex_lock(&priv->buffer_mutex);
 317        priv->buf[xfer_head.len++] = (CC2520_CMD_MEMORY_WRITE |
 318                                                ((reg >> 8) & 0xff));
 319        priv->buf[xfer_head.len++] = reg & 0xff;
 320
 321        spi_message_init(&msg);
 322        spi_message_add_tail(&xfer_head, &msg);
 323        spi_message_add_tail(&xfer_buf, &msg);
 324
 325        status = spi_sync(priv->spi, &msg);
 326        dev_dbg(&priv->spi->dev, "spi status = %d\n", status);
 327        if (msg.status)
 328                status = msg.status;
 329
 330        mutex_unlock(&priv->buffer_mutex);
 331        return status;
 332}
 333
 334static int
 335cc2520_read_register(struct cc2520_private *priv, u8 reg, u8 *data)
 336{
 337        int status;
 338        struct spi_message msg;
 339        struct spi_transfer xfer1 = {
 340                .len = 0,
 341                .tx_buf = priv->buf,
 342                .rx_buf = priv->buf,
 343        };
 344
 345        struct spi_transfer xfer2 = {
 346                .len = 1,
 347                .rx_buf = data,
 348        };
 349
 350        spi_message_init(&msg);
 351        spi_message_add_tail(&xfer1, &msg);
 352        spi_message_add_tail(&xfer2, &msg);
 353
 354        mutex_lock(&priv->buffer_mutex);
 355        priv->buf[xfer1.len++] = CC2520_CMD_MEMORY_READ;
 356        priv->buf[xfer1.len++] = reg;
 357
 358        status = spi_sync(priv->spi, &msg);
 359        dev_dbg(&priv->spi->dev,
 360                "spi status = %d\n", status);
 361        if (msg.status)
 362                status = msg.status;
 363
 364        mutex_unlock(&priv->buffer_mutex);
 365
 366        return status;
 367}
 368
 369static int
 370cc2520_write_txfifo(struct cc2520_private *priv, u8 *data, u8 len)
 371{
 372        int status;
 373
 374        /* length byte must include FCS even
 375         * if it is calculated in the hardware
 376         */
 377        int len_byte = len + 2;
 378
 379        struct spi_message msg;
 380
 381        struct spi_transfer xfer_head = {
 382                .len = 0,
 383                .tx_buf = priv->buf,
 384                .rx_buf = priv->buf,
 385        };
 386        struct spi_transfer xfer_len = {
 387                .len = 1,
 388                .tx_buf = &len_byte,
 389        };
 390        struct spi_transfer xfer_buf = {
 391                .len = len,
 392                .tx_buf = data,
 393        };
 394
 395        spi_message_init(&msg);
 396        spi_message_add_tail(&xfer_head, &msg);
 397        spi_message_add_tail(&xfer_len, &msg);
 398        spi_message_add_tail(&xfer_buf, &msg);
 399
 400        mutex_lock(&priv->buffer_mutex);
 401        priv->buf[xfer_head.len++] = CC2520_CMD_TXBUF;
 402        dev_vdbg(&priv->spi->dev,
 403                 "TX_FIFO cmd buf[0] = %02x\n", priv->buf[0]);
 404
 405        status = spi_sync(priv->spi, &msg);
 406        dev_vdbg(&priv->spi->dev, "status = %d\n", status);
 407        if (msg.status)
 408                status = msg.status;
 409        dev_vdbg(&priv->spi->dev, "status = %d\n", status);
 410        dev_vdbg(&priv->spi->dev, "buf[0] = %02x\n", priv->buf[0]);
 411        mutex_unlock(&priv->buffer_mutex);
 412
 413        return status;
 414}
 415
 416static int
 417cc2520_read_rxfifo(struct cc2520_private *priv, u8 *data, u8 len, u8 *lqi)
 418{
 419        int status;
 420        struct spi_message msg;
 421
 422        struct spi_transfer xfer_head = {
 423                .len = 0,
 424                .tx_buf = priv->buf,
 425                .rx_buf = priv->buf,
 426        };
 427        struct spi_transfer xfer_buf = {
 428                .len = len,
 429                .rx_buf = data,
 430        };
 431
 432        spi_message_init(&msg);
 433        spi_message_add_tail(&xfer_head, &msg);
 434        spi_message_add_tail(&xfer_buf, &msg);
 435
 436        mutex_lock(&priv->buffer_mutex);
 437        priv->buf[xfer_head.len++] = CC2520_CMD_RXBUF;
 438
 439        dev_vdbg(&priv->spi->dev, "read rxfifo buf[0] = %02x\n", priv->buf[0]);
 440        dev_vdbg(&priv->spi->dev, "buf[1] = %02x\n", priv->buf[1]);
 441
 442        status = spi_sync(priv->spi, &msg);
 443        dev_vdbg(&priv->spi->dev, "status = %d\n", status);
 444        if (msg.status)
 445                status = msg.status;
 446        dev_vdbg(&priv->spi->dev, "status = %d\n", status);
 447        dev_vdbg(&priv->spi->dev,
 448                 "return status buf[0] = %02x\n", priv->buf[0]);
 449        dev_vdbg(&priv->spi->dev, "length buf[1] = %02x\n", priv->buf[1]);
 450
 451        mutex_unlock(&priv->buffer_mutex);
 452
 453        return status;
 454}
 455
 456static int cc2520_start(struct ieee802154_hw *hw)
 457{
 458        return cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRXON);
 459}
 460
 461static void cc2520_stop(struct ieee802154_hw *hw)
 462{
 463        cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRFOFF);
 464}
 465
 466static int
 467cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
 468{
 469        struct cc2520_private *priv = hw->priv;
 470        unsigned long flags;
 471        int rc;
 472        u8 status = 0;
 473
 474        rc = cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
 475        if (rc)
 476                goto err_tx;
 477
 478        rc = cc2520_write_txfifo(priv, skb->data, skb->len);
 479        if (rc)
 480                goto err_tx;
 481
 482        rc = cc2520_get_status(priv, &status);
 483        if (rc)
 484                goto err_tx;
 485
 486        if (status & CC2520_STATUS_TX_UNDERFLOW) {
 487                dev_err(&priv->spi->dev, "cc2520 tx underflow exception\n");
 488                goto err_tx;
 489        }
 490
 491        spin_lock_irqsave(&priv->lock, flags);
 492        BUG_ON(priv->is_tx);
 493        priv->is_tx = 1;
 494        spin_unlock_irqrestore(&priv->lock, flags);
 495
 496        rc = cc2520_cmd_strobe(priv, CC2520_CMD_STXONCCA);
 497        if (rc)
 498                goto err;
 499
 500        rc = wait_for_completion_interruptible(&priv->tx_complete);
 501        if (rc < 0)
 502                goto err;
 503
 504        cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
 505        cc2520_cmd_strobe(priv, CC2520_CMD_SRXON);
 506
 507        return rc;
 508err:
 509        spin_lock_irqsave(&priv->lock, flags);
 510        priv->is_tx = 0;
 511        spin_unlock_irqrestore(&priv->lock, flags);
 512err_tx:
 513        return rc;
 514}
 515
 516
 517static int cc2520_rx(struct cc2520_private *priv)
 518{
 519        u8 len = 0, lqi = 0, bytes = 1;
 520        struct sk_buff *skb;
 521
 522        cc2520_read_rxfifo(priv, &len, bytes, &lqi);
 523
 524        if (len < 2 || len > IEEE802154_MTU)
 525                return -EINVAL;
 526
 527        skb = dev_alloc_skb(len);
 528        if (!skb)
 529                return -ENOMEM;
 530
 531        if (cc2520_read_rxfifo(priv, skb_put(skb, len), len, &lqi)) {
 532                dev_dbg(&priv->spi->dev, "frame reception failed\n");
 533                kfree_skb(skb);
 534                return -EINVAL;
 535        }
 536
 537        skb_trim(skb, skb->len - 2);
 538
 539        ieee802154_rx_irqsafe(priv->hw, skb, lqi);
 540
 541        dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi);
 542
 543        return 0;
 544}
 545
 546static int
 547cc2520_ed(struct ieee802154_hw *hw, u8 *level)
 548{
 549        struct cc2520_private *priv = hw->priv;
 550        u8 status = 0xff;
 551        u8 rssi;
 552        int ret;
 553
 554        ret = cc2520_read_register(priv , CC2520_RSSISTAT, &status);
 555        if (ret)
 556                return ret;
 557
 558        if (status != RSSI_VALID)
 559                return -EINVAL;
 560
 561        ret = cc2520_read_register(priv , CC2520_RSSI, &rssi);
 562        if (ret)
 563                return ret;
 564
 565        /* level = RSSI(rssi) - OFFSET [dBm] : offset is 76dBm */
 566        *level = rssi - RSSI_OFFSET;
 567
 568        return 0;
 569}
 570
 571static int
 572cc2520_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 573{
 574        struct cc2520_private *priv = hw->priv;
 575        int ret;
 576
 577        dev_dbg(&priv->spi->dev, "trying to set channel\n");
 578
 579        BUG_ON(page != 0);
 580        BUG_ON(channel < CC2520_MINCHANNEL);
 581        BUG_ON(channel > CC2520_MAXCHANNEL);
 582
 583        ret = cc2520_write_register(priv, CC2520_FREQCTRL,
 584                                    11 + 5*(channel - 11));
 585
 586        return ret;
 587}
 588
 589static int
 590cc2520_filter(struct ieee802154_hw *hw,
 591              struct ieee802154_hw_addr_filt *filt, unsigned long changed)
 592{
 593        struct cc2520_private *priv = hw->priv;
 594
 595        if (changed & IEEE802154_AFILT_PANID_CHANGED) {
 596                u16 panid = le16_to_cpu(filt->pan_id);
 597
 598                dev_vdbg(&priv->spi->dev,
 599                         "cc2520_filter called for pan id\n");
 600                cc2520_write_ram(priv, CC2520RAM_PANID,
 601                                 sizeof(panid), (u8 *)&panid);
 602        }
 603
 604        if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
 605                dev_vdbg(&priv->spi->dev,
 606                         "cc2520_filter called for IEEE addr\n");
 607                cc2520_write_ram(priv, CC2520RAM_IEEEADDR,
 608                                 sizeof(filt->ieee_addr),
 609                                 (u8 *)&filt->ieee_addr);
 610        }
 611
 612        if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
 613                u16 addr = le16_to_cpu(filt->short_addr);
 614
 615                dev_vdbg(&priv->spi->dev,
 616                         "cc2520_filter called for saddr\n");
 617                cc2520_write_ram(priv, CC2520RAM_SHORTADDR,
 618                                 sizeof(addr), (u8 *)&addr);
 619        }
 620
 621        if (changed & IEEE802154_AFILT_PANC_CHANGED) {
 622                dev_vdbg(&priv->spi->dev,
 623                         "cc2520_filter called for panc change\n");
 624                if (filt->pan_coord)
 625                        cc2520_write_register(priv, CC2520_FRMFILT0, 0x02);
 626                else
 627                        cc2520_write_register(priv, CC2520_FRMFILT0, 0x00);
 628        }
 629
 630        return 0;
 631}
 632
 633static const struct ieee802154_ops cc2520_ops = {
 634        .owner = THIS_MODULE,
 635        .start = cc2520_start,
 636        .stop = cc2520_stop,
 637        .xmit_sync = cc2520_tx,
 638        .ed = cc2520_ed,
 639        .set_channel = cc2520_set_channel,
 640        .set_hw_addr_filt = cc2520_filter,
 641};
 642
 643static int cc2520_register(struct cc2520_private *priv)
 644{
 645        int ret = -ENOMEM;
 646
 647        priv->hw = ieee802154_alloc_hw(sizeof(*priv), &cc2520_ops);
 648        if (!priv->hw)
 649                goto err_ret;
 650
 651        priv->hw->priv = priv;
 652        priv->hw->parent = &priv->spi->dev;
 653        priv->hw->extra_tx_headroom = 0;
 654        priv->hw->vif_data_size = sizeof(*priv);
 655
 656        /* We do support only 2.4 Ghz */
 657        priv->hw->phy->channels_supported[0] = 0x7FFF800;
 658        priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
 659                          IEEE802154_HW_AFILT;
 660
 661        dev_vdbg(&priv->spi->dev, "registered cc2520\n");
 662        ret = ieee802154_register_hw(priv->hw);
 663        if (ret)
 664                goto err_free_device;
 665
 666        return 0;
 667
 668err_free_device:
 669        ieee802154_free_hw(priv->hw);
 670err_ret:
 671        return ret;
 672}
 673
 674static void cc2520_fifop_irqwork(struct work_struct *work)
 675{
 676        struct cc2520_private *priv
 677                = container_of(work, struct cc2520_private, fifop_irqwork);
 678
 679        dev_dbg(&priv->spi->dev, "fifop interrupt received\n");
 680
 681        if (gpio_get_value(priv->fifo_pin))
 682                cc2520_rx(priv);
 683        else
 684                dev_dbg(&priv->spi->dev, "rxfifo overflow\n");
 685
 686        cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHRX);
 687        cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHRX);
 688}
 689
 690static irqreturn_t cc2520_fifop_isr(int irq, void *data)
 691{
 692        struct cc2520_private *priv = data;
 693
 694        schedule_work(&priv->fifop_irqwork);
 695
 696        return IRQ_HANDLED;
 697}
 698
 699static irqreturn_t cc2520_sfd_isr(int irq, void *data)
 700{
 701        struct cc2520_private *priv = data;
 702        unsigned long flags;
 703
 704        spin_lock_irqsave(&priv->lock, flags);
 705        if (priv->is_tx) {
 706                priv->is_tx = 0;
 707                spin_unlock_irqrestore(&priv->lock, flags);
 708                dev_dbg(&priv->spi->dev, "SFD for TX\n");
 709                complete(&priv->tx_complete);
 710        } else {
 711                spin_unlock_irqrestore(&priv->lock, flags);
 712                dev_dbg(&priv->spi->dev, "SFD for RX\n");
 713        }
 714
 715        return IRQ_HANDLED;
 716}
 717
 718static int cc2520_hw_init(struct cc2520_private *priv)
 719{
 720        u8 status = 0, state = 0xff;
 721        int ret;
 722        int timeout = 100;
 723
 724        ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state);
 725        if (ret)
 726                goto err_ret;
 727
 728        if (state != STATE_IDLE)
 729                return -EINVAL;
 730
 731        do {
 732                ret = cc2520_get_status(priv, &status);
 733                if (ret)
 734                        goto err_ret;
 735
 736                if (timeout-- <= 0) {
 737                        dev_err(&priv->spi->dev, "oscillator start failed!\n");
 738                        return ret;
 739                }
 740                udelay(1);
 741        } while (!(status & CC2520_STATUS_XOSC32M_STABLE));
 742
 743        dev_vdbg(&priv->spi->dev, "oscillator brought up\n");
 744
 745        /* Registers default value: section 28.1 in Datasheet */
 746        ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7);
 747        if (ret)
 748                goto err_ret;
 749
 750        ret = cc2520_write_register(priv, CC2520_CCACTRL0, 0x1A);
 751        if (ret)
 752                goto err_ret;
 753
 754        ret = cc2520_write_register(priv, CC2520_MDMCTRL0, 0x85);
 755        if (ret)
 756                goto err_ret;
 757
 758        ret = cc2520_write_register(priv, CC2520_MDMCTRL1, 0x14);
 759        if (ret)
 760                goto err_ret;
 761
 762        ret = cc2520_write_register(priv, CC2520_RXCTRL, 0x3f);
 763        if (ret)
 764                goto err_ret;
 765
 766        ret = cc2520_write_register(priv, CC2520_FSCTRL, 0x5a);
 767        if (ret)
 768                goto err_ret;
 769
 770        ret = cc2520_write_register(priv, CC2520_FSCAL1, 0x2b);
 771        if (ret)
 772                goto err_ret;
 773
 774        ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11);
 775        if (ret)
 776                goto err_ret;
 777
 778        ret = cc2520_write_register(priv, CC2520_ADCTEST0, 0x10);
 779        if (ret)
 780                goto err_ret;
 781
 782        ret = cc2520_write_register(priv, CC2520_ADCTEST1, 0x0e);
 783        if (ret)
 784                goto err_ret;
 785
 786        ret = cc2520_write_register(priv, CC2520_ADCTEST2, 0x03);
 787        if (ret)
 788                goto err_ret;
 789
 790        ret = cc2520_write_register(priv, CC2520_FRMCTRL0, 0x60);
 791        if (ret)
 792                goto err_ret;
 793
 794        ret = cc2520_write_register(priv, CC2520_FRMCTRL1, 0x03);
 795        if (ret)
 796                goto err_ret;
 797
 798        ret = cc2520_write_register(priv, CC2520_FRMFILT0, 0x00);
 799        if (ret)
 800                goto err_ret;
 801
 802        ret = cc2520_write_register(priv, CC2520_FIFOPCTRL, 127);
 803        if (ret)
 804                goto err_ret;
 805
 806        return 0;
 807
 808err_ret:
 809        return ret;
 810}
 811
 812static struct cc2520_platform_data *
 813cc2520_get_platform_data(struct spi_device *spi)
 814{
 815        struct cc2520_platform_data *pdata;
 816        struct device_node *np = spi->dev.of_node;
 817        struct cc2520_private *priv = spi_get_drvdata(spi);
 818
 819        if (!np)
 820                return spi->dev.platform_data;
 821
 822        pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL);
 823        if (!pdata)
 824                goto done;
 825
 826        pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0);
 827        priv->fifo_pin = pdata->fifo;
 828
 829        pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0);
 830
 831        pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0);
 832        pdata->cca = of_get_named_gpio(np, "cca-gpio", 0);
 833        pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0);
 834        pdata->reset = of_get_named_gpio(np, "reset-gpio", 0);
 835
 836        spi->dev.platform_data = pdata;
 837
 838done:
 839        return pdata;
 840}
 841
 842static int cc2520_probe(struct spi_device *spi)
 843{
 844        struct cc2520_private *priv;
 845        struct pinctrl *pinctrl;
 846        struct cc2520_platform_data *pdata;
 847        int ret;
 848
 849        priv = devm_kzalloc(&spi->dev,
 850                            sizeof(struct cc2520_private), GFP_KERNEL);
 851        if (!priv) {
 852                ret = -ENOMEM;
 853                goto err_ret;
 854        }
 855
 856        spi_set_drvdata(spi, priv);
 857
 858        pinctrl = devm_pinctrl_get_select_default(&spi->dev);
 859        if (IS_ERR(pinctrl))
 860                dev_warn(&spi->dev,
 861                         "pinctrl pins are not configured\n");
 862
 863        pdata = cc2520_get_platform_data(spi);
 864        if (!pdata) {
 865                dev_err(&spi->dev, "no platform data\n");
 866                return -EINVAL;
 867        }
 868
 869        priv->spi = spi;
 870
 871        priv->buf = devm_kzalloc(&spi->dev,
 872                                 SPI_COMMAND_BUFFER, GFP_KERNEL);
 873        if (!priv->buf) {
 874                ret = -ENOMEM;
 875                goto err_ret;
 876        }
 877
 878        mutex_init(&priv->buffer_mutex);
 879        INIT_WORK(&priv->fifop_irqwork, cc2520_fifop_irqwork);
 880        spin_lock_init(&priv->lock);
 881        init_completion(&priv->tx_complete);
 882
 883        /* Request all the gpio's */
 884        if (!gpio_is_valid(pdata->fifo)) {
 885                dev_err(&spi->dev, "fifo gpio is not valid\n");
 886                ret = -EINVAL;
 887                goto err_hw_init;
 888        }
 889
 890        ret = devm_gpio_request_one(&spi->dev, pdata->fifo,
 891                                    GPIOF_IN, "fifo");
 892        if (ret)
 893                goto err_hw_init;
 894
 895        if (!gpio_is_valid(pdata->cca)) {
 896                dev_err(&spi->dev, "cca gpio is not valid\n");
 897                ret = -EINVAL;
 898                goto err_hw_init;
 899        }
 900
 901        ret = devm_gpio_request_one(&spi->dev, pdata->cca,
 902                                    GPIOF_IN, "cca");
 903        if (ret)
 904                goto err_hw_init;
 905
 906        if (!gpio_is_valid(pdata->fifop)) {
 907                dev_err(&spi->dev, "fifop gpio is not valid\n");
 908                ret = -EINVAL;
 909                goto err_hw_init;
 910        }
 911
 912        ret = devm_gpio_request_one(&spi->dev, pdata->fifop,
 913                                    GPIOF_IN, "fifop");
 914        if (ret)
 915                goto err_hw_init;
 916
 917        if (!gpio_is_valid(pdata->sfd)) {
 918                dev_err(&spi->dev, "sfd gpio is not valid\n");
 919                ret = -EINVAL;
 920                goto err_hw_init;
 921        }
 922
 923        ret = devm_gpio_request_one(&spi->dev, pdata->sfd,
 924                                    GPIOF_IN, "sfd");
 925        if (ret)
 926                goto err_hw_init;
 927
 928        if (!gpio_is_valid(pdata->reset)) {
 929                dev_err(&spi->dev, "reset gpio is not valid\n");
 930                ret = -EINVAL;
 931                goto err_hw_init;
 932        }
 933
 934        ret = devm_gpio_request_one(&spi->dev, pdata->reset,
 935                                    GPIOF_OUT_INIT_LOW, "reset");
 936        if (ret)
 937                goto err_hw_init;
 938
 939        if (!gpio_is_valid(pdata->vreg)) {
 940                dev_err(&spi->dev, "vreg gpio is not valid\n");
 941                ret = -EINVAL;
 942                goto err_hw_init;
 943        }
 944
 945        ret = devm_gpio_request_one(&spi->dev, pdata->vreg,
 946                                    GPIOF_OUT_INIT_LOW, "vreg");
 947        if (ret)
 948                goto err_hw_init;
 949
 950
 951        gpio_set_value(pdata->vreg, HIGH);
 952        usleep_range(100, 150);
 953
 954        gpio_set_value(pdata->reset, HIGH);
 955        usleep_range(200, 250);
 956
 957        ret = cc2520_hw_init(priv);
 958        if (ret)
 959                goto err_hw_init;
 960
 961        /* Set up fifop interrupt */
 962        ret = devm_request_irq(&spi->dev,
 963                               gpio_to_irq(pdata->fifop),
 964                               cc2520_fifop_isr,
 965                               IRQF_TRIGGER_RISING,
 966                               dev_name(&spi->dev),
 967                               priv);
 968        if (ret) {
 969                dev_err(&spi->dev, "could not get fifop irq\n");
 970                goto err_hw_init;
 971        }
 972
 973        /* Set up sfd interrupt */
 974        ret = devm_request_irq(&spi->dev,
 975                               gpio_to_irq(pdata->sfd),
 976                               cc2520_sfd_isr,
 977                               IRQF_TRIGGER_FALLING,
 978                               dev_name(&spi->dev),
 979                               priv);
 980        if (ret) {
 981                dev_err(&spi->dev, "could not get sfd irq\n");
 982                goto err_hw_init;
 983        }
 984
 985        ret = cc2520_register(priv);
 986        if (ret)
 987                goto err_hw_init;
 988
 989        return 0;
 990
 991err_hw_init:
 992        mutex_destroy(&priv->buffer_mutex);
 993        flush_work(&priv->fifop_irqwork);
 994
 995err_ret:
 996        return ret;
 997}
 998
 999static int cc2520_remove(struct spi_device *spi)
1000{
1001        struct cc2520_private *priv = spi_get_drvdata(spi);
1002
1003        mutex_destroy(&priv->buffer_mutex);
1004        flush_work(&priv->fifop_irqwork);
1005
1006        ieee802154_unregister_hw(priv->hw);
1007        ieee802154_free_hw(priv->hw);
1008
1009        return 0;
1010}
1011
1012static const struct spi_device_id cc2520_ids[] = {
1013        {"cc2520", },
1014        {},
1015};
1016MODULE_DEVICE_TABLE(spi, cc2520_ids);
1017
1018static const struct of_device_id cc2520_of_ids[] = {
1019        {.compatible = "ti,cc2520", },
1020        {},
1021};
1022MODULE_DEVICE_TABLE(of, cc2520_of_ids);
1023
1024/* SPI driver structure */
1025static struct spi_driver cc2520_driver = {
1026        .driver = {
1027                .name = "cc2520",
1028                .bus = &spi_bus_type,
1029                .owner = THIS_MODULE,
1030                .of_match_table = of_match_ptr(cc2520_of_ids),
1031        },
1032        .id_table = cc2520_ids,
1033        .probe = cc2520_probe,
1034        .remove = cc2520_remove,
1035};
1036module_spi_driver(cc2520_driver);
1037
1038MODULE_AUTHOR("Varka Bhadram <varkab@cdac.in>");
1039MODULE_DESCRIPTION("CC2520 Transceiver Driver");
1040MODULE_LICENSE("GPL v2");
1041