// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for NXP MCR20A 802.15.4 Wireless-PAN Networking controller
*
* Copyright (C) 2018 Xue Liu <liuxuenetmail@gmail.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio/consumer.h>
#include <linux/spi/spi.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/skbuff.h>
#include <linux/regmap.h>
#include <linux/ieee802154.h>
#include <linux/debugfs.h>
#include <net/mac802154.h>
#include <net/cfg802154.h>
#include <linux/device.h>
#include "mcr20a.h"
#define SPI_COMMAND_BUFFER 3
#define REGISTER_READ BIT(7)
#define REGISTER_WRITE (0 << 7)
#define REGISTER_ACCESS (0 << 6)
#define PACKET_BUFF_BURST_ACCESS BIT(6)
#define PACKET_BUFF_BYTE_ACCESS BIT(5)
#define MCR20A_WRITE_REG(x) (x)
#define MCR20A_READ_REG(x) (REGISTER_READ | (x))
#define MCR20A_BURST_READ_PACKET_BUF (0xC0)
#define MCR20A_BURST_WRITE_PACKET_BUF (0x40)
#define MCR20A_CMD_REG 0x80
#define MCR20A_CMD_REG_MASK 0x3f
#define MCR20A_CMD_WRITE 0x40
#define MCR20A_CMD_FB 0x20
/* Number of Interrupt Request Status Register */
#define MCR20A_IRQSTS_NUM 2 /* only IRQ_STS1 and IRQ_STS2 */
/* MCR20A CCA Type */
enum {
MCR20A_CCA_ED, // energy detect - CCA bit not active,
// not to be used for T and CCCA sequences
MCR20A_CCA_MODE1, // energy detect - CCA bit ACTIVE
MCR20A_CCA_MODE2, // 802.15.4 compliant signal detect - CCA bit ACTIVE
MCR20A_CCA_MODE3
};
enum {
MCR20A_XCVSEQ_IDLE = 0x00,
MCR20A_XCVSEQ_RX = 0x01,
MCR20A_XCVSEQ_TX = 0x02,
MCR20A_XCVSEQ_CCA = 0x03,
MCR20A_XCVSEQ_TR = 0x04,
MCR20A_XCVSEQ_CCCA = 0x05,
};
/* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
#define MCR20A_MIN_CHANNEL (11)
#define MCR20A_MAX_CHANNEL (26)
#define MCR20A_CHANNEL_SPACING (5)
/* MCR20A CCA Threshold constans */
#define MCR20A_MIN_CCA_THRESHOLD (0x6EU)
#define MCR20A_MAX_CCA_THRESHOLD (0x00U)
/* version 0C */
#define MCR20A_OVERWRITE_VERSION (0x0C)
/* MCR20A PLL configurations */
static const u8 PLL_INT[16] = {
/* 2405 */ 0x0B, /* 2410 */ 0x0B, /* 2415 */ 0x0B,
/* 2420 */ 0x0B, /* 2425 */ 0x0B, /* 2430 */ 0x0B,
/* 2435 */ 0x0C, /* 2440 */ 0x0C, /* 2445 */ 0x0C,
/* 2450 */ 0x0C, /* 2455 */ 0x0C, /* 2460 */ 0x0C,
/* 2465 */ 0x0D, /* 2470 */ 0x0D, /* 2475 */ 0x0D,
/* 2480 */ 0x0D
};
static const u8 PLL_FRAC[16] = {
/* 2405 */ 0x28, /* 2410 */ 0x50, /* 2415 */ 0x78,
/* 2420 */ 0xA0, /* 2425 */ 0xC8, /* 2430 */ 0xF0,
/* 2435 */ 0x18, /* 2440 */ 0x40, /* 2445 */ 0x68,
/* 2450 */ 0x90, /* 2455 */ 0xB8, /* 2460 */ 0xE0,
/* 2465 */ 0x08, /* 2470 */ 0x30, /* 2475 */ 0x58,
/* 2480 */ 0x80
};
static const struct reg_sequence mar20a_iar_overwrites[] = {
{ IAR_MISC_PAD_CTRL, 0x02 },
{ IAR_VCO_CTRL1, 0xB3 },
{ IAR_VCO_CTRL2, 0x07 },
{ IAR_PA_TUNING, 0x71 },
{ IAR_CHF_IBUF, 0x2F },
{ IAR_CHF_QBUF, 0x2F },
{ IAR_CHF_IRIN, 0x24 },
{ IAR_CHF_QRIN,<