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 25#include <net/mac802154.h> 26#include <net/wpan-phy.h> 27#include <net/ieee802154.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_dev *dev; /* 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_dev *dev) 457{ 458 return cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRXON); 459} 460 461static void cc2520_stop(struct ieee802154_dev *dev) 462{ 463 cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRFOFF); 464} 465 466static int 467cc2520_tx(struct ieee802154_dev *dev, struct sk_buff *skb) 468{ 469 struct cc2520_private *priv = dev->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 = alloc_skb(len, GFP_KERNEL); 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->dev, 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_dev *dev, u8 *level) 548{ 549 struct cc2520_private *priv = dev->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_dev *dev, int page, int channel) 573{ 574 struct cc2520_private *priv = dev->priv; 575 int ret; 576 577 might_sleep(); 578 dev_dbg(&priv->spi->dev, "trying to set channel\n"); 579 580 BUG_ON(page != 0); 581 BUG_ON(channel < CC2520_MINCHANNEL); 582 BUG_ON(channel > CC2520_MAXCHANNEL); 583 584 ret = cc2520_write_register(priv, CC2520_FREQCTRL, 585 11 + 5*(channel - 11)); 586 587 return ret; 588} 589 590static int 591cc2520_filter(struct ieee802154_dev *dev, 592 struct ieee802154_hw_addr_filt *filt, unsigned long changed) 593{ 594 struct cc2520_private *priv = dev->priv; 595 596 if (changed & IEEE802515_AFILT_PANID_CHANGED) { 597 u16 panid = le16_to_cpu(filt->pan_id); 598 599 dev_vdbg(&priv->spi->dev, 600 "cc2520_filter called for pan id\n"); 601 cc2520_write_ram(priv, CC2520RAM_PANID, 602 sizeof(panid), (u8 *)&panid); 603 } 604 605 if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { 606 dev_vdbg(&priv->spi->dev, 607 "cc2520_filter called for IEEE addr\n"); 608 cc2520_write_ram(priv, CC2520RAM_IEEEADDR, 609 sizeof(filt->ieee_addr), 610 (u8 *)&filt->ieee_addr); 611 } 612 613 if (changed & IEEE802515_AFILT_SADDR_CHANGED) { 614 u16 addr = le16_to_cpu(filt->short_addr); 615 616 dev_vdbg(&priv->spi->dev, 617 "cc2520_filter called for saddr\n"); 618 cc2520_write_ram(priv, CC2520RAM_SHORTADDR, 619 sizeof(addr), (u8 *)&addr); 620 } 621 622 if (changed & IEEE802515_AFILT_PANC_CHANGED) { 623 dev_vdbg(&priv->spi->dev, 624 "cc2520_filter called for panc change\n"); 625 if (filt->pan_coord) 626 cc2520_write_register(priv, CC2520_FRMFILT0, 0x02); 627 else 628 cc2520_write_register(priv, CC2520_FRMFILT0, 0x00); 629 } 630 631 return 0; 632} 633 634static struct ieee802154_ops cc2520_ops = { 635 .owner = THIS_MODULE, 636 .start = cc2520_start, 637 .stop = cc2520_stop, 638 .xmit = cc2520_tx, 639 .ed = cc2520_ed, 640 .set_channel = cc2520_set_channel, 641 .set_hw_addr_filt = cc2520_filter, 642}; 643 644static int cc2520_register(struct cc2520_private *priv) 645{ 646 int ret = -ENOMEM; 647 648 priv->dev = ieee802154_alloc_device(sizeof(*priv), &cc2520_ops); 649 if (!priv->dev) 650 goto err_ret; 651 652 priv->dev->priv = priv; 653 priv->dev->parent = &priv->spi->dev; 654 priv->dev->extra_tx_headroom = 0; 655 656 /* We do support only 2.4 Ghz */ 657 priv->dev->phy->channels_supported[0] = 0x7FFF800; 658 priv->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK; 659 660 dev_vdbg(&priv->spi->dev, "registered cc2520\n"); 661 ret = ieee802154_register_device(priv->dev); 662 if (ret) 663 goto err_free_device; 664 665 return 0; 666 667err_free_device: 668 ieee802154_free_device(priv->dev); 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_hw_init(struct cc2520_private *priv) 718{ 719 u8 status = 0, state = 0xff; 720 int ret; 721 int timeout = 100; 722 723 ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state); 724 if (ret) 725 goto err_ret; 726 727 if (state != STATE_IDLE) 728 return -EINVAL; 729 730 do { 731 ret = cc2520_get_status(priv, &status); 732 if (ret) 733 goto err_ret; 734 735 if (timeout-- <= 0) { 736 dev_err(&priv->spi->dev, "oscillator start failed!\n"); 737 return ret; 738 } 739 udelay(1); 740 } while (!(status & CC2520_STATUS_XOSC32M_STABLE)); 741 742 dev_vdbg(&priv->spi->dev, "oscillator brought up\n"); 743 744 /* Registers default value: section 28.1 in Datasheet */ 745 ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7); 746 if (ret) 747 goto err_ret; 748 749 ret = cc2520_write_register(priv, CC2520_CCACTRL0, 0x1A); 750 if (ret) 751 goto err_ret; 752 753 ret = cc2520_write_register(priv, CC2520_MDMCTRL0, 0x85); 754 if (ret) 755 goto err_ret; 756 757 ret = cc2520_write_register(priv, CC2520_MDMCTRL1, 0x14); 758 if (ret) 759 goto err_ret; 760 761 ret = cc2520_write_register(priv, CC2520_RXCTRL, 0x3f); 762 if (ret) 763 goto err_ret; 764 765 ret = cc2520_write_register(priv, CC2520_FSCTRL, 0x5a); 766 if (ret) 767 goto err_ret; 768 769 ret = cc2520_write_register(priv, CC2520_FSCAL1, 0x2b); 770 if (ret) 771 goto err_ret; 772 773 ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11); 774 if (ret) 775 goto err_ret; 776 777 ret = cc2520_write_register(priv, CC2520_ADCTEST0, 0x10); 778 if (ret) 779 goto err_ret; 780 781 ret = cc2520_write_register(priv, CC2520_ADCTEST1, 0x0e); 782 if (ret) 783 goto err_ret; 784 785 ret = cc2520_write_register(priv, CC2520_ADCTEST2, 0x03); 786 if (ret) 787 goto err_ret; 788 789 ret = cc2520_write_register(priv, CC2520_FRMCTRL0, 0x60); 790 if (ret) 791 goto err_ret; 792 793 ret = cc2520_write_register(priv, CC2520_FRMCTRL1, 0x03); 794 if (ret) 795 goto err_ret; 796 797 ret = cc2520_write_register(priv, CC2520_FRMFILT0, 0x00); 798 if (ret) 799 goto err_ret; 800 801 ret = cc2520_write_register(priv, CC2520_FIFOPCTRL, 127); 802 if (ret) 803 goto err_ret; 804 805 return 0; 806 807err_ret: 808 return ret; 809} 810 811static struct cc2520_platform_data * 812cc2520_get_platform_data(struct spi_device *spi) 813{ 814 struct cc2520_platform_data *pdata; 815 struct device_node *np = spi->dev.of_node; 816 struct cc2520_private *priv = spi_get_drvdata(spi); 817 818 if (!np) 819 return spi->dev.platform_data; 820 821 pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL); 822 if (!pdata) 823 goto done; 824 825 pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0); 826 priv->fifo_pin = pdata->fifo; 827 828 pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0); 829 830 pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0); 831 pdata->cca = of_get_named_gpio(np, "cca-gpio", 0); 832 pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0); 833 pdata->reset = of_get_named_gpio(np, "reset-gpio", 0); 834 835 spi->dev.platform_data = pdata; 836 837done: 838 return pdata; 839} 840 841static int cc2520_probe(struct spi_device *spi) 842{ 843 struct cc2520_private *priv; 844 struct pinctrl *pinctrl; 845 struct cc2520_platform_data *pdata; 846 int ret; 847 848 priv = devm_kzalloc(&spi->dev, 849 sizeof(struct cc2520_private), GFP_KERNEL); 850 if (!priv) { 851 ret = -ENOMEM; 852 goto err_ret; 853 } 854 855 spi_set_drvdata(spi, priv); 856 857 pinctrl = devm_pinctrl_get_select_default(&spi->dev); 858 if (IS_ERR(pinctrl)) 859 dev_warn(&spi->dev, 860 "pinctrl pins are not configured"); 861 862 pdata = cc2520_get_platform_data(spi); 863 if (!pdata) { 864 dev_err(&spi->dev, "no platform data\n"); 865 return -EINVAL; 866 } 867 868 priv->spi = spi; 869 870 priv->buf = devm_kzalloc(&spi->dev, 871 SPI_COMMAND_BUFFER, GFP_KERNEL); 872 if (!priv->buf) { 873 ret = -ENOMEM; 874 goto err_ret; 875 } 876 877 mutex_init(&priv->buffer_mutex); 878 INIT_WORK(&priv->fifop_irqwork, cc2520_fifop_irqwork); 879 spin_lock_init(&priv->lock); 880 init_completion(&priv->tx_complete); 881 882 /* Request all the gpio's */ 883 if (!gpio_is_valid(pdata->fifo)) { 884 dev_err(&spi->dev, "fifo gpio is not valid\n"); 885 ret = -EINVAL; 886 goto err_hw_init; 887 } 888 889 ret = devm_gpio_request_one(&spi->dev, pdata->fifo, 890 GPIOF_IN, "fifo"); 891 if (ret) 892 goto err_hw_init; 893 894 if (!gpio_is_valid(pdata->cca)) { 895 dev_err(&spi->dev, "cca gpio is not valid\n"); 896 ret = -EINVAL; 897 goto err_hw_init; 898 } 899 900 ret = devm_gpio_request_one(&spi->dev, pdata->cca, 901 GPIOF_IN, "cca"); 902 if (ret) 903 goto err_hw_init; 904 905 if (!gpio_is_valid(pdata->fifop)) { 906 dev_err(&spi->dev, "fifop gpio is not valid\n"); 907 ret = -EINVAL; 908 goto err_hw_init; 909 } 910 911 ret = devm_gpio_request_one(&spi->dev, pdata->fifop, 912 GPIOF_IN, "fifop"); 913 if (ret) 914 goto err_hw_init; 915 916 if (!gpio_is_valid(pdata->sfd)) { 917 dev_err(&spi->dev, "sfd gpio is not valid\n"); 918 ret = -EINVAL; 919 goto err_hw_init; 920 } 921 922 ret = devm_gpio_request_one(&spi->dev, pdata->sfd, 923 GPIOF_IN, "sfd"); 924 if (ret) 925 goto err_hw_init; 926 927 if (!gpio_is_valid(pdata->reset)) { 928 dev_err(&spi->dev, "reset gpio is not valid\n"); 929 ret = -EINVAL; 930 goto err_hw_init; 931 } 932 933 ret = devm_gpio_request_one(&spi->dev, pdata->reset, 934 GPIOF_OUT_INIT_LOW, "reset"); 935 if (ret) 936 goto err_hw_init; 937 938 if (!gpio_is_valid(pdata->vreg)) { 939 dev_err(&spi->dev, "vreg gpio is not valid\n"); 940 ret = -EINVAL; 941 goto err_hw_init; 942 } 943 944 ret = devm_gpio_request_one(&spi->dev, pdata->vreg, 945 GPIOF_OUT_INIT_LOW, "vreg"); 946 if (ret) 947 goto err_hw_init; 948 949 950 gpio_set_value(pdata->vreg, HIGH); 951 usleep_range(100, 150); 952 953 gpio_set_value(pdata->reset, HIGH); 954 usleep_range(200, 250); 955 956 ret = cc2520_hw_init(priv); 957 if (ret) 958 goto err_hw_init; 959 960 /* Set up fifop interrupt */ 961 ret = devm_request_irq(&spi->dev, 962 gpio_to_irq(pdata->fifop), 963 cc2520_fifop_isr, 964 IRQF_TRIGGER_RISING, 965 dev_name(&spi->dev), 966 priv); 967 if (ret) { 968 dev_err(&spi->dev, "could not get fifop irq\n"); 969 goto err_hw_init; 970 } 971 972 /* Set up sfd interrupt */ 973 ret = devm_request_irq(&spi->dev, 974 gpio_to_irq(pdata->sfd), 975 cc2520_sfd_isr, 976 IRQF_TRIGGER_FALLING, 977 dev_name(&spi->dev), 978 priv); 979 if (ret) { 980 dev_err(&spi->dev, "could not get sfd irq\n"); 981 goto err_hw_init; 982 } 983 984 ret = cc2520_register(priv); 985 if (ret) 986 goto err_hw_init; 987 988 return 0; 989 990err_hw_init: 991 mutex_destroy(&priv->buffer_mutex); 992 flush_work(&priv->fifop_irqwork); 993 994err_ret: 995 return ret; 996} 997 998static int cc2520_remove(struct spi_device *spi) 999{ 1000 struct cc2520_private *priv = spi_get_drvdata(spi); 1001 1002 mutex_destroy(&priv->buffer_mutex); 1003 flush_work(&priv->fifop_irqwork); 1004 1005 ieee802154_unregister_device(priv->dev); 1006 ieee802154_free_device(priv->dev); 1007 1008 return 0; 1009} 1010 1011static const struct spi_device_id cc2520_ids[] = { 1012 {"cc2520", }, 1013 {}, 1014}; 1015MODULE_DEVICE_TABLE(spi, cc2520_ids); 1016 1017static const struct of_device_id cc2520_of_ids[] = { 1018 {.compatible = "ti,cc2520", }, 1019 {}, 1020}; 1021MODULE_DEVICE_TABLE(of, cc2520_of_ids); 1022 1023/* SPI driver structure */ 1024static struct spi_driver cc2520_driver = { 1025 .driver = { 1026 .name = "cc2520", 1027 .bus = &spi_bus_type, 1028 .owner = THIS_MODULE, 1029 .of_match_table = of_match_ptr(cc2520_of_ids), 1030 }, 1031 .id_table = cc2520_ids, 1032 .probe = cc2520_probe, 1033 .remove = cc2520_remove, 1034}; 1035module_spi_driver(cc2520_driver); 1036 1037MODULE_AUTHOR("Varka Bhadram <varkab@cdac.in>"); 1038MODULE_DESCRIPTION("CC2520 Transceiver Driver"); 1039MODULE_LICENSE("GPL v2"); 1040