blob: 4495a2d37f4f162831c14bbec8a0e4aad345623a [file] [log] [blame]
/*
* This file is part of the UWB stack for linux.
*
* Copyright (c) 2020-2021 Qorvo US, Inc.
*
* This software is provided under the GNU General Public License, version 2
* (GPLv2), as well as under a Qorvo commercial license.
*
* You may choose to use this software under the terms of the GPLv2 License,
* version 2 ("GPLv2"), as published by the Free Software Foundation.
* You should have received a copy of the GPLv2 along with this program. If
* not, see <http://www.gnu.org/licenses/>.
*
* This program is distributed under the GPLv2 in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPLv2 for more
* details.
*
* If you cannot meet the requirements of the GPLv2, you may not use this
* software for any purpose without first obtaining a commercial license from
* Qorvo. Please contact Qorvo to inquire about licensing terms.
*/
#ifndef __DW3000_H
#define __DW3000_H
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/skbuff.h>
#include <net/mcps802154.h>
#include <linux/pm_qos.h>
#include <linux/regulator/consumer.h>
#include "dw3000_chip.h"
#include "dw3000_stm.h"
#include "dw3000_calib.h"
#include "dw3000_testmode_nl.h"
#include "dw3000_nfcc_coex.h"
#include "dw3000_pctt.h"
#include "dw3000_debugfs.h"
#undef BIT_MASK
#ifndef DEBUG
#define DEBUG 0
#endif
#define LOG(format, arg...) \
do { \
pr_info("dw3000: %s(): " format "\n", __func__, ##arg); \
} while (0)
extern unsigned dw3000_regulator_delay_us;
/* Defined constants when SPI CRC mode is used */
enum dw3000_spi_crc_mode {
DW3000_SPI_CRC_MODE_NO = 0, /* No CRC */
DW3000_SPI_CRC_MODE_WR, /* This is used to enable SPI CRC check (the SPI
CRC check will be enabled on DW3000 and CRC-8
added for SPI write transactions) */
DW3000_SPI_CRC_MODE_WRRD /* This is used to optionally enable additional
CRC check on the SPI read operations, while
the CRC check on the SPI write operations is
also enabled */
};
/* ISR data */
struct dw3000_isr_data {
u64 status; /* initial value of register as ISR is entered */
u16 datalength; /* length of frame */
u64 ts_rctu; /* frame timestamp in RCTU unit */
u8 dss_stat; /* value of the dual-SPI semaphore events */
u8 rx_flags; /* RX frame flags, see dw3000_rx_flags */
};
/* Time units and conversion factor */
#define DW3000_DTU_PER_SYS_POWER 4
#define DW3000_CHIP_FREQ 499200000
#define DW3000_CHIP_PER_SYS 2
#define DW3000_CHIP_PER_DTU \
(DW3000_CHIP_PER_SYS * (1 << DW3000_DTU_PER_SYS_POWER))
#define DW3000_CHIP_PER_DLY 512
#define DW3000_RCTU_PER_CHIP 128
#define DW3000_RCTU_PER_DTU (DW3000_RCTU_PER_CHIP * DW3000_CHIP_PER_DTU)
#define DW3000_RCTU_PER_SYS (DW3000_RCTU_PER_CHIP * DW3000_CHIP_PER_SYS)
#define DW3000_RCTU_PER_DLY (DW3000_CHIP_PER_DLY / DW3000_RCTU_PER_CHIP)
#define DW3000_DTU_FREQ (DW3000_CHIP_FREQ / DW3000_CHIP_PER_DTU)
/* 6.9.1.5 in 4z, for HRP UWB PHY:
416 chips = 416 / (499.2 * 10^6) ~= 833.33 ns */
#define DW3000_DTU_PER_RSTU (416 / DW3000_CHIP_PER_DTU)
#define DW3000_DTU_PER_DLY (DW3000_CHIP_PER_DLY / DW3000_CHIP_PER_DTU)
#define DW3000_SYS_PER_DLY (DW3000_CHIP_PER_DLY / DW3000_CHIP_PER_SYS)
#define DW3000_ANTICIP_DTU (16 * (DW3000_DTU_FREQ / 1000))
#define DTU_TO_US(x) (int)((s64)(x)*1000000 / DW3000_DTU_FREQ)
#define US_TO_DTU(x) (u32)((s64)(x)*DW3000_DTU_FREQ / 1000000)
#define NS_TO_DTU(x) (u32)((s64)(x) * (DW3000_DTU_FREQ / 100000) / 10000)
#define DW3000_RX_ENABLE_STARTUP_DLY 16
#define DW3000_RX_ENABLE_STARTUP_DTU \
(DW3000_RX_ENABLE_STARTUP_DLY * DW3000_CHIP_PER_DLY / \
DW3000_CHIP_PER_DTU)
/* UWB High band 802.15.4a-2007. Only channels 5 & 9 for DW3000. */
#define DW3000_SUPPORTED_CHANNELS ((1 << 5) | (1 << 9))
/* Number of symbols of accumulation to wait before checking
for an SFD pattern, when Ipatov len > 64 */
#define DW3000_RX_SFD_HLDOFF 0x20
/* Default number of symbols of accumulation to wait before checking
for an SFD pattern */
#define DW3000_RX_SFD_HLDOFF_DEF 0x14
/**
* typedef dw3000_wakeup_done_cb - Wake up done handler.
* @dw: Driver context.
*
* Return: 0 on success, else an error.
*/
typedef int (*dw3000_wakeup_done_cb)(struct dw3000 *dw);
/**
* typedef dw3000_idle_timeout_cb - Idle timeout handler.
* @dw: Driver context.
*
* Return: 0 on success, else an error.
*/
typedef int (*dw3000_idle_timeout_cb)(struct dw3000 *dw);
/**
* struct dw3000_otp_data - data read from OTP memory of DW3000 device
* @partID: device part ID
* @lotID: device lot ID
* @ldo_tune_lo: tuned value used by chip specific prog_ldo_and_bias_tune
* @ldo_tune_hi: tuned value used by chip specific prog_ldo_and_bias_tune
* @bias_tune: tuned value used by chip specific prog_ldo_and_bias_tune
* @dgc_addr: dgc_addr value used by chip specific prog_ldo_and_bias_tune
* @xtal_trim: tuned value used by dw3000_prog_xtrim
* @vBatP: vBatP
* @tempP: tempP
* @rev: OTP revision
* @mode: Saved last OTP read mode to avoid multiple read
* @pll_coarse_code: PLL coarse code use by chip->prog_pll_coarse_code
*/
struct dw3000_otp_data {
u32 partID;
u32 lotID;
u32 ldo_tune_lo;
u32 ldo_tune_hi;
u32 bias_tune;
u32 dgc_addr;
u8 xtal_trim;
u8 vBatP;
u8 tempP;
u8 rev;
int mode;
u32 pll_coarse_code;
};
/**
* enum dw3000_ciagdiag_reg_select - CIA diagnostic register selector config.
* @DW3000_CIA_DIAG_REG_SELECT_WITHOUT_STS: without STS
* @DW3000_CIA_DIAG_REG_SELECT_WITH_STS: with STS
* @DW3000_CIA_DIAG_REG_SELECT_WITH_PDAO_M3: PDOA mode 3
*
* According to DW3000's configuration, we must read some values
* (e.g: channel impulse response power, preamble accumulation count)
* in different registers in the CIA interface.
*/
enum dw3000_ciagdiag_reg_select {
DW3000_CIA_DIAG_REG_SELECT_WITHOUT_STS = 0,
DW3000_CIA_DIAG_REG_SELECT_WITH_STS = 1,
DW3000_CIA_DIAG_REG_SELECT_WITH_PDAO_M3 = 2,
};
/**
* struct dw3000_local_data - Local data and register cache
* @spicrc: current SPI crc mode
* @ciadiag_reg_select: CIA diagnostic register selector according to DW3000's
* config
* @ciadiag_enabled: CIA diagnostic on/off
* @dgc_otp_set: true if DGC info is programmed into OTP
* @check_cfo: true when CFO checking is required for next RX frame
* @ack_time: Auto ack turnaroud time
* @dblbuffon: double buffering mode
* @xtal_bias: XTAL trimming adjustment value
* @max_frames_len: current configured max frame length
* @sleep_mode: bitfield for work to be done on wakeup
* @ststhreshold: current computed STS threshold
* @tx_fctrl: Transmit frame control
* @rx_timeout_pac: Preamble detection timeout period in units of PAC size
* symbols
* @rx_frame_timeout_dly: reception frame timeout period in units of dly.
* @w4r_time: Wait-for-response time (RX after TX delay)
* @sts_key: STS Key
* @sts_iv: STS IV
*/
struct dw3000_local_data {
enum dw3000_spi_crc_mode spicrc;
enum dw3000_ciagdiag_reg_select ciadiag_reg_select;
bool ciadiag_enabled : 1;
bool dgc_otp_set : 1;
bool check_cfo : 1;
u8 dblbuffon;
u8 ack_time;
s8 xtal_bias;
u16 sleep_mode;
u16 max_frames_len;
s16 ststhreshold;
u16 rx_timeout_pac;
u32 rx_frame_timeout_dly;
u32 tx_fctrl;
u32 w4r_time;
u8 sts_key[AES_KEYSIZE_128];
u8 sts_iv[AES_BLOCK_SIZE];
};
/* Statistics items */
enum dw3000_stats_items {
DW3000_STATS_RX_GOOD,
DW3000_STATS_RX_ERROR,
DW3000_STATS_RX_TO,
__DW3000_STATS_COUNT
};
/**
* struct dw3000_stats - DW3000 statistics
* @count: Count per-items
* @rssi: Last RSSI data per type
* @enabled: Stats enabled flag
* @indexes: Free-running index per-items
*/
struct dw3000_stats {
/* Total stats */
u16 count[__DW3000_STATS_COUNT];
/* Required data array for calculation of the RSSI average */
struct dw3000_rssi rssi[DW3000_RSSI_REPORTS_MAX];
/* Stats on/off */
bool enabled;
u16 indexes[__DW3000_STATS_COUNT];
};
/* Maximum skb length
*
* Maximum supported frame size minus the checksum.
*/
#define DW3000_MAX_SKB_LEN (IEEE802154_MAX_SIFS_FRAME_SIZE - IEEE802154_FCS_LEN)
/* Additional information on rx. */
enum dw3000_rx_flags {
/* Set if an automatic ack is send. */
DW3000_RX_FLAG_AACK = BIT(0),
/* Set if no data. */
DW3000_RX_FLAG_ND = BIT(1),
/* Set if timestamp known. */
DW3000_RX_FLAG_TS = BIT(2),
/* Ranging bit */
DW3000_RX_FLAG_RNG = BIT(3),
/* CIA done */
DW3000_RX_FLAG_CIA = BIT(4),
/* CIA error */
DW3000_RX_FLAG_CER = BIT(5),
/* STS error */
DW3000_RX_FLAG_CPER = BIT(6)
};
/* Receive descriptor */
struct dw3000_rx {
/* Receive lock */
spinlock_t lock;
/* Socket buffer */
struct sk_buff *skb;
/* Frame timestamp */
u64 ts_rctu;
/* Additional information on rx. See dw3000_rx_flags. */
u8 flags;
/* Busy flag */
u8 busy;
};
/* DW3000 STS length field of the CP_CFG register (unit of 8 symbols bloc) */
enum dw3000_sts_lengths {
DW3000_STS_LEN_8 = 0,
DW3000_STS_LEN_16 = 1,
DW3000_STS_LEN_32 = 2,
DW3000_STS_LEN_64 = 3,
DW3000_STS_LEN_128 = 4,
DW3000_STS_LEN_256 = 5,
DW3000_STS_LEN_512 = 6,
DW3000_STS_LEN_1024 = 7,
DW3000_STS_LEN_2048 = 8
};
/* DW3000 power supply structure */
struct dw3000_power_control {
/* Power supply generic */
struct regulator *regulator_vdd;
/* Power supply 1.8V */
struct regulator *regulator_1p8;
/* Power supply 2.5V */
struct regulator *regulator_2p5;
};
/**
* struct dw3000_config - Structure holding current device configuration
* @chan: Channel number (5 or 9)
* @txPreambLength: DW3000_PLEN_64..DW3000_PLEN_4096
* @txCode: TX preamble code (the code configures the PRF, e.g. 9 -> PRF of 64 MHz)
* @rxCode: RX preamble code (the code configures the PRF, e.g. 9 -> PRF of 64 MHz)
* @sfdType: SFD type (0 for short IEEE 8b standard, 1 for DW 8b, 2 for DW 16b, 2 for 4z BPRF)
* @dataRate: Data rate {DW3000_BR_850K or DW3000_BR_6M8}
* @phrMode: PHR mode {0x0 - standard DW3000_PHRMODE_STD, 0x3 - extended frames DW3000_PHRMODE_EXT}
* @phrRate: PHR rate {0x0 - standard DW3000_PHRRATE_STD, 0x1 - at datarate DW3000_PHRRATE_DTA}
* @sfdTO: SFD timeout value (in symbols)
* @stsMode: STS mode (no STS, STS before PHR or STS after data)
* @stsLength: STS length (see enum dw3000_sts_lengths)
* @pdoaMode: PDOA mode
* @ant: Antennas currently connected to RF1 & RF2 ports respectively
* @pdoaOffset: Calibrated PDOA offset
* @pdoaLut: Pointer to calibrated PDOA to AoA look-up table
* @rmarkerOffset: Calibrated rmarker offset
* @promisc: Promiscuous mode enabled?
* @alternate_pulse_shape: set alternate pulse shape
* @hw_addr_filt: HW filter configuration
*/
struct dw3000_config {
u8 chan;
u8 txPreambLength;
u8 txCode;
u8 rxCode;
u8 sfdType;
u8 dataRate;
u8 phrMode;
u8 phrRate;
u16 sfdTO;
u8 stsMode;
enum dw3000_sts_lengths stsLength;
u8 pdoaMode;
s8 ant[2];
s16 pdoaOffset;
const dw3000_pdoa_lut_t *pdoaLut;
u32 rmarkerOffset;
bool promisc;
bool alternate_pulse_shape;
struct ieee802154_hw_addr_filt hw_addr_filt;
};
/**
* struct dw3000_txconfig - Structure holding current TX configuration
* @PGdly: PG delay
* @PGcount: PG count
* @power: TX power for 1ms frame
* 31:24 TX_CP_PWR
* 23:16 TX_SHR_PWR
* 15:8 TX_PHR_PWR
* 7:0 TX_DATA_PWR
* @smart: TX smart power enabled flag
* @testmode_enabled: Normal or test mode
*/
struct dw3000_txconfig {
u8 PGdly;
u8 PGcount;
u32 power;
bool smart;
bool testmode_enabled;
};
enum operational_state {
DW3000_OP_STATE_OFF = 0,
DW3000_OP_STATE_DEEP_SLEEP,
DW3000_OP_STATE_SLEEP,
DW3000_OP_STATE_WAKE_UP,
DW3000_OP_STATE_INIT_RC,
DW3000_OP_STATE_IDLE_RC,
DW3000_OP_STATE_IDLE_PLL,
DW3000_OP_STATE_TX_WAIT,
DW3000_OP_STATE_TX,
DW3000_OP_STATE_RX_WAIT,
DW3000_OP_STATE_RX,
DW3000_OP_STATE_MAX,
};
/**
* struct sysfs_power_stats - DW3000 device power related data
* @dur: accumulated duration in selected state in ns except for RX/TX where
* duration is in DTU
* @count: number of time this state was active
*/
struct sysfs_power_stats {
u64 dur;
u64 count;
};
/**
* enum power_state - DW3000 device current power state
* @DW3000_PWR_OFF: DW3000 is OFF (unpowered or in reset)
* @DW3000_PWR_DEEPSLEEP: DW3000 is ACTIVE (started) but in DEEP SLEEP
* @DW3000_PWR_RUN: DW3000 is ACTIVE (include RX/TX state below)
* @DW3000_PWR_IDLE: DW3000 is ACTIVE but IDLE (only count is used for it)
* @DW3000_PWR_RX: DW3000 is currently RECEIVING
* @DW3000_PWR_TX: DW3000 is currently TRANSMITTING
* @DW3000_PWR_MAX: Number of power states stored in struct dw3000_power
*/
enum power_state {
DW3000_PWR_OFF = 0,
DW3000_PWR_DEEPSLEEP,
DW3000_PWR_RUN,
DW3000_PWR_IDLE,
DW3000_PWR_RX,
DW3000_PWR_TX,
DW3000_PWR_MAX,
};
/**
* enum config_changed_flags - values for configuration changed bitfield
* @DW3000_AFILT_SADDR_CHANGED: same as IEEE802154_AFILT_SADDR_CHANGED
* @DW3000_AFILT_IEEEADDR_CHANGED: same as IEEE802154_AFILT_IEEEADDR_CHANGED
* @DW3000_AFILT_PANID_CHANGED: same as IEEE802154_AFILT_PANID_CHANGED
* @DW3000_AFILT_PANC_CHANGED: same as IEEE802154_AFILT_PANC_CHANGED
* @DW3000_CHANNEL_CHANGED: channel configuration changed
* @DW3000_PCODE_CHANGED: preamble code configuration changed
* @DW3000_PREAMBLE_LENGTH_CHANGED: length of preamble changed
* @DW3000_SFD_CHANGED: Start Frame Delimiter changed
* @DW3000_PHR_RATE_CHANGED: Physical HeadeR rate changed
* @DW3000_DATA_RATE_CHANGED: Data rate changed
*/
enum config_changed_flags {
DW3000_AFILT_SADDR_CHANGED = IEEE802154_AFILT_SADDR_CHANGED,
DW3000_AFILT_IEEEADDR_CHANGED = IEEE802154_AFILT_IEEEADDR_CHANGED,
DW3000_AFILT_PANID_CHANGED = IEEE802154_AFILT_PANID_CHANGED,
DW3000_AFILT_PANC_CHANGED = IEEE802154_AFILT_PANC_CHANGED,
DW3000_CHANNEL_CHANGED = BIT(4),
DW3000_PCODE_CHANGED = BIT(5),
DW3000_PREAMBLE_LENGTH_CHANGED = BIT(6),
DW3000_SFD_CHANGED = BIT(7),
DW3000_PHR_RATE_CHANGED = BIT(8),
DW3000_DATA_RATE_CHANGED = BIT(9),
};
/**
* struct dw3000_power - DW3000 device power related data
* @stats: accumulated statistics defined by struct sysfs_power_stats
* @start_time: timestamp of current state start
* @cur_state: current state defined by enum power_state
* @tx_adjust: TX time adjustment based on frame length
* @rx_start: RX start date in DTU for RX time adjustment
* @interrupts: Hardware interrupts count on the device.
*/
struct dw3000_power {
struct sysfs_power_stats stats[DW3000_PWR_MAX];
u64 start_time;
int cur_state;
int tx_adjust;
u32 rx_start;
atomic64_t interrupts;
};
/**
* struct dw3000_deep_sleep_state - Useful data to restore on wake up
* @next_operational_state: operational state to enter after DEEP SLEEP mode
* @config_changed: bitfield of configuration changed during DEEP-SLEEP
* @frame_idx: saved frame index to use for deferred TX/RX
* @tx_skb: saved frame to transmit for deferred TX
* @tx_config: saved config to use for deferred TX
* @rx_config: saved parameter for deferred RX
* @regbackup: registers backup to detect diff
* @compare_work: deferred registers backup compare work
*/
struct dw3000_deep_sleep_state {
enum operational_state next_operational_state;
unsigned long config_changed;
int frame_idx;
struct sk_buff *tx_skb;
union {
struct mcps802154_tx_frame_config tx_config;
struct mcps802154_rx_frame_config rx_config;
};
#ifdef CONFIG_DW3000_DEBUG
void *regbackup;
struct work_struct compare_work;
#endif
};
/** enum dw3000_rctu_conv_state - DTU to RCTU conversion state
* @UNALIGNED: need to redo all
* @ALIGNED: aligned to DTU but not synced yet with RCTU
* @ALIGNED_SYNCED: all done
*
*/
enum dw3000_rctu_conv_state { UNALIGNED = 0, ALIGNED, ALIGNED_SYNCED };
/**
* struct dw3000_rctu_conv - DTU to RCTU conversion data
* @state: current state of converter
* @alignment_rmarker_dtu: alignment DTU value
* @synced_rmarker_rctu: rmarker RCTU value
*/
struct dw3000_rctu_conv {
enum dw3000_rctu_conv_state state;
u32 alignment_rmarker_dtu;
u64 synced_rmarker_rctu;
};
struct dw3000_cir_data;
#define DW3000_MAX_QUEUED_SPI_XFER 32
#define DW3000_QUEUED_SPI_BUFFER_SZ 2048
/* Number of samples to average. */
#define DW3000_NB_AVERAGE 1
/**
* struct dw3000_rx_ctx - Custom rx context use with rx_init/rx_get_measurement.
* @pdoa_rad_q11: Array of PDoA measurements.
* @aoa_rad_q11: Array of AoA measurements.
* @index: Index for pdoa_rad_q11 and aoa_rad_q11 arrays.
* @sample_valid_nb: Number of valid measurements in array, used for average.
*/
struct dw3000_rx_ctx {
int pdoa_rad_q11[DW3000_NB_AVERAGE];
int aoa_rad_q11[DW3000_NB_AVERAGE];
int index;
int sample_valid_nb;
};
/**
* struct dw3000 - main DW3000 device structure
* @spi: pointer to corresponding spi device
* @dev: pointer to generic device holding sysfs attributes
* @pm_qos_req: CPU latency request object
* @sysfs_power_dir: kobject holding sysfs power directory
* @chip_ops: version specific chip operations
* @llhw: pointer to associated struct mcps802154_llhw
* @config: current running chip configuration
* @txconfig: current running TX configuration
* @data: local data and register cache
* @otp_data: OTP data cache
* @calib_data: calibration data
* @stats: statistics
* @power: power related statistics and states
* @rctu_conv: RCTU converter
* @time_zero_ns: initial time in ns to convert ktime to/from DTU
* @dtu_sync: synchro DTU immediately after wakeup
* @sys_time_sync: device SYS_TIME immediately after wakeup
* @sleep_enter_dtu: DTU when entered sleep
* @deep_sleep_state: state related to the deep sleep
* @idle_timeout: true when idle_timeout_dtu is a valid date.
* @idle_timeout_dtu: timestamp requested to leave idle mode.
* @idle_timer: timer to exiting after an idle call.
* @timer_expired_work: call mcps802154_timer_expired outside driver kthread.
* @wakeup_done_cb: callback called on wakeup done.
* @idle_timeout_cb: callback when idle timer expired
* @auto_sleep_margin_us: configurable automatic deep sleep margin
* @need_ranging_clock: true if next operation need ranging clock
* and deep sleep cannot be used
* @nfcc_coex: NFCC coexistence specific context
* @pctt: PCTT specific context
* @chip_dev_id: identified chip device ID
* @chip_idx: index of current chip in supported devices array
* @of_max_speed_hz: saved SPI max speed from device tree
* @iface_is_started: interface status
* @has_lock_pm: power management locked status
* @reset_gpio: GPIO to use for hard reset
* @regulators: structure that holds regulators to toggle
* @is_powered: save current regulators state
* @chips_per_pac: chips per PAC unit
* @pre_timeout_pac: preamble timeout in PAC unit
* @coex_delay_us: WiFi coexistence GPIO delay in us
* @coex_margin_us: WiFi coexistence GPIO margin in us
* @coex_interval_us: Minimum interval between two operations in us
* under which WiFi coexistence GPIO is kept active
* @coex_gpio: WiFi coexistence GPIO, >= 0 if activated
* @coex_enabled: WiFi coexistence activation
* @coex_status: WiFi coexistence GPIO status, 1 if activated
* @lna_pa_mode: LNA/PA configuration to use
* @autoack: auto-ack status, true if activated
* @pgf_cal_running: true if pgf calibration is running
* @stm: High-priority thread state machine
* @rx: received skbuff and associated spinlock
* @current_operational_state: internal operational state of the chip
* @operational_state_wq: Wait queue for operational state
* @debugfs: debugfs informations
* @spi_pid: PID of the SPI controller pump messages
* @dw3000_pid: PID the dw3000 state machine thread
* @restricted_channels: bit field of restricted channels
* @tx_rf2: parameter to enable the tx on rf2 port
* @cir_data_changed: true if buffer data have been reallocated
* @full_cia_read: CIA registers fully loaded into cir_data struct
* @cir_data: allocated CIR exploitation data
* @msg_queue: SPI message holding transfer queue
* @msg_queue_xfer: next transfer available
* @msg_queue_xfer_count: number of queued transfers
* @msg_queue_buf: buffer for queued transfers
* @msg_queue_buf_pos: current position in buffer
* @msg_mutex: mutex protecting @msg_readwrite_fdx
* @msg_readwrite_fdx: pre-computed generic register read/write SPI message
* @msg_fast_command: pre-computed fast command SPI message
* @msg_read_cir_pwr: pre-computed SPI message
* @msg_read_pacc_cnt: pre-computed SPI message
* @msg_read_rdb_status: pre-computed SPI message
* @msg_read_rx_timestamp: pre-computed SPI message
* @msg_read_rx_timestamp_a: pre-computed SPI message
* @msg_read_rx_timestamp_b: pre-computed SPI message
* @msg_read_sys_status: pre-computed SPI message
* @msg_read_all_sys_status: pre-computed SPI message
* @msg_read_sys_time: pre-computed SPI message
* @msg_write_sys_status: pre-computed SPI message
* @msg_write_all_sys_status: pre-computed SPI message
* @msg_read_dss_status: pre-computed SPI message
* @msg_write_dss_status: pre-computed SPI message
* @msg_write_spi_collision_status: pre-computed SPI message
*/
struct dw3000 {
/* SPI device */
struct spi_device *spi;
/* Generic device */
struct device *dev;
/* PM QoS object */
struct pm_qos_request pm_qos_req;
/* Kernel object holding sysfs power sub-directory */
struct kobject sysfs_power_dir;
/* Chip version specific operations */
const struct dw3000_chip_ops *chip_ops;
/* MCPS 802.15.4 device */
struct mcps802154_llhw *llhw;
/* Configuration */
struct dw3000_config config;
struct dw3000_txconfig txconfig;
/* Data */
struct dw3000_local_data data;
struct dw3000_otp_data otp_data;
struct dw3000_calibration_data calib_data;
/* Statistics */
struct dw3000_stats stats;
struct dw3000_power power;
/* Time conversion */
struct dw3000_rctu_conv rctu_conv;
s64 time_zero_ns;
u32 dtu_sync;
u32 sys_time_sync;
u32 sleep_enter_dtu;
/* Deep Sleep & MCPS Idle management */
struct dw3000_deep_sleep_state deep_sleep_state;
bool idle_timeout;
u32 idle_timeout_dtu;
struct hrtimer idle_timer;
struct work_struct timer_expired_work;
dw3000_wakeup_done_cb wakeup_done_cb;
dw3000_idle_timeout_cb idle_timeout_cb;
bool need_ranging_clock;
int auto_sleep_margin_us;
/* NFCC coexistence specific context. */
struct dw3000_nfcc_coex nfcc_coex;
/* PCTT specific context. */
struct dw3000_pctt pctt;
/* Chip type management */
u32 chip_dev_id;
u32 chip_idx;
/* Saved SPI max speed from device tree */
u32 of_max_speed_hz;
/* True when MCPS start() operation had been called */
atomic_t iface_is_started;
/* SPI controller power-management */
bool has_lock_pm;
/* Control GPIOs */
int reset_gpio;
/* Regulators handler */
struct dw3000_power_control regulators;
bool is_powered;
/* Chips per PAC unit. */
int chips_per_pac;
/* Preamble timeout in PAC unit. */
int pre_timeout_pac;
/* WiFi coexistence GPIO and delay */
unsigned coex_delay_us;
unsigned coex_margin_us;
unsigned coex_interval_us;
s8 coex_gpio;
bool coex_enabled;
int coex_status;
/* LNA/PA mode */
s8 lna_pa_mode;
/* Is auto-ack activated? */
bool autoack;
/* pgf calibration running */
bool pgf_cal_running;
/* State machine */
struct dw3000_state stm;
/* Receive descriptor */
struct dw3000_rx rx;
/* Internal operational state of the chip */
enum operational_state current_operational_state;
/* Wait queue for operational state */
wait_queue_head_t operational_state_wq;
/* Debugfs settings */
struct dw3000_debugfs debugfs;
/* PID of the SPI controller pump messages */
pid_t spi_pid;
/* PID the dw3000 state machine thread */
pid_t dw3000_pid;
/* Restricted channels */
u16 restricted_channels;
/* enable tx on RF2 port */
u8 tx_rf2;
/* Channel impulse response data */
bool cir_data_changed;
bool full_cia_read;
struct dw3000_cir_data *cir_data;
/* SPI message holding transfers queue */
struct spi_message *msg_queue;
struct spi_transfer *msg_queue_xfer;
unsigned msg_queue_xfer_count;
/* Buffer for queued transfers */
char *msg_queue_buf;
char *msg_queue_buf_pos;
/* dw3000 thread clamp value */
int min_clamp_value;
/* Insert new fields before this line */
/* Shared message protected by a mutex */
struct mutex msg_mutex;
/* Precomputed spi_messages */
struct spi_message *msg_readwrite_fdx;
struct spi_message *msg_fast_command;
struct spi_message *msg_read_rdb_status;
struct spi_message *msg_read_rx_timestamp;
struct spi_message *msg_read_rx_timestamp_a;
struct spi_message *msg_read_rx_timestamp_b;
struct spi_message *msg_read_sys_status;
struct spi_message *msg_read_all_sys_status;
struct spi_message *msg_read_sys_time;
struct spi_message *msg_write_sys_status;
struct spi_message *msg_write_all_sys_status;
struct spi_message *msg_read_dss_status;
struct spi_message *msg_write_dss_status;
struct spi_message *msg_write_spi_collision_status;
};
/**
* dw3000_is_active() - Return if DW is in active state (UP and running)
* @dw: The DW device.
*
* Allow to know if DW is in active state (dw3000_enable() called successfully)
* Used to avoid modification of registers while DW is in use.
* The chip can be in DEEP_SLEEP state and interface still up & running
*
* Return: true is DW is in active state
*/
static inline bool dw3000_is_active(struct dw3000 *dw)
{
return atomic_read(&dw->iface_is_started);
}
/**
* nfcc_coex_to_dw() - Help function to retrieve dw3000 context from nfcc_coex.
* @nfcc_coex: NFCC coexistence context.
*
* Returns: DW3000 device context.
*/
static inline struct dw3000 *nfcc_coex_to_dw(struct dw3000_nfcc_coex *nfcc_coex)
{
return container_of(nfcc_coex, struct dw3000, nfcc_coex);
}
#endif /* __DW3000_H */