^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for NXP MCR20A 802.15.4 Wireless-PAN Networking controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2018 Xue Liu <liuxuenetmail@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ieee802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/mac802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <net/cfg802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "mcr20a.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SPI_COMMAND_BUFFER 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define REGISTER_READ BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define REGISTER_WRITE (0 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define REGISTER_ACCESS (0 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PACKET_BUFF_BURST_ACCESS BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define PACKET_BUFF_BYTE_ACCESS BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MCR20A_WRITE_REG(x) (x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MCR20A_READ_REG(x) (REGISTER_READ | (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define MCR20A_BURST_READ_PACKET_BUF (0xC0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MCR20A_BURST_WRITE_PACKET_BUF (0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MCR20A_CMD_REG 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MCR20A_CMD_REG_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MCR20A_CMD_WRITE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MCR20A_CMD_FB 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Number of Interrupt Request Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MCR20A_IRQSTS_NUM 2 /* only IRQ_STS1 and IRQ_STS2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* MCR20A CCA Type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) MCR20A_CCA_ED, // energy detect - CCA bit not active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) // not to be used for T and CCCA sequences
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) MCR20A_CCA_MODE1, // energy detect - CCA bit ACTIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MCR20A_CCA_MODE2, // 802.15.4 compliant signal detect - CCA bit ACTIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) MCR20A_CCA_MODE3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) MCR20A_XCVSEQ_IDLE = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) MCR20A_XCVSEQ_RX = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) MCR20A_XCVSEQ_TX = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) MCR20A_XCVSEQ_CCA = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) MCR20A_XCVSEQ_TR = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) MCR20A_XCVSEQ_CCCA = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define MCR20A_MIN_CHANNEL (11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define MCR20A_MAX_CHANNEL (26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MCR20A_CHANNEL_SPACING (5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* MCR20A CCA Threshold constans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define MCR20A_MIN_CCA_THRESHOLD (0x6EU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define MCR20A_MAX_CCA_THRESHOLD (0x00U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* version 0C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define MCR20A_OVERWRITE_VERSION (0x0C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* MCR20A PLL configurations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static const u8 PLL_INT[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* 2405 */ 0x0B, /* 2410 */ 0x0B, /* 2415 */ 0x0B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* 2420 */ 0x0B, /* 2425 */ 0x0B, /* 2430 */ 0x0B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* 2435 */ 0x0C, /* 2440 */ 0x0C, /* 2445 */ 0x0C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* 2450 */ 0x0C, /* 2455 */ 0x0C, /* 2460 */ 0x0C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* 2465 */ 0x0D, /* 2470 */ 0x0D, /* 2475 */ 0x0D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* 2480 */ 0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static const u8 PLL_FRAC[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* 2405 */ 0x28, /* 2410 */ 0x50, /* 2415 */ 0x78,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* 2420 */ 0xA0, /* 2425 */ 0xC8, /* 2430 */ 0xF0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* 2435 */ 0x18, /* 2440 */ 0x40, /* 2445 */ 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* 2450 */ 0x90, /* 2455 */ 0xB8, /* 2460 */ 0xE0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* 2465 */ 0x08, /* 2470 */ 0x30, /* 2475 */ 0x58,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* 2480 */ 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static const struct reg_sequence mar20a_iar_overwrites[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) { IAR_MISC_PAD_CTRL, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) { IAR_VCO_CTRL1, 0xB3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) { IAR_VCO_CTRL2, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) { IAR_PA_TUNING, 0x71 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) { IAR_CHF_IBUF, 0x2F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) { IAR_CHF_QBUF, 0x2F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) { IAR_CHF_IRIN, 0x24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) { IAR_CHF_QRIN, 0x24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) { IAR_CHF_IL, 0x24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) { IAR_CHF_QL, 0x24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) { IAR_CHF_CC1, 0x32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) { IAR_CHF_CCL, 0x1D },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) { IAR_CHF_CC2, 0x2D },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) { IAR_CHF_IROUT, 0x24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) { IAR_CHF_QROUT, 0x24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { IAR_PA_CAL, 0x28 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) { IAR_AGC_THR1, 0x55 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { IAR_AGC_THR2, 0x2D },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { IAR_ATT_RSSI1, 0x5F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) { IAR_ATT_RSSI2, 0x8F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { IAR_RSSI_OFFSET, 0x61 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) { IAR_CHF_PMA_GAIN, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) { IAR_CCA1_THRESH, 0x50 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) { IAR_CORR_NVAL, 0x13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) { IAR_ACKDELAY, 0x3D },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define MCR20A_VALID_CHANNELS (0x07FFF800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define MCR20A_MAX_BUF (127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define printdev(X) (&X->spi->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* regmap information for Direct Access Register (DAR) access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define MCR20A_DAR_WRITE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define MCR20A_DAR_READ 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define MCR20A_DAR_NUMREGS 0x3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* regmap information for Indirect Access Register (IAR) access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define MCR20A_IAR_ACCESS 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define MCR20A_IAR_NUMREGS 0xBEFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Read/Write SPI Commands for DAR and IAR registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define MCR20A_READSHORT(reg) ((reg) << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define MCR20A_WRITESHORT(reg) ((reg) << 1 | 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define MCR20A_READLONG(reg) (1 << 15 | (reg) << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define MCR20A_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Type definitions for link configuration of instantiable layers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define MCR20A_PHY_INDIRECT_QUEUE_SIZE (12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) mcr20a_dar_writeable(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case DAR_IRQ_STS1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case DAR_IRQ_STS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case DAR_IRQ_STS3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case DAR_PHY_CTRL1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case DAR_PHY_CTRL2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case DAR_PHY_CTRL3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) case DAR_PHY_CTRL4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case DAR_SRC_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case DAR_SRC_ADDRS_SUM_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case DAR_SRC_ADDRS_SUM_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case DAR_T3CMP_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) case DAR_T3CMP_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case DAR_T3CMP_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case DAR_T2PRIMECMP_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case DAR_T2PRIMECMP_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case DAR_T1CMP_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case DAR_T1CMP_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case DAR_T1CMP_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case DAR_T2CMP_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) case DAR_T2CMP_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case DAR_T2CMP_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case DAR_T4CMP_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case DAR_T4CMP_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case DAR_T4CMP_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case DAR_PLL_INT0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case DAR_PLL_FRAC0_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case DAR_PLL_FRAC0_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case DAR_PA_PWR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* no DAR_ACM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case DAR_OVERWRITE_VER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case DAR_CLK_OUT_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case DAR_PWR_MODES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mcr20a_dar_readable(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bool rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* all writeable are also readable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) rc = mcr20a_dar_writeable(dev, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* readonly regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case DAR_RX_FRM_LEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case DAR_CCA1_ED_FNL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case DAR_EVENT_TMR_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case DAR_EVENT_TMR_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case DAR_EVENT_TMR_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) case DAR_TIMESTAMP_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case DAR_TIMESTAMP_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case DAR_TIMESTAMP_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case DAR_SEQ_STATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case DAR_LQI_VALUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) case DAR_RSSI_CCA_CONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mcr20a_dar_volatile(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* can be changed during runtime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) case DAR_IRQ_STS1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case DAR_IRQ_STS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case DAR_IRQ_STS3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* use them in spi_async and regmap so it's volatile */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mcr20a_dar_precious(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* don't clear irq line on read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case DAR_IRQ_STS1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case DAR_IRQ_STS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case DAR_IRQ_STS3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static const struct regmap_config mcr20a_dar_regmap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .name = "mcr20a_dar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .write_flag_mask = REGISTER_ACCESS | REGISTER_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .read_flag_mask = REGISTER_ACCESS | REGISTER_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .writeable_reg = mcr20a_dar_writeable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .readable_reg = mcr20a_dar_readable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .volatile_reg = mcr20a_dar_volatile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .precious_reg = mcr20a_dar_precious,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .can_multi_write = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) mcr20a_iar_writeable(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case IAR_XTAL_TRIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case IAR_PMC_LP_TRIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case IAR_MACPANID0_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case IAR_MACPANID0_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case IAR_MACSHORTADDRS0_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case IAR_MACSHORTADDRS0_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case IAR_MACLONGADDRS0_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case IAR_MACLONGADDRS0_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case IAR_MACLONGADDRS0_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case IAR_MACLONGADDRS0_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case IAR_MACLONGADDRS0_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case IAR_MACLONGADDRS0_40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) case IAR_MACLONGADDRS0_48:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case IAR_MACLONGADDRS0_56:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case IAR_RX_FRAME_FILTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case IAR_PLL_INT1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case IAR_PLL_FRAC1_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case IAR_PLL_FRAC1_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case IAR_MACPANID1_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case IAR_MACPANID1_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case IAR_MACSHORTADDRS1_LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) case IAR_MACSHORTADDRS1_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case IAR_MACLONGADDRS1_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case IAR_MACLONGADDRS1_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case IAR_MACLONGADDRS1_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) case IAR_MACLONGADDRS1_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) case IAR_MACLONGADDRS1_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case IAR_MACLONGADDRS1_40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) case IAR_MACLONGADDRS1_48:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) case IAR_MACLONGADDRS1_56:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case IAR_DUAL_PAN_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case IAR_DUAL_PAN_DWELL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case IAR_CCA1_THRESH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) case IAR_CCA1_ED_OFFSET_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case IAR_LQI_OFFSET_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case IAR_CCA_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case IAR_CCA2_CORR_PEAKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case IAR_CCA2_CORR_THRESH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case IAR_TMR_PRESCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) case IAR_ANT_PAD_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case IAR_MISC_PAD_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case IAR_BSM_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) case IAR_RNG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) case IAR_RX_WTR_MARK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case IAR_SOFT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case IAR_TXDELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case IAR_ACKDELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case IAR_CORR_NVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) case IAR_ANT_AGC_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case IAR_AGC_THR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case IAR_AGC_THR2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) case IAR_PA_CAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case IAR_ATT_RSSI1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case IAR_ATT_RSSI2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) case IAR_RSSI_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) case IAR_XTAL_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case IAR_CHF_PMA_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) case IAR_CHF_IBUF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case IAR_CHF_QBUF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) case IAR_CHF_IRIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) case IAR_CHF_QRIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case IAR_CHF_IL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) case IAR_CHF_QL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case IAR_CHF_CC1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case IAR_CHF_CCL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case IAR_CHF_CC2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case IAR_CHF_IROUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case IAR_CHF_QROUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case IAR_PA_TUNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case IAR_VCO_CTRL1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case IAR_VCO_CTRL2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mcr20a_iar_readable(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) bool rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* all writeable are also readable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) rc = mcr20a_iar_writeable(dev, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* readonly regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case IAR_PART_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case IAR_DUAL_PAN_STS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case IAR_RX_BYTE_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case IAR_FILTERFAIL_CODE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case IAR_FILTERFAIL_CODE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case IAR_RSSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mcr20a_iar_volatile(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* can be changed during runtime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case IAR_DUAL_PAN_STS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case IAR_RX_BYTE_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case IAR_FILTERFAIL_CODE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case IAR_FILTERFAIL_CODE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case IAR_RSSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static const struct regmap_config mcr20a_iar_regmap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .name = "mcr20a_iar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .reg_bits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .write_flag_mask = REGISTER_ACCESS | REGISTER_WRITE | IAR_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .read_flag_mask = REGISTER_ACCESS | REGISTER_READ | IAR_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .writeable_reg = mcr20a_iar_writeable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .readable_reg = mcr20a_iar_readable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .volatile_reg = mcr20a_iar_volatile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct mcr20a_local {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct spi_device *spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct ieee802154_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct regmap *regmap_dar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct regmap *regmap_iar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) bool is_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* for writing tx buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct spi_message tx_buf_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) u8 tx_header[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* burst buffer write command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct spi_transfer tx_xfer_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) u8 tx_len[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* len of tx packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct spi_transfer tx_xfer_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* data of tx packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct spi_transfer tx_xfer_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct sk_buff *tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* for read length rxfifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct spi_message reg_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) u8 reg_cmd[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) u8 reg_data[MCR20A_IRQSTS_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct spi_transfer reg_xfer_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct spi_transfer reg_xfer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* receive handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct spi_message rx_buf_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) u8 rx_header[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct spi_transfer rx_xfer_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) u8 rx_lqi[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct spi_transfer rx_xfer_lqi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) u8 rx_buf[MCR20A_MAX_BUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct spi_transfer rx_xfer_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* isr handling for reading intstat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct spi_message irq_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) u8 irq_header[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) u8 irq_data[MCR20A_IRQSTS_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct spi_transfer irq_xfer_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct spi_transfer irq_xfer_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) mcr20a_write_tx_buf_complete(void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct mcr20a_local *lp = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) lp->reg_msg.complete = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_PHY_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) lp->reg_data[0] = MCR20A_XCVSEQ_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) lp->reg_xfer_data.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ret = spi_async(lp->spi, &lp->reg_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dev_err(printdev(lp), "failed to set SEQ TX\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) mcr20a_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) lp->tx_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) print_hex_dump_debug("mcr20a tx: ", DUMP_PREFIX_OFFSET, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) skb->data, skb->len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) lp->is_tx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) lp->reg_msg.complete = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_PHY_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) lp->reg_data[0] = MCR20A_XCVSEQ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) lp->reg_xfer_data.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return spi_async(lp->spi, &lp->reg_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) mcr20a_ed(struct ieee802154_hw *hw, u8 *level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) WARN_ON(!level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) *level = 0xbe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) mcr20a_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* freqency = ((PLL_INT+64) + (PLL_FRAC/65536)) * 32 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ret = regmap_write(lp->regmap_dar, DAR_PLL_INT0, PLL_INT[channel - 11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = regmap_write(lp->regmap_dar, DAR_PLL_FRAC0_LSB, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ret = regmap_write(lp->regmap_dar, DAR_PLL_FRAC0_MSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) PLL_FRAC[channel - 11]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) mcr20a_start(struct ieee802154_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* No slotted operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dev_dbg(printdev(lp), "no slotted operation\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) DAR_PHY_CTRL1_SLOTTED, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* enable irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) enable_irq(lp->spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* Unmask SEQ interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) DAR_PHY_CTRL2_SEQMSK, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /* Start the RX sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) dev_dbg(printdev(lp), "start the RX sequence\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) mcr20a_stop(struct ieee802154_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* stop all running sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* disable irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) disable_irq(lp->spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) mcr20a_set_hw_addr_filt(struct ieee802154_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct ieee802154_hw_addr_filt *filt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) unsigned long changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) u16 addr = le16_to_cpu(filt->short_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) regmap_write(lp->regmap_iar, IAR_MACSHORTADDRS0_LSB, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) regmap_write(lp->regmap_iar, IAR_MACSHORTADDRS0_MSB, addr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (changed & IEEE802154_AFILT_PANID_CHANGED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) u16 pan = le16_to_cpu(filt->pan_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) regmap_write(lp->regmap_iar, IAR_MACPANID0_LSB, pan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) regmap_write(lp->regmap_iar, IAR_MACPANID0_MSB, pan >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) u8 addr[8], i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) memcpy(addr, &filt->ieee_addr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) for (i = 0; i < 8; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) regmap_write(lp->regmap_iar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) IAR_MACLONGADDRS0_0 + i, addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (changed & IEEE802154_AFILT_PANC_CHANGED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (filt->pan_coord) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) DAR_PHY_CTRL4_PANCORDNTR0, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) DAR_PHY_CTRL4_PANCORDNTR0, 0x00);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* -30 dBm to 10 dBm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) #define MCR20A_MAX_TX_POWERS 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static const s32 mcr20a_powers[MCR20A_MAX_TX_POWERS + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) -3000, -2800, -2600, -2400, -2200, -2000, -1800, -1600, -1400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) -1200, -1000, -800, -600, -400, -200, 0, 200, 400, 600, 800, 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) mcr20a_set_txpower(struct ieee802154_hw *hw, s32 mbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dev_dbg(printdev(lp), "%s(%d)\n", __func__, mbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) for (i = 0; i < lp->hw->phy->supported.tx_powers_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (lp->hw->phy->supported.tx_powers[i] == mbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return regmap_write(lp->regmap_dar, DAR_PA_PWR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ((i + 8) & 0x1F));
^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) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) #define MCR20A_MAX_ED_LEVELS MCR20A_MIN_CCA_THRESHOLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static s32 mcr20a_ed_levels[MCR20A_MAX_ED_LEVELS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) mcr20a_set_cca_mode(struct ieee802154_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) const struct wpan_phy_cca *cca)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) unsigned int cca_mode = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) bool cca_mode_and = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* mapping 802.15.4 to driver spec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) switch (cca->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) case NL802154_CCA_ENERGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) cca_mode = MCR20A_CCA_MODE1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) case NL802154_CCA_CARRIER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) cca_mode = MCR20A_CCA_MODE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case NL802154_CCA_ENERGY_CARRIER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) switch (cca->opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) case NL802154_CCA_OPT_ENERGY_CARRIER_AND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) cca_mode = MCR20A_CCA_MODE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) cca_mode_and = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) case NL802154_CCA_OPT_ENERGY_CARRIER_OR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) cca_mode = MCR20A_CCA_MODE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) cca_mode_and = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) DAR_PHY_CTRL4_CCATYPE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) cca_mode << DAR_PHY_CTRL4_CCATYPE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (cca_mode == MCR20A_CCA_MODE3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (cca_mode_and) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ret = regmap_update_bits(lp->regmap_iar, IAR_CCA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) IAR_CCA_CTRL_CCA3_AND_NOT_OR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = regmap_update_bits(lp->regmap_iar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) IAR_CCA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) IAR_CCA_CTRL_CCA3_AND_NOT_OR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) mcr20a_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) for (i = 0; i < hw->phy->supported.cca_ed_levels_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (hw->phy->supported.cca_ed_levels[i] == mbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return regmap_write(lp->regmap_iar, IAR_CCA1_THRESH, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) mcr20a_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct mcr20a_local *lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) u8 rx_frame_filter_reg = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) dev_dbg(printdev(lp), "%s(%d)\n", __func__, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* All frame types accepted*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) rx_frame_filter_reg &= ~(IAR_RX_FRAME_FLT_FRM_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) rx_frame_filter_reg |= (IAR_RX_FRAME_FLT_ACK_FT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) IAR_RX_FRAME_FLT_NS_FT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) DAR_PHY_CTRL4_PROMISCUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) DAR_PHY_CTRL4_PROMISCUOUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) rx_frame_filter_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) DAR_PHY_CTRL4_PROMISCUOUS, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) IAR_RX_FRAME_FLT_FRM_VER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) IAR_RX_FRAME_FLT_BEACON_FT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) IAR_RX_FRAME_FLT_DATA_FT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) IAR_RX_FRAME_FLT_CMD_FT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static const struct ieee802154_ops mcr20a_hw_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .xmit_async = mcr20a_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .ed = mcr20a_ed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) .set_channel = mcr20a_set_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) .start = mcr20a_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .stop = mcr20a_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .set_hw_addr_filt = mcr20a_set_hw_addr_filt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .set_txpower = mcr20a_set_txpower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .set_cca_mode = mcr20a_set_cca_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) .set_cca_ed_level = mcr20a_set_cca_ed_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .set_promiscuous_mode = mcr20a_set_promiscuous_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) mcr20a_request_rx(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* Start the RX sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) regmap_update_bits_async(lp->regmap_dar, DAR_PHY_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) mcr20a_handle_rx_read_buf_complete(void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct mcr20a_local *lp = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) u8 len = lp->reg_data[0] & DAR_RX_FRAME_LENGTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dev_dbg(printdev(lp), "RX is done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (!ieee802154_is_valid_psdu_len(len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev_vdbg(&lp->spi->dev, "corrupted frame received\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) len = IEEE802154_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) len = len - 2; /* get rid of frame check field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) skb = dev_alloc_skb(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) __skb_put_data(skb, lp->rx_buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ieee802154_rx_irqsafe(lp->hw, skb, lp->rx_lqi[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) print_hex_dump_debug("mcr20a rx: ", DUMP_PREFIX_OFFSET, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) lp->rx_buf, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) pr_debug("mcr20a rx: lqi: %02hhx\n", lp->rx_lqi[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* start RX sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) mcr20a_request_rx(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) mcr20a_handle_rx_read_len_complete(void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct mcr20a_local *lp = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) u8 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* get the length of received frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) len = lp->reg_data[0] & DAR_RX_FRAME_LENGTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) dev_dbg(printdev(lp), "frame len : %d\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /* prepare to read the rx buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) lp->rx_buf_msg.complete = mcr20a_handle_rx_read_buf_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) lp->rx_header[0] = MCR20A_BURST_READ_PACKET_BUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) lp->rx_xfer_buf.len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ret = spi_async(lp->spi, &lp->rx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) dev_err(printdev(lp), "failed to read rx buffer length\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) mcr20a_handle_rx(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) lp->reg_msg.complete = mcr20a_handle_rx_read_len_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) lp->reg_cmd[0] = MCR20A_READ_REG(DAR_RX_FRM_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) lp->reg_xfer_data.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return spi_async(lp->spi, &lp->reg_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) mcr20a_handle_tx_complete(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) ieee802154_xmit_complete(lp->hw, lp->tx_skb, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return mcr20a_request_rx(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) mcr20a_handle_tx(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /* write tx buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) lp->tx_header[0] = MCR20A_BURST_WRITE_PACKET_BUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /* add 2 bytes of FCS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) lp->tx_len[0] = lp->tx_skb->len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) lp->tx_xfer_buf.tx_buf = lp->tx_skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /* add 1 byte psduLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) lp->tx_xfer_buf.len = lp->tx_skb->len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) ret = spi_async(lp->spi, &lp->tx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) dev_err(printdev(lp), "SPI write Failed for TX buf\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) mcr20a_irq_clean_complete(void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct mcr20a_local *lp = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u8 seq_state = lp->irq_data[DAR_IRQ_STS1] & DAR_PHY_CTRL1_XCVSEQ_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) enable_irq(lp->spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev_dbg(printdev(lp), "IRQ STA1 (%02x) STA2 (%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) lp->irq_data[DAR_IRQ_STS1], lp->irq_data[DAR_IRQ_STS2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) switch (seq_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /* TX IRQ, RX IRQ and SEQ IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) case (DAR_IRQSTS1_TXIRQ | DAR_IRQSTS1_SEQIRQ):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (lp->is_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) lp->is_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) dev_dbg(printdev(lp), "TX is done. No ACK\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) mcr20a_handle_tx_complete(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) case (DAR_IRQSTS1_RXIRQ | DAR_IRQSTS1_SEQIRQ):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* rx is starting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) dev_dbg(printdev(lp), "RX is starting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) mcr20a_handle_rx(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) case (DAR_IRQSTS1_RXIRQ | DAR_IRQSTS1_TXIRQ | DAR_IRQSTS1_SEQIRQ):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (lp->is_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* tx is done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) lp->is_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) dev_dbg(printdev(lp), "TX is done. Get ACK\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) mcr20a_handle_tx_complete(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /* rx is starting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) dev_dbg(printdev(lp), "RX is starting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) mcr20a_handle_rx(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case (DAR_IRQSTS1_SEQIRQ):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (lp->is_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) dev_dbg(printdev(lp), "TX is starting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) mcr20a_handle_tx(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) dev_dbg(printdev(lp), "MCR20A is stop\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) static void mcr20a_irq_status_complete(void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct mcr20a_local *lp = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) regmap_update_bits_async(lp->regmap_dar, DAR_PHY_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) lp->reg_msg.complete = mcr20a_irq_clean_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) lp->reg_cmd[0] = MCR20A_WRITE_REG(DAR_IRQ_STS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) memcpy(lp->reg_data, lp->irq_data, MCR20A_IRQSTS_NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) lp->reg_xfer_data.len = MCR20A_IRQSTS_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ret = spi_async(lp->spi, &lp->reg_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) dev_err(printdev(lp), "failed to clean irq status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static irqreturn_t mcr20a_irq_isr(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct mcr20a_local *lp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) disable_irq_nosync(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) lp->irq_header[0] = MCR20A_READ_REG(DAR_IRQ_STS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* read IRQSTSx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) ret = spi_async(lp->spi, &lp->irq_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) enable_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static void mcr20a_hw_setup(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct ieee802154_hw *hw = lp->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct wpan_phy *phy = lp->hw->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) phy->symbol_duration = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) phy->lifs_period = 40 * phy->symbol_duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) phy->sifs_period = 12 * phy->symbol_duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) hw->flags = IEEE802154_HW_TX_OMIT_CKSUM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) IEEE802154_HW_AFILT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) IEEE802154_HW_PROMISCUOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) WPAN_PHY_FLAG_CCA_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) BIT(NL802154_CCA_CARRIER) | BIT(NL802154_CCA_ENERGY_CARRIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) BIT(NL802154_CCA_OPT_ENERGY_CARRIER_OR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* initiating cca_ed_levels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) for (i = MCR20A_MAX_CCA_THRESHOLD; i < MCR20A_MIN_CCA_THRESHOLD + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) mcr20a_ed_levels[i] = -i * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) phy->supported.cca_ed_levels = mcr20a_ed_levels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) phy->supported.cca_ed_levels_size = ARRAY_SIZE(mcr20a_ed_levels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) phy->cca.mode = NL802154_CCA_ENERGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) phy->supported.channels[0] = MCR20A_VALID_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) phy->current_page = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* MCR20A default reset value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) phy->current_channel = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) phy->symbol_duration = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) phy->supported.tx_powers = mcr20a_powers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) phy->supported.tx_powers_size = ARRAY_SIZE(mcr20a_powers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) phy->cca_ed_level = phy->supported.cca_ed_levels[75];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) phy->transmit_power = phy->supported.tx_powers[0x0F];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) mcr20a_setup_tx_spi_messages(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) spi_message_init(&lp->tx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) lp->tx_buf_msg.context = lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) lp->tx_buf_msg.complete = mcr20a_write_tx_buf_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) lp->tx_xfer_header.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) lp->tx_xfer_header.tx_buf = lp->tx_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) lp->tx_xfer_len.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) lp->tx_xfer_len.tx_buf = lp->tx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) spi_message_add_tail(&lp->tx_xfer_header, &lp->tx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) spi_message_add_tail(&lp->tx_xfer_len, &lp->tx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) spi_message_add_tail(&lp->tx_xfer_buf, &lp->tx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) mcr20a_setup_rx_spi_messages(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) spi_message_init(&lp->reg_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) lp->reg_msg.context = lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) lp->reg_xfer_cmd.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) lp->reg_xfer_cmd.tx_buf = lp->reg_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) lp->reg_xfer_cmd.rx_buf = lp->reg_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) lp->reg_xfer_data.rx_buf = lp->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) lp->reg_xfer_data.tx_buf = lp->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) spi_message_add_tail(&lp->reg_xfer_cmd, &lp->reg_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) spi_message_add_tail(&lp->reg_xfer_data, &lp->reg_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) spi_message_init(&lp->rx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) lp->rx_buf_msg.context = lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) lp->rx_buf_msg.complete = mcr20a_handle_rx_read_buf_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) lp->rx_xfer_header.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) lp->rx_xfer_header.tx_buf = lp->rx_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) lp->rx_xfer_header.rx_buf = lp->rx_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) lp->rx_xfer_buf.rx_buf = lp->rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) lp->rx_xfer_lqi.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) lp->rx_xfer_lqi.rx_buf = lp->rx_lqi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) spi_message_add_tail(&lp->rx_xfer_header, &lp->rx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) spi_message_add_tail(&lp->rx_xfer_buf, &lp->rx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) spi_message_add_tail(&lp->rx_xfer_lqi, &lp->rx_buf_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) mcr20a_setup_irq_spi_messages(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) spi_message_init(&lp->irq_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) lp->irq_msg.context = lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) lp->irq_msg.complete = mcr20a_irq_status_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) lp->irq_xfer_header.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) lp->irq_xfer_header.tx_buf = lp->irq_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) lp->irq_xfer_header.rx_buf = lp->irq_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) lp->irq_xfer_data.len = MCR20A_IRQSTS_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) lp->irq_xfer_data.rx_buf = lp->irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) spi_message_add_tail(&lp->irq_xfer_header, &lp->irq_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) spi_message_add_tail(&lp->irq_xfer_data, &lp->irq_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) mcr20a_phy_init(struct mcr20a_local *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) unsigned int phy_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) dev_dbg(printdev(lp), "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /* Disable Tristate on COCO MISO for SPI reads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ret = regmap_write(lp->regmap_iar, IAR_MISC_PAD_CTRL, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /* Clear all PP IRQ bits in IRQSTS1 to avoid unexpected interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * immediately after init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS1, 0xEF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /* Clear all PP IRQ bits in IRQSTS2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) DAR_IRQSTS2_ASM_IRQ | DAR_IRQSTS2_PB_ERR_IRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) DAR_IRQSTS2_WAKE_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* Disable all timer interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ret = regmap_write(lp->regmap_dar, DAR_IRQ_STS3, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) /* PHY_CTRL1 : default HW settings + AUTOACK enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) DAR_PHY_CTRL1_AUTOACK, DAR_PHY_CTRL1_AUTOACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /* PHY_CTRL2 : disable all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) ret = regmap_write(lp->regmap_dar, DAR_PHY_CTRL2, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) /* PHY_CTRL3 : disable all timers and remaining interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) ret = regmap_write(lp->regmap_dar, DAR_PHY_CTRL3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) DAR_PHY_CTRL3_ASM_MSK | DAR_PHY_CTRL3_PB_ERR_MSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) DAR_PHY_CTRL3_WAKE_MSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /* SRC_CTRL : enable Acknowledge Frame Pending and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * Source Address Matching Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) ret = regmap_write(lp->regmap_dar, DAR_SRC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) DAR_SRC_CTRL_ACK_FRM_PND |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) (DAR_SRC_CTRL_INDEX << DAR_SRC_CTRL_INDEX_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* RX_FRAME_FILTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /* FRM_VER[1:0] = b11. Accept FrameVersion 0 and 1 packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ret = regmap_write(lp->regmap_iar, IAR_RX_FRAME_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) IAR_RX_FRAME_FLT_FRM_VER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) IAR_RX_FRAME_FLT_BEACON_FT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) IAR_RX_FRAME_FLT_DATA_FT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) IAR_RX_FRAME_FLT_CMD_FT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) dev_info(printdev(lp), "MCR20A DAR overwrites version: 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) MCR20A_OVERWRITE_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /* Overwrites direct registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) ret = regmap_write(lp->regmap_dar, DAR_OVERWRITE_VER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) MCR20A_OVERWRITE_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) /* Overwrites indirect registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) ret = regmap_multi_reg_write(lp->regmap_iar, mar20a_iar_overwrites,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) ARRAY_SIZE(mar20a_iar_overwrites));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) /* Clear HW indirect queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) dev_dbg(printdev(lp), "clear HW indirect queue\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) for (index = 0; index < MCR20A_PHY_INDIRECT_QUEUE_SIZE; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) phy_reg = (u8)(((index & DAR_SRC_CTRL_INDEX) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) DAR_SRC_CTRL_INDEX_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) | (DAR_SRC_CTRL_SRCADDR_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) | (DAR_SRC_CTRL_INDEX_DISABLE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) ret = regmap_write(lp->regmap_dar, DAR_SRC_CTRL, phy_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) phy_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /* Assign HW Indirect hash table to PAN0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ret = regmap_read(lp->regmap_iar, IAR_DUAL_PAN_CTRL, &phy_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* Clear current lvl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) phy_reg &= ~IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* Set new lvl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) phy_reg |= MCR20A_PHY_INDIRECT_QUEUE_SIZE <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) IAR_DUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ret = regmap_write(lp->regmap_iar, IAR_DUAL_PAN_CTRL, phy_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) /* Set CCA threshold to -75 dBm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) ret = regmap_write(lp->regmap_iar, IAR_CCA1_THRESH, 0x4B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) /* Set prescaller to obtain 1 symbol (16us) timebase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) ret = regmap_write(lp->regmap_iar, IAR_TMR_PRESCALE, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* Enable autodoze mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) ret = regmap_update_bits(lp->regmap_dar, DAR_PWR_MODES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) DAR_PWR_MODES_AUTODOZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) DAR_PWR_MODES_AUTODOZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* Disable clk_out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) ret = regmap_update_bits(lp->regmap_dar, DAR_CLK_OUT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) DAR_CLK_OUT_CTRL_EN, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) err_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) mcr20a_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) struct ieee802154_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct mcr20a_local *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct gpio_desc *rst_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) dev_dbg(&spi->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (!spi->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) dev_err(&spi->dev, "no IRQ specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) rst_b = devm_gpiod_get(&spi->dev, "rst_b", GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (IS_ERR(rst_b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ret = PTR_ERR(rst_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) dev_err(&spi->dev, "Failed to get 'rst_b' gpio: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /* reset mcr20a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) gpiod_set_value_cansleep(rst_b, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) gpiod_set_value_cansleep(rst_b, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) usleep_range(120, 240);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) /* allocate ieee802154_hw and private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) hw = ieee802154_alloc_hw(sizeof(*lp), &mcr20a_hw_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (!hw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) dev_crit(&spi->dev, "ieee802154_alloc_hw failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /* init mcr20a local data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) lp = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) lp->hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) lp->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) /* init ieee802154_hw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) hw->parent = &spi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) /* init buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) lp->buf = devm_kzalloc(&spi->dev, SPI_COMMAND_BUFFER, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (!lp->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) goto free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) mcr20a_setup_tx_spi_messages(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) mcr20a_setup_rx_spi_messages(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) mcr20a_setup_irq_spi_messages(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) /* setup regmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) lp->regmap_dar = devm_regmap_init_spi(spi, &mcr20a_dar_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (IS_ERR(lp->regmap_dar)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) ret = PTR_ERR(lp->regmap_dar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) dev_err(&spi->dev, "Failed to allocate dar map: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) goto free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) lp->regmap_iar = devm_regmap_init_spi(spi, &mcr20a_iar_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (IS_ERR(lp->regmap_iar)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) ret = PTR_ERR(lp->regmap_iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) dev_err(&spi->dev, "Failed to allocate iar map: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) goto free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) mcr20a_hw_setup(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) spi_set_drvdata(spi, lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) ret = mcr20a_phy_init(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) dev_crit(&spi->dev, "mcr20a_phy_init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) goto free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) irq_type = irq_get_trigger_type(spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (!irq_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) irq_type = IRQF_TRIGGER_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ret = devm_request_irq(&spi->dev, spi->irq, mcr20a_irq_isr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) irq_type, dev_name(&spi->dev), lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) dev_err(&spi->dev, "could not request_irq for mcr20a\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) goto free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /* disable_irq by default and wait for starting hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) disable_irq(spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) ret = ieee802154_register_hw(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) dev_crit(&spi->dev, "ieee802154_register_hw failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) goto free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) free_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ieee802154_free_hw(lp->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) static int mcr20a_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) struct mcr20a_local *lp = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) dev_dbg(&spi->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) ieee802154_unregister_hw(lp->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) ieee802154_free_hw(lp->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) static const struct of_device_id mcr20a_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) { .compatible = "nxp,mcr20a", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) MODULE_DEVICE_TABLE(of, mcr20a_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static const struct spi_device_id mcr20a_device_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) { .name = "mcr20a", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) MODULE_DEVICE_TABLE(spi, mcr20a_device_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) static struct spi_driver mcr20a_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) .id_table = mcr20a_device_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) .of_match_table = of_match_ptr(mcr20a_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) .name = "mcr20a",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) .probe = mcr20a_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) .remove = mcr20a_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) module_spi_driver(mcr20a_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) MODULE_DESCRIPTION("MCR20A Transceiver Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) MODULE_AUTHOR("Xue Liu <liuxuenetmail@gmail>");