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