root/drivers/net/ieee802154/cc2520.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cc2520_cmd_strobe
  2. cc2520_get_status
  3. cc2520_write_register
  4. cc2520_write_ram
  5. cc2520_read_register
  6. cc2520_write_txfifo
  7. cc2520_read_rxfifo
  8. cc2520_start
  9. cc2520_stop
  10. cc2520_tx
  11. cc2520_rx
  12. cc2520_ed
  13. cc2520_set_channel
  14. cc2520_filter
  15. cc2520_set_tx_power
  16. cc2520_cc2591_set_tx_power
  17. cc2520_set_txpower
  18. cc2520_set_promiscuous_mode
  19. cc2520_register
  20. cc2520_fifop_irqwork
  21. cc2520_fifop_isr
  22. cc2520_sfd_isr
  23. cc2520_get_platform_data
  24. cc2520_hw_init
  25. cc2520_probe
  26. cc2520_remove

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

/* [<][>][^][v][top][bottom][index][help] */