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