summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Viel <clement.viel@qorvo.com>2022-11-14 14:10:17 +0100
committerVictor Liu <victorliu@google.com>2022-11-16 17:35:44 +0000
commitec82eb1c760bf2d6e8f81d0f02846739d6914282 (patch)
treec2903401d7683e82831ca1e3f53a8dc40a50b733
parent75322a07f3751489bad24fba3a480797afae67e7 (diff)
downloaduwb-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.h3
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core.c68
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core.h2
-rw-r--r--kernel/drivers/net/ieee802154/dw3000_core_reg.h2
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