diff options
author | Clément Viel <clement.viel@qorvo.com> | 2022-11-14 14:10:17 +0100 |
---|---|---|
committer | Victor Liu <victorliu@google.com> | 2022-11-16 17:35:44 +0000 |
commit | ec82eb1c760bf2d6e8f81d0f02846739d6914282 (patch) | |
tree | c2903401d7683e82831ca1e3f53a8dc40a50b733 | |
parent | 75322a07f3751489bad24fba3a480797afae67e7 (diff) | |
download | uwb-ec82eb1c760bf2d6e8f81d0f02846739d6914282.tar.gz |
dw3000: allow RX on RF2 path.
Bug: 257887283
Change-Id: I97d14ba5620dca1a00edb0ad7dbf6207e2ad8914
Signed-off-by: Clément Viel <clement.viel@qorvo.com>
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000.h | 3 | ||||
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_core.c | 68 | ||||
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_core.h | 2 | ||||
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_core_reg.h | 2 |
4 files changed, 59 insertions, 16 deletions
diff --git a/kernel/drivers/net/ieee802154/dw3000.h b/kernel/drivers/net/ieee802154/dw3000.h index 4495a2d..6fb5d5e 100644 --- a/kernel/drivers/net/ieee802154/dw3000.h +++ b/kernel/drivers/net/ieee802154/dw3000.h @@ -585,6 +585,7 @@ struct dw3000_rx_ctx { * @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 + * @rx_rf2: parameter to enable the rx 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 @@ -703,6 +704,8 @@ struct dw3000 { u16 restricted_channels; /* enable tx on RF2 port */ u8 tx_rf2; + /* enable rx on RF2 port */ + u8 rx_rf2; /* Channel impulse response data */ bool cir_data_changed; bool full_cia_read; diff --git a/kernel/drivers/net/ieee802154/dw3000_core.c b/kernel/drivers/net/ieee802154/dw3000_core.c index 0419221..932f0db 100644 --- a/kernel/drivers/net/ieee802154/dw3000_core.c +++ b/kernel/drivers/net/ieee802154/dw3000_core.c @@ -299,6 +299,8 @@ enum ciadiag_dbl_options { /* LDO VOUT value */ #define DW3000_RF_LDO_VOUT 0x0D7FFFFFUL +/* RF SWITCH RX RF2 */ +#define DW3000_RF_SWITCH_RX_RF2 0x2131 /* PLL common value */ #define DW3000_RF_PLL_COMMON 0xE104 @@ -1385,14 +1387,44 @@ int dw3000_clear_spi_collision_status(struct dw3000 *dw, u8 clear_bits) return rc; } - -int dw3000_change_tx_rf1_to_rf2(struct dw3000 *dw, bool tx) +/** + * dw3000_change_tx_rf_port() - Enable TX on RF2 port. + * @dw: the DW device on which the SPI transfer will occurs + * @use_rf2: variable to trigger the SWITCH to RF2 + * + * Return: 0 on success, else a negative error code. + */ +static int dw3000_change_tx_rf_port(struct dw3000 *dw, bool use_rf2) { int rc; - if (tx) - rc = dw3000_reg_write32(dw, DW3000_RF_SWITCH_CTRL_ID, 0, 0x1C000050); - else - rc = dw3000_reg_write32(dw, DW3000_RF_SWITCH_CTRL_ID, 0, 0x1C000000); + u32 val = DW3000_TXRXSWITCH_AUTO | + ((u32)use_rf2 + << DW3000_RF_SWITCH_CTRL_ANT_TXRX_TXPORT_BIT_OFFSET) | + ((u32)use_rf2 + << DW3000_RF_SWITCH_CTRL_ANT_TXRX_MODE_OVR_BIT_OFFSET); + rc = dw3000_reg_write32(dw, DW3000_RF_SWITCH_CTRL_ID, 0, val); + if (!rc) + dw->tx_rf2 = use_rf2; + return rc; +} + +/** + * dw3000_change_rx_rf_port() - Enable RX on RF2 port. + * @dw: the DW device on which the SPI transfer will occurs + * @use_rf2: variable to trigger the SWITCH to RF2 + * + * Return: 0 on success, else a negative error code. + */ +static int dw3000_change_rx_rf_port(struct dw3000 *dw, bool use_rf2) +{ + int rc = 0; + u32 val; + if (use_rf2) { + val =DW3000_TXRXSWITCH_AUTO | DW3000_RF_SWITCH_RX_RF2; + rc = dw3000_reg_write32(dw, DW3000_RF_SWITCH_CTRL_ID, 0, val); + if (!rc) + dw->rx_rf2 = use_rf2; + } return rc; } @@ -2654,7 +2686,7 @@ int dw3000_do_rx_enable(struct dw3000 *dw, if (unlikely(rc)) goto fail; /* Ensure correct RX antennas are selected. */ - rc = dw3000_set_rx_antennas(dw, config->ant_set_id, pdoa_enabled); + rc = dw3000_set_rx_antennas(dw, config->ant_set_id, pdoa_enabled, frame_idx); if (unlikely(rc)) goto fail; if (config->flags & MCPS802154_RX_FRAME_CONFIG_AACK) { @@ -6457,10 +6489,8 @@ int dw3000_set_tx_antenna(struct dw3000 *dw, int ant_set_id) /* Retrieve antenna GPIO configuration from calibration data */ ant_calib = &dw->calib_data.ant[ant_idx1]; /* switching to RF2 port for TX if necessary */ - if (ant_calib->port == 1) { - dw3000_change_tx_rf1_to_rf2(dw, true); - dw->tx_rf2 = 1; - } + if (ant_calib->port == 1 || dw->tx_rf2) + dw3000_change_tx_rf_port(dw, ant_calib->port == 1); /* Set GPIO state according config to select this antenna */ rc = dw3000_set_antenna_gpio(dw, ant_calib); @@ -6477,10 +6507,11 @@ int dw3000_set_tx_antenna(struct dw3000 *dw, int ant_set_id) * @dw: The DW device. * @ant_set_id: The antennas set id to use * @pdoa_enabled: True if PDoA is enabled + * @frame_idx: the id of the frame to be rcvd * * Return: zero on success, else a negative error code. */ -int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, bool pdoa_enabled) +int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, bool pdoa_enabled, int frame_idx) { struct dw3000_config *config = &dw->config; struct dw3000_antenna_calib *ant_calib; @@ -6489,9 +6520,6 @@ int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, bool pdoa_enabled) /* Sanity checks first */ if (ant_set_id < 0 || ant_set_id >= ANTSET_ID_MAX) return -EINVAL; - if (dw->tx_rf2) { - dw3000_change_tx_rf1_to_rf2(dw, false); - } /* Retrieve RX antennas configuration from antenna set id */ dw3000_calib_ant_set_id_to_ant(ant_set_id, &ant_idx1, &ant_idx2); if (pdoa_enabled && (ant_idx1 < 0 || ant_idx2 < 0)) { @@ -6504,6 +6532,16 @@ int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, bool pdoa_enabled) if (ant_idx1 >= 0) { ant_calib = &dw->calib_data.ant[ant_idx1]; port = ant_calib->port; /* Save port for later check */ + if (((ant_calib->port == 1) || dw->rx_rf2) && ant_idx2 < 0) { + dw3000_change_rx_rf_port(dw, true); + } else if (ant_calib->port == 1 && ant_idx2 > 0) { + if (frame_idx == 5) + dw3000_change_rx_rf_port(dw, true); + else + dw3000_change_rx_rf_port(dw, false); + } else { + dw3000_change_rx_rf_port(dw, false); + } if (ant_idx1 != config->ant[port]) { /* Set GPIO state according config for this first antenna */ rc = dw3000_set_antenna_gpio(dw, ant_calib); diff --git a/kernel/drivers/net/ieee802154/dw3000_core.h b/kernel/drivers/net/ieee802154/dw3000_core.h index bf936b9..aa7c4ed 100644 --- a/kernel/drivers/net/ieee802154/dw3000_core.h +++ b/kernel/drivers/net/ieee802154/dw3000_core.h @@ -419,7 +419,7 @@ int dw3000_tx_setcwtone(struct dw3000 *dw, bool on); int dw3000_config_antenna_gpios(struct dw3000 *dw); int dw3000_set_tx_antenna(struct dw3000 *dw, int ant_set_id); int dw3000_set_rx_antennas(struct dw3000 *dw, int ant_set_id, - bool pdoa_enabled); + bool pdoa_enabled, int frame_idx); s16 dw3000_read_pdoa(struct dw3000 *dw); s16 dw3000_pdoa_to_aoa_lut(struct dw3000 *dw, s16 pdoa_rad_q11); diff --git a/kernel/drivers/net/ieee802154/dw3000_core_reg.h b/kernel/drivers/net/ieee802154/dw3000_core_reg.h index 8847bf8..592f582 100644 --- a/kernel/drivers/net/ieee802154/dw3000_core_reg.h +++ b/kernel/drivers/net/ieee802154/dw3000_core_reg.h @@ -1182,6 +1182,8 @@ #define DW3000_RF_SWITCH_CTRL_ANT_TXRX_MODE_OVR_BIT_OFFSET (4U) #define DW3000_RF_SWITCH_CTRL_ANT_TXRX_MODE_OVR_BIT_LEN (1U) #define DW3000_RF_SWITCH_CTRL_ANT_TXRX_MODE_OVR_BIT_MASK 0x10U +#define DW3000_RF_SWITCH_CTRL_ANT_TXRX_NOTOGGLE_BIT_MASK 0x1U +#define DW3000_RF_SWITCH_CTRL_ANT_TXRX_NOTOGGLE_LEN (0U) /* register TX_CTRL_LO */ #define DW3000_TX_CTRL_LO_ID 0x70018 |