Search Linux Wireless

[RFC v1 083/256] cl8k: add fem.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Viktor Barna <viktor.barna@xxxxxxxxxx>

(Part of the split. Please, take a look at the cover letter for more
details).

Signed-off-by: Viktor Barna <viktor.barna@xxxxxxxxxx>
---
 drivers/net/wireless/celeno/cl8k/fem.c | 1271 ++++++++++++++++++++++++
 1 file changed, 1271 insertions(+)
 create mode 100644 drivers/net/wireless/celeno/cl8k/fem.c

diff --git a/drivers/net/wireless/celeno/cl8k/fem.c b/drivers/net/wireless/celeno/cl8k/fem.c
new file mode 100644
index 000000000000..4786106b63aa
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/fem.c
@@ -0,0 +1,1271 @@
+// SPDX-License-Identifier: MIT
+/* Copyright(c) 2019-2021, Celeno Communications Ltd. */
+
+#include "chip.h"
+#include "fem.h"
+#include "reg/reg_fem.h"
+#include "fem_common.h"
+#include "e2p.h"
+#include "reg/reg_ricu.h"
+#include "reg/reg_riu_rc.h"
+#include "agc_params.h"
+
+static const struct cl_fem_lna_enable_gpio lna_enable_gpio[FEM_WIRING_MAX] = {
+       [FEM_WIRING_0_TCV0_6_TCV1_6]           = { .val = 0b000000000000 },
+       [FEM_WIRING_1_TCV0_6_TCV1_6]           = { .val = 0b000000000000 },
+       [FEM_WIRING_2_TCV0_6_TCV1_6]           = { .val = 0b000000000000 },
+       [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b001100110000 },
+       [FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b001100110000 },
+       [FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b001100110000 },
+       [FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b001100110000 },
+       [FEM_WIRING_7_TCV0_4_TCV1_4]           = { .val = 0b000000111010 },
+       [FEM_WIRING_8_TCV0_4_TCV1_4]           = { .val = 0b000000111010 },
+       [FEM_WIRING_9_TCV0_4_TCV1_4]           = { .val = 0b111100000000 },
+       [FEM_WIRING_10_TCV0_4_TCV1_4]          = { .val = 0b111100000000 },
+       [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY]  = { .val = 0b111100000000 },
+       [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY]  = { .val = 0b111100000000 },
+       [FEM_WIRING_13_SENSING_4RX_2TX]        = { .val = 0b001111110000 },
+       [FEM_WIRING_14_SENSING_4TX_2RX]        = { .val = 0b111100110000 },
+       [FEM_WIRING_15_CHAMELEON_4TX_4RX]      = { .val = 0b001100001010 },
+       [FEM_WIRING_16_TCV0_2_TCV1_2]          = { .val = 0b100110111110 },
+       [FEM_WIRING_17_TCV0_4_TCV1_0]          = { .val = 0b111111110000 },
+       [FEM_WIRING_18_TCV0_4_TCV1_4]          = { .val = 0b000000111010 },
+       [FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED]  = { .val = 0b000011111111 },
+       [FEM_WIRING_20_TCV0_4_TCV1_2]          = { .val = 0b000011111010 },
+       [FEM_WIRING_21_TCV0_4_TCV1_2]          = { .val = 0b111111000000 },
+};
+
+static const struct cl_fem_pa_enable_gpio pa_enable_gpio[FEM_WIRING_MAX] = {
+       [FEM_WIRING_0_TCV0_6_TCV1_6]           = { .val = 0b000000000000 },
+       [FEM_WIRING_1_TCV0_6_TCV1_6]           = { .val = 0b000000000000 },
+       [FEM_WIRING_2_TCV0_6_TCV1_6]           = { .val = 0b000000000000 },
+       [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b000000000000 },
+       [FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b000000000000 },
+       [FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b000000000000 },
+       [FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b000000000000 },
+       [FEM_WIRING_7_TCV0_4_TCV1_4]           = { .val = 0b000000111010 },
+       [FEM_WIRING_8_TCV0_4_TCV1_4]           = { .val = 0b000000111010 },
+       [FEM_WIRING_9_TCV0_4_TCV1_4]           = { .val = 0b111100000000 },
+       [FEM_WIRING_10_TCV0_4_TCV1_4]          = { .val = 0b111100000000 },
+       [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY]  = { .val = 0b111111110000 },
+       [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY]  = { .val = 0b111111110000 },
+       [FEM_WIRING_13_SENSING_4RX_2TX]        = { .val = 0b001111110000 },
+       [FEM_WIRING_14_SENSING_4TX_2RX]        = { .val = 0b001111111010 },
+       [FEM_WIRING_15_CHAMELEON_4TX_4RX]      = { .val = 0b001111111010 },
+       [FEM_WIRING_16_TCV0_2_TCV1_2]          = { .val = 0b100110111110 },
+       [FEM_WIRING_17_TCV0_4_TCV1_0]          = { .val = 0b111111110000 },
+       [FEM_WIRING_18_TCV0_4_TCV1_4]          = { .val = 0b000000111010 },
+       [FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED]  = { .val = 0b000011111111 },
+       [FEM_WIRING_20_TCV0_4_TCV1_2]          = { .val = 0b000011111010 },
+       [FEM_WIRING_21_TCV0_4_TCV1_2]          = { .val = 0b111111110000 },
+};
+
+static const struct cl_fem_rx_active_gpio rx_active_gpio[FEM_WIRING_MAX] = {
+       [FEM_WIRING_0_TCV0_6_TCV1_6]           = { .val = 0b11000000 },
+       [FEM_WIRING_1_TCV0_6_TCV1_6]           = { .val = 0b11111111 },
+       [FEM_WIRING_2_TCV0_6_TCV1_6]           = { .val = 0b00000000 }, /* N/A */
+       [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b11111100 },
+       [FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b11111111 },
+       [FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b00000000 }, /* N/A */
+       [FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2] = { .val = 0b00000000 }, /* N/A */
+       [FEM_WIRING_7_TCV0_4_TCV1_4]           = { .val = 0b11110000 },
+       [FEM_WIRING_8_TCV0_4_TCV1_4]           = { .val = 0b00000000 }, /* N/A */
+       [FEM_WIRING_9_TCV0_4_TCV1_4]           = { .val = 0b11111111 },
+       [FEM_WIRING_10_TCV0_4_TCV1_4]          = { .val = 0b00000000 },
+       [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY]  = { .val = 0b11110000 },
+       [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY]  = { .val = 0b11111111 },
+       [FEM_WIRING_13_SENSING_4RX_2TX]        = { .val = 0b11000000 },
+       [FEM_WIRING_14_SENSING_4TX_2RX]        = { .val = 0b11110000 },
+       [FEM_WIRING_15_CHAMELEON_4TX_4RX]      = { .val = 0b11110000 },
+       [FEM_WIRING_16_TCV0_2_TCV1_2]          = { .val = 0b11111001 },
+       [FEM_WIRING_17_TCV0_4_TCV1_0]          = { .val = 0b11111111 },
+       [FEM_WIRING_18_TCV0_4_TCV1_4]          = { .val = 0b00000000 },
+       [FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED]  = { .val = 0b11001111 },
+       [FEM_WIRING_20_TCV0_4_TCV1_2]          = { .val = 0b11110000 },
+       [FEM_WIRING_21_TCV0_4_TCV1_2]          = { .val = 0b11111111 },
+};
+
+static const u32 ricu_fem_conf[FEM_WIRING_MAX][TCV_MAX] = {
+       [FEM_WIRING_0_TCV0_6_TCV1_6]           = { 0x00AB3021, 0x0054CD89},
+       [FEM_WIRING_1_TCV0_6_TCV1_6]           = { 0x00AB3021, 0x0054CD89},
+       [FEM_WIRING_2_TCV0_6_TCV1_6]           = { 0x00AB3021, 0x0054CD89},
+       [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = { 0x00003021, 0x00AB0089},
+       [FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2] = { 0x00003021, 0x00AB0089},
+       [FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2] = { 0x00003021, 0x00AB0089},
+       [FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2] = { 0x00003021, 0x00AB0089},
+       [FEM_WIRING_7_TCV0_4_TCV1_4]           = { 0x00000001, 0x0032AB89},
+       [FEM_WIRING_8_TCV0_4_TCV1_4]           = { 0x00000001, 0x0032AB89},
+       [FEM_WIRING_9_TCV0_4_TCV1_4]           = { 0x00AB3210, 0x00000089},
+       [FEM_WIRING_10_TCV0_4_TCV1_4]          = { 0x00AB3210, 0x00000089},
+       [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY]  = { 0x00AB3210, 0x00000089},
+       [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY]  = { 0x00AB3210, 0x00000089},
+       [FEM_WIRING_13_SENSING_4RX_2TX]        = { 0x00003021, 0x00890000},
+       [FEM_WIRING_14_SENSING_4TX_2RX]        = { 0x00003021, 0x00000089},
+       [FEM_WIRING_15_CHAMELEON_4TX_4RX]      = { 0x00AB0001, 0x00320089},
+       [FEM_WIRING_16_TCV0_2_TCV1_2]          = { 0x00000001, 0x0000B00A},
+       [FEM_WIRING_17_TCV0_4_TCV1_0]          = { 0x00AB3210, 0x00000089},
+       [FEM_WIRING_18_TCV0_4_TCV1_4]          = { 0x00000001, 0x0032AB89},
+       [FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED]  = { 0x00000000, 0x00AB3289},
+       [FEM_WIRING_20_TCV0_4_TCV1_2]          = { 0x00000001, 0x0032AB00},
+       [FEM_WIRING_21_TCV0_4_TCV1_2]          = { 0x00AB3210, 0x00000089},
+};
+
+static const u8 fem_full_list[FEM_WIRING_MAX][TCV_MAX][FEM_LUT_AMOUNT_PER_MAC] = {
+       [FEM_WIRING_0_TCV0_6_TCV1_6] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1},
+       },
+       [FEM_WIRING_1_TCV0_6_TCV1_6] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1},
+       },
+       [FEM_WIRING_2_TCV0_6_TCV1_6] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1},
+       },
+       [FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_ELASTIC,
+                       FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_ELASTIC,
+                       FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC},
+       },
+       [FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_ELASTIC,
+                       FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_ELASTIC,
+                       FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC},
+       },
+       [FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_ELASTIC,
+                       FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_ELASTIC,
+                       FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC},
+       },
+       [FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_ELASTIC,
+                       FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_ELASTIC,
+                       FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC, FEM_TYPE_ELASTIC},
+       },
+       [FEM_WIRING_7_TCV0_4_TCV1_4] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_8_TCV0_4_TCV1_4] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_9_TCV0_4_TCV1_4] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_10_TCV0_4_TCV1_4] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_TYPE_SENSING,
+                       FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_TYPE_SENSING,
+                       FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_13_SENSING_4RX_2TX] = {
+               {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_TYPE_SENSING,
+                       FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_LUT_EMPTY,
+                       FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_14_SENSING_4TX_2RX] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_LUT_EMPTY,
+                       FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_15_CHAMELEON_4TX_4RX] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_SENSING, FEM_TYPE_SENSING, FEM_TYPE_SENSING,
+                       FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_16_TCV0_2_TCV1_2] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_LUT_EMPTY,
+                       FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_17_TCV0_4_TCV1_0] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY,
+                       FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_18_TCV0_4_TCV1_4] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_TYPE_TCV1, FEM_TYPE_TCV1, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED] = {
+               {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_20_TCV0_4_TCV1_2] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_TCV1,
+                       FEM_TYPE_TCV1, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       },
+       [FEM_WIRING_21_TCV0_4_TCV1_2] = {
+               {FEM_TYPE_TCV0, FEM_TYPE_TCV0, FEM_TYPE_TCV0,
+                       FEM_TYPE_TCV0, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+               {FEM_LUT_EMPTY, FEM_LUT_EMPTY, FEM_TYPE_SENSING,
+                       FEM_TYPE_SENSING, FEM_LUT_EMPTY, FEM_LUT_EMPTY},
+       }
+};
+
+static u16 cl_fem_reg_manual(struct cl_hw *cl_hw, u16 val, u8 ant_idx)
+{
+       u8 shift = 0;
+       u16 lut, lut0, lut1, lut2;
+
+       if (cl_hw->fem_ant != ant_idx && cl_hw->fem_ant != U8_MAX)
+               shift = 0; /* In case manual fem setting was chosen */
+       else
+               shift = cl_hw->fem_system_mode * 4;
+
+       lut = (val >> shift) & RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK;
+       lut0 = ((lut << RIU_RC_RF_LNA_LUT_RFLNALUT_0_LSB) & (u16)RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK);
+       lut1 = ((lut << RIU_RC_RF_LNA_LUT_RFLNALUT_1_LSB) & (u16)RIU_RC_RF_LNA_LUT_RFLNALUT_1_MASK);
+       lut2 = ((lut << RIU_RC_RF_LNA_LUT_RFLNALUT_2_LSB) & (u16)RIU_RC_RF_LNA_LUT_RFLNALUT_2_MASK);
+
+       return (lut0 | lut1 | lut2);
+}
+
+int cl_fem_get_registers(struct cl_hw *cl_hw, u32 fem_reg[FEM_REGISTERS_AMOUNT])
+{
+       u8 i;
+       u8 reg_idx;
+       u8 shift;
+       u8 tcv_idx = cl_hw->tcv_idx;
+       u16 reg_val;
+       struct cl_fem_params *fem = &cl_hw->chip->fem;
+
+       /* In case there's no valid wiring_id, keep the fem lut registers empty. */
+       if (fem->wiring_id >= FEM_WIRING_MAX)
+               return 0;
+
+       for (i = 0; i < MAX_ANTENNAS; i++) {
+               reg_idx = i >> 1; /* 0 - 2 */
+               shift = (i & 0x1) ? 16 : 0; /* even - 0. odd  - 16 */
+
+               if (i < cl_hw->num_antennas) {
+                       if (cl_hw->fem_system_mode == FEM_MODE_OPERETIONAL) {
+                               reg_val = fem->lut_registers[tcv_idx][i];
+                       } else {
+                               u16 fem_val = fem->lut_registers[tcv_idx][i];
+
+                               reg_val = cl_fem_reg_manual(cl_hw, fem_val, i);
+                       }
+               } else {
+                       reg_val = fem->lut_off_register[tcv_idx];
+               }
+
+               fem_reg[reg_idx] |= ((u32)reg_val << shift);
+       }
+
+       for (i = 0; i < FEM_REGISTERS_AMOUNT; i++)
+               cl_dbg_trace(cl_hw, "RC_RFLNALUT_%u: [0x%08X]\n", i, fem_reg[i]);
+
+       return 0;
+}
+
+static int cl_fem_read_lut(struct cl_chip *chip)
+{
+       int i;
+       int has_valid_fem_lut = 0;
+       struct cl_fem_params *fem = &chip->fem;
+
+       /* Read FEM LUT from eeprom */
+       if (cl_e2p_read(chip, (u8 *)&fem->lut, SIZE_FEM_LUT, ADDR_FEM_LUT))
+               return -1;
+
+       for (i = 0; i < FEM_TYPE_MAX; i++) {
+               if (fem->lut[i] == U16_MAX)
+                       continue;
+
+               /* Mark as valid if at least one the FEM LUTs has a valid value. */
+               has_valid_fem_lut = 1;
+               fem->lut_off_register_list[i] = EXTRACT_OFF_LUT(fem->lut[i]);
+               fem->lut[i] &= FEM_LUT_MASK;
+               cl_dbg_chip_trace(chip, "lut[%d] = 0x%X, lut_off_register_list[%d] = 0x%X\n",
+                                 i, fem->lut[i], i, fem->lut_off_register_list[i]);
+       }
+
+       return !has_valid_fem_lut;
+}
+
+#define FEM_LUT_OFFSET_BYPASS 0
+#define FEM_LUT_OFFSET_TX     4
+#define FEM_LUT_OFFSET_RX     8
+#define FEM_LUT_OFFSET_OFF    12
+#define FEM_LUT_VAL_MASK      0x7
+
+static int _cl_fem_check_lut_validity(struct cl_chip *chip, enum fem_type type)
+{
+       u16 fem_lut = chip->fem.lut[type];
+       u16 bypass = (fem_lut >> FEM_LUT_OFFSET_BYPASS) & FEM_LUT_VAL_MASK;
+       u16 tx = (fem_lut >> FEM_LUT_OFFSET_TX) & FEM_LUT_VAL_MASK;
+       u16 rx = (fem_lut >> FEM_LUT_OFFSET_RX) & FEM_LUT_VAL_MASK;
+       u16 off = (fem_lut >> FEM_LUT_OFFSET_OFF) & FEM_LUT_VAL_MASK;
+       int ret = 0;
+
+       if (fem_lut == U16_MAX) {
+               cl_dbg_chip_err(chip, "Wiring_id [%u] must have valid FEM LUTs for %s\n",
+                               chip->fem.wiring_id, FEM_TYPE_STR(type));
+               return -1;
+       }
+
+       // Skip uniqueness check for sensing type
+       if (type == FEM_TYPE_SENSING)
+               return 0;
+
+       // Check uniqueness of BYPASS/TX/RX/OFF
+       if (bypass == tx) {
+               cl_dbg_chip_err(chip, "Error: bypass (%u) and tx (%u) values are equal\n",
+                               bypass, tx);
+               ret = -EIO;
+       }
+
+       if (bypass == rx) {
+               cl_dbg_chip_err(chip, "Error: bypass (%u) and rx (%u) values are equal\n",
+                               bypass, rx);
+               ret = -EIO;
+       }
+
+       if (tx == rx) {
+               cl_dbg_chip_err(chip, "Error: tx (%u) and rx (%u) values are equal\n",
+                               tx, rx);
+               ret = -EIO;
+       }
+
+       if (tx == off) {
+               cl_dbg_chip_err(chip, "Error: tx (%u) and off (%u) values are equal\n",
+                               tx, off);
+               ret = -EIO;
+       }
+
+       if (rx == off) {
+               cl_dbg_chip_err(chip, "Error: rx (%u) and off (%u) values are equal\n",
+                               rx, off);
+               ret = -EIO;
+       }
+
+       return ret;
+}
+
+static int cl_fem_check_lut_validity(struct cl_chip *chip, u8 wiring_id)
+{
+       if (cl_fem_read_lut(chip)) {
+               cl_dbg_chip_err(chip, "None of the FEM LUTs is valid. Aborting.\n");
+               return -1;
+       }
+
+       switch (wiring_id) {
+       case FEM_WIRING_0_TCV0_6_TCV1_6:
+       case FEM_WIRING_1_TCV0_6_TCV1_6:
+       /* case FEM_WIRING_2_TCV0_6_TCV1_6: */
+       case FEM_WIRING_7_TCV0_4_TCV1_4:
+       /* case FEM_WIRING_8_TCV0_4_TCV1_4: */
+       case FEM_WIRING_9_TCV0_4_TCV1_4:
+       case FEM_WIRING_10_TCV0_4_TCV1_4:
+       case FEM_WIRING_16_TCV0_2_TCV1_2:
+       case FEM_WIRING_18_TCV0_4_TCV1_4:
+       case FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED:
+       case FEM_WIRING_20_TCV0_4_TCV1_2:
+               if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0) ||
+                   _cl_fem_check_lut_validity(chip, FEM_TYPE_TCV1))
+                       return -1;
+               break;
+
+       case FEM_WIRING_17_TCV0_4_TCV1_0:
+               if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0))
+                       return -1;
+               break;
+
+       case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2:
+       /* case FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2: */
+       /* case FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2: */
+               if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0) ||
+                   _cl_fem_check_lut_validity(chip, FEM_TYPE_TCV1) ||
+                   _cl_fem_check_lut_validity(chip, FEM_TYPE_ELASTIC))
+                       return -1;
+               break;
+
+       case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY:
+       case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY:
+       case FEM_WIRING_14_SENSING_4TX_2RX:
+       case FEM_WIRING_15_CHAMELEON_4TX_4RX:
+       case FEM_WIRING_21_TCV0_4_TCV1_2:
+               if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV0) ||
+                   _cl_fem_check_lut_validity(chip, FEM_TYPE_SENSING))
+                       return -1;
+               break;
+
+       case FEM_WIRING_13_SENSING_4RX_2TX:
+               if (_cl_fem_check_lut_validity(chip, FEM_TYPE_TCV1) ||
+                   _cl_fem_check_lut_validity(chip, FEM_TYPE_SENSING))
+                       return -1;
+               break;
+
+       case FEM_WIRING_2_TCV0_6_TCV1_6:
+       case FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_8_TCV0_4_TCV1_4:
+               cl_dbg_chip_err(chip, "wiring_id %u is not supported\n", wiring_id);
+               return -1;
+
+       default:
+               cl_dbg_chip_err(chip, "Wiring_id [%u] is not valid [0..%u]\n",
+                               wiring_id, FEM_WIRING_MAX - 1);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int cl_fem_validate_wiring_id(struct cl_chip *chip, u8 wiring_id)
+{
+       switch (wiring_id) {
+       case FEM_WIRING_0_TCV0_6_TCV1_6:
+       case FEM_WIRING_1_TCV0_6_TCV1_6:
+       case FEM_WIRING_2_TCV0_6_TCV1_6:
+       case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_7_TCV0_4_TCV1_4:
+       case FEM_WIRING_8_TCV0_4_TCV1_4:
+       case FEM_WIRING_9_TCV0_4_TCV1_4:
+       case FEM_WIRING_10_TCV0_4_TCV1_4:
+       case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY:
+       case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY:
+       case FEM_WIRING_13_SENSING_4RX_2TX:
+       case FEM_WIRING_14_SENSING_4TX_2RX:
+       case FEM_WIRING_15_CHAMELEON_4TX_4RX:
+       case FEM_WIRING_18_TCV0_4_TCV1_4:
+       case FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED:
+               return cl_chip_is_8ant(chip) ? 0 : -1;
+       case FEM_WIRING_20_TCV0_4_TCV1_2:
+       case FEM_WIRING_21_TCV0_4_TCV1_2:
+               return cl_chip_is_6ant(chip) ? 0 : -1;
+       case FEM_WIRING_16_TCV0_2_TCV1_2:
+       case FEM_WIRING_17_TCV0_4_TCV1_0:
+               return cl_chip_is_4ant(chip) ? 0 : -1;
+       default:
+               cl_dbg_chip_err(chip, "wiring_id %u is not valid. [0..%u] are valid values\n",
+                               wiring_id, (FEM_WIRING_MAX - 1));
+               return -1;
+       }
+
+       return -1;
+}
+
+int cl_fem_read_wiring_id(struct cl_chip *chip)
+{
+       struct cl_fem_params *fem = &chip->fem;
+
+       /* In case there's a valid wiring id in chip, no need to re-read it from EEPROM */
+       if (fem->wiring_id < FEM_WIRING_MAX)
+               return 0;
+
+       /* Read wiring_id from eeprom */
+       if (cl_e2p_read(chip, &fem->wiring_id, SIZE_FEM_WIRING_ID, ADDR_FEM_WIRING_ID))
+               return -1;
+
+       return cl_fem_validate_wiring_id(chip, fem->wiring_id);
+}
+
+static void cl_fem_set_registers(struct cl_chip *chip)
+{
+       struct cl_fem_params *fem = &chip->fem;
+       int i;
+       u8 wiring_id = fem->wiring_id;
+
+       for (i = 0; i < FEM_LUT_AMOUNT_PER_MAC; i++) {
+               fem->lut_registers[TCV0][i] = fem->lut[fem_full_list[wiring_id][TCV0][i]];
+               fem->lut_registers[TCV1][i] = fem->lut[fem_full_list[wiring_id][TCV1][i]];
+       }
+}
+
+static int cl_fem_set_lut_off(struct cl_chip *chip)
+{
+       struct cl_fem_params *fem = &chip->fem;
+
+       switch (fem->wiring_id) {
+       case FEM_WIRING_0_TCV0_6_TCV1_6:
+       case FEM_WIRING_1_TCV0_6_TCV1_6:
+       case FEM_WIRING_2_TCV0_6_TCV1_6:
+       case FEM_WIRING_7_TCV0_4_TCV1_4:
+       case FEM_WIRING_8_TCV0_4_TCV1_4:
+       case FEM_WIRING_9_TCV0_4_TCV1_4:
+       case FEM_WIRING_10_TCV0_4_TCV1_4:
+       case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY:
+       case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY:
+       case FEM_WIRING_13_SENSING_4RX_2TX:
+       case FEM_WIRING_14_SENSING_4TX_2RX:
+       case FEM_WIRING_15_CHAMELEON_4TX_4RX:
+       case FEM_WIRING_16_TCV0_2_TCV1_2:
+       case FEM_WIRING_18_TCV0_4_TCV1_4:
+       case FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED:
+       case FEM_WIRING_20_TCV0_4_TCV1_2:
+       case FEM_WIRING_21_TCV0_4_TCV1_2:
+               fem->lut_off_register[TCV0] = fem->lut_off_register_list[FEM_TYPE_TCV0];
+               fem->lut_off_register[TCV1] = fem->lut_off_register_list[FEM_TYPE_TCV1];
+               break;
+
+       case FEM_WIRING_17_TCV0_4_TCV1_0:
+               fem->lut_off_register[TCV0] = fem->lut_off_register_list[FEM_TYPE_TCV0];
+               break;
+
+       case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2:
+               fem->lut_off_register[TCV0] = fem->lut_off_register_list[FEM_TYPE_ELASTIC];
+               fem->lut_off_register[TCV1] = fem->lut_off_register_list[FEM_TYPE_ELASTIC];
+               break;
+
+       default:
+               cl_dbg_chip_err(chip, "Unsupported wiring id [%u]\n", fem->wiring_id);
+               return -1;
+       }
+
+       cl_dbg_chip_trace(chip, "wiring_id = %u, lut_off_register = [%u %u]\n",
+                         fem->wiring_id,
+                         fem->lut_off_register[TCV0],
+                         fem->lut_off_register[TCV1]);
+       return 0;
+}
+
+int cl_fem_init(struct cl_chip *chip)
+{
+       int ret = 0;
+       struct cl_fem_params *fem = &chip->fem;
+
+       fem->wiring_id = FEM_WIRING_DEFAULT;
+
+       ret = cl_fem_read_wiring_id(chip);
+
+       if (ret) {
+               CL_DBG_ERROR_CHIP(chip, "Invalid wiring_id = %u. Aborting.\n", fem->wiring_id);
+
+               if (!chip->conf->ce_production_mode)
+                       return ret;
+       }
+
+       if (cl_fem_read_lut(chip)) {
+               CL_DBG_ERROR_CHIP(chip, "None of the FEM_LUT registers is valid. Aborting.\n");
+
+               if (!chip->conf->ce_production_mode)
+                       return -1;
+       }
+
+       if (cl_fem_check_lut_validity(chip, fem->wiring_id) &&
+           !chip->conf->ce_production_mode)
+               return -1;
+
+       if (cl_fem_set_lut_off(chip) &&
+           !chip->conf->ce_production_mode)
+               return -1;
+
+       cl_dbg_chip_verbose(chip, "wiring_id = %u\n", fem->wiring_id);
+       cl_fem_set_registers(chip);
+
+       ret = cl_agc_params_read_platform_id(chip);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static void cl_fem_get_conf_params(struct cl_chip *chip,
+                                  u32 *ricu_fem_conf_0,
+                                  u32 *ricu_fem_conf_1)
+{
+       u8 wiring_id = chip->fem.wiring_id;
+
+       *ricu_fem_conf_0 = ricu_fem_conf[wiring_id][0];
+       *ricu_fem_conf_1 = ricu_fem_conf[wiring_id][1];
+
+       cl_dbg_chip_verbose(chip, "ricu_fem_conf_0 = 0x%08X, ricu_fem_conf_1 = 0x%08X\n",
+                           *ricu_fem_conf_0, *ricu_fem_conf_1);
+}
+
+static u8 get_num_antennas_tcv0(struct cl_chip *chip)
+{
+       if (chip->cl_hw_tcv0)
+               return chip->cl_hw_tcv0->num_antennas;
+       else
+               return chip->max_antennas - chip->cl_hw_tcv1->num_antennas;
+}
+
+static void update_formation_1_band_select(struct cl_chip *chip)
+{
+       u8 num_antennas_tcv0 = get_num_antennas_tcv0(chip);
+
+       if (num_antennas_tcv0 == 2) {
+               io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+               io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+               io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+               io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+       } else if (num_antennas_tcv0 == 3) {
+               io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+               io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+               io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+               io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+       } else if (num_antennas_tcv0 == 4) {
+               io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+               io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+               io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+               io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+       } else if (num_antennas_tcv0 == 5) {
+               io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+               io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(0));
+               io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+               io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+       } else if (num_antennas_tcv0 == 6) {
+               io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+               io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+               io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+               io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_OUT_CFG(1));
+       }
+}
+
+static void set_lna_bypass_gpio(struct cl_chip *chip)
+{
+       struct cl_fem_params *fem = &chip->fem;
+       u8 lna_bypass_val_tcv0 = fem->lut[FEM_TYPE_TCV0] & RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK;
+       u8 lna_bypass_val_tcv1 = fem->lut[FEM_TYPE_TCV1] & RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK;
+       u8 lna_bypass_val_elastic = fem->lut[FEM_TYPE_ELASTIC] & RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK;
+       u8 lna_bypass_val_sensing = fem->lut[FEM_TYPE_SENSING] & RIU_RC_RF_LNA_LUT_RFLNALUT_0_MASK;
+       u8 pa_enable_bit_tcv0 = GET_BIT(lna_bypass_val_tcv0, PA_ENABLE_POS);
+       u8 pa_enable_bit_tcv1 = GET_BIT(lna_bypass_val_tcv1, PA_ENABLE_POS);
+       u8 pa_enable_bit_elastic = GET_BIT(lna_bypass_val_elastic, PA_ENABLE_POS);
+       u8 pa_enable_bit_sensing = GET_BIT(lna_bypass_val_sensing, PA_ENABLE_POS);
+       u8 lna_enable_bit_tcv0 = GET_BIT(lna_bypass_val_tcv0, LNA_ENABLE_POS);
+       u8 lna_enable_bit_tcv1 = GET_BIT(lna_bypass_val_tcv1, LNA_ENABLE_POS);
+       u8 lna_enable_bit_elastic = GET_BIT(lna_bypass_val_elastic, LNA_ENABLE_POS);
+       u8 lna_enable_bit_sensing = GET_BIT(lna_bypass_val_sensing, LNA_ENABLE_POS);
+       u8 rx_active_bit_tcv0 = GET_BIT(lna_bypass_val_tcv0, RX_ACTIVE_POS);
+       u8 rx_active_bit_tcv1 = GET_BIT(lna_bypass_val_tcv1, RX_ACTIVE_POS);
+       u8 rx_active_bit_sensing = GET_BIT(lna_bypass_val_sensing, RX_ACTIVE_POS);
+       u32 pa_enable_cfg_tcv0 = PA_ENABLE_GPIO_OUT_CFG(pa_enable_bit_tcv0);
+       u32 pa_enable_cfg_tcv1 = PA_ENABLE_GPIO_OUT_CFG(pa_enable_bit_tcv1);
+       u32 pa_enable_cfg_elastic = PA_ENABLE_GPIO_OUT_CFG(pa_enable_bit_elastic);
+       u32 pa_enable_cfg_sensing = PA_ENABLE_GPIO_OUT_CFG(pa_enable_bit_sensing);
+       u32 lna_enable_cfg_tcv0 = LNA_ENABLE_GPIO_OUT_CFG(lna_enable_bit_tcv0);
+       u32 lna_enable_cfg_tcv1 = LNA_ENABLE_GPIO_OUT_CFG(lna_enable_bit_tcv1);
+       u32 lna_enable_cfg_elastic = LNA_ENABLE_GPIO_OUT_CFG(lna_enable_bit_elastic);
+       u32 lna_enable_cfg_sensing = LNA_ENABLE_GPIO_OUT_CFG(lna_enable_bit_sensing);
+       u32 rx_active_cfg_tcv0 = RX_ACTIVE_GPIO_OUT_CFG(rx_active_bit_tcv0);
+       u32 rx_active_cfg_tcv1 = RX_ACTIVE_GPIO_OUT_CFG(rx_active_bit_tcv1);
+       u32 rx_active_cfg_sensing = RX_ACTIVE_GPIO_OUT_CFG(rx_active_bit_sensing);
+
+       switch (fem->wiring_id) {
+       case FEM_WIRING_0_TCV0_6_TCV1_6:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_1_TCV0_6_TCV1_6:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0);
+               break;
+       case FEM_WIRING_2_TCV0_6_TCV1_6:
+               /* TBD */
+               break;
+       case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_elastic);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_elastic);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_elastic);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_elastic);
+               break;
+       case FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_elastic);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_elastic);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_elastic);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_elastic);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv1);
+               io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv1);
+               break;
+       case FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2:
+               /* TBD */
+               break;
+       case FEM_WIRING_7_TCV0_4_TCV1_4:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_8_TCV0_4_TCV1_4:
+               /* TBD */
+               break;
+       case FEM_WIRING_9_TCV0_4_TCV1_4:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+               break;
+       case FEM_WIRING_10_TCV0_4_TCV1_4:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_4_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_5_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv1);
+               io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv1);
+               io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv1);
+               io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv1);
+               break;
+       case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_sensing);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_sensing);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+               break;
+       case FEM_WIRING_13_SENSING_4RX_2TX:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv1);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_sensing);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_sensing);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_sensing);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_sensing);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv1);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_sensing);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_sensing);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_sensing);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_sensing);
+               io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv1);
+               io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv1);
+               break;
+       case FEM_WIRING_14_SENSING_4TX_2RX:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_sensing);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_15_CHAMELEON_4TX_4RX:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_16_TCV0_2_TCV1_2:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_17_TCV0_4_TCV1_0:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+               break;
+       case FEM_WIRING_18_TCV0_4_TCV1_4:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_6_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_7_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_6_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_7_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_6_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_7_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED:
+               io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_4_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_5_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_20_TCV0_4_TCV1_2:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_8_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_9_set(chip, lna_enable_cfg_tcv1);
+               io_ctrl_lna_enable_10_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_11_set(chip, lna_enable_cfg_tcv0);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_8_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_9_set(chip, pa_enable_cfg_tcv1);
+               io_ctrl_pa_enable_10_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_11_set(chip, pa_enable_cfg_tcv0);
+
+               io_ctrl_rx_active_0_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_1_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_2_set(chip, rx_active_cfg_tcv0);
+               io_ctrl_rx_active_3_set(chip, rx_active_cfg_tcv0);
+               break;
+       case FEM_WIRING_21_TCV0_4_TCV1_2:
+               io_ctrl_lna_enable_0_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_1_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_2_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_3_set(chip, lna_enable_cfg_tcv0);
+               io_ctrl_lna_enable_4_set(chip, lna_enable_cfg_sensing);
+               io_ctrl_lna_enable_5_set(chip, lna_enable_cfg_sensing);
+
+               io_ctrl_pa_enable_0_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_1_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_2_set(chip, pa_enable_cfg_tcv0);
+               io_ctrl_pa_enable_3_set(chip, pa_enable_cfg_tcv0);
+               break;
+       default:
+               break;
+       }
+}
+
+static void _cl_fem_conf_gpio(struct cl_chip *chip,
+                             const struct cl_fem_lna_enable_gpio *lna_enable_gpio,
+                             const struct cl_fem_pa_enable_gpio *pa_enable_gpio,
+                             const struct cl_fem_rx_active_gpio *rx_active_gpio)
+{
+       io_ctrl_lna_enable_0_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b0));
+       io_ctrl_lna_enable_1_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b1));
+       io_ctrl_lna_enable_2_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b2));
+       io_ctrl_lna_enable_3_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b3));
+       io_ctrl_lna_enable_4_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b4));
+       io_ctrl_lna_enable_5_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b5));
+       io_ctrl_lna_enable_6_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b6));
+       io_ctrl_lna_enable_7_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b7));
+       io_ctrl_lna_enable_8_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b8));
+       io_ctrl_lna_enable_9_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b9));
+       io_ctrl_lna_enable_10_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b10));
+       io_ctrl_lna_enable_11_set(chip, LNA_ENABLE_GPIO_VAL(lna_enable_gpio->b11));
+
+       io_ctrl_pa_enable_0_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b0));
+       io_ctrl_pa_enable_1_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b1));
+       io_ctrl_pa_enable_2_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b2));
+       io_ctrl_pa_enable_3_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b3));
+       io_ctrl_pa_enable_4_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b4));
+       io_ctrl_pa_enable_5_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b5));
+       io_ctrl_pa_enable_6_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b6));
+       io_ctrl_pa_enable_7_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b7));
+       io_ctrl_pa_enable_8_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b8));
+       io_ctrl_pa_enable_9_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b9));
+       io_ctrl_pa_enable_10_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b10));
+       io_ctrl_pa_enable_11_set(chip, PA_ENABLE_GPIO_VAL(pa_enable_gpio->b11));
+
+       io_ctrl_rx_active_0_set(chip, RX_ACTIVE_GPIO_VAL(rx_active_gpio->b0));
+       io_ctrl_rx_active_1_set(chip, RX_ACTIVE_GPIO_VAL(rx_active_gpio->b1));
+       io_ctrl_rx_active_2_set(chip, RX_ACTIVE_GPIO_VAL(rx_active_gpio->b2));
+       io_ctrl_rx_active_3_set(chip, RX_ACTIVE_GPIO_VAL(rx_active_gpio->b3));
+       io_ctrl_rx_active_4_set(chip, RX_ACTIVE_GPIO_VAL(rx_active_gpio->b4));
+       io_ctrl_rx_active_5_set(chip, RX_ACTIVE_GPIO_VAL(rx_active_gpio->b5));
+       io_ctrl_rx_active_6_set(chip, RX_ACTIVE_GPIO_VAL(rx_active_gpio->b6));
+       io_ctrl_rx_active_7_set(chip, RX_ACTIVE_GPIO_VAL(rx_active_gpio->b7));
+}
+
+static int cl_fem_conf_gpio(struct cl_chip *chip)
+{
+       struct cl_fem_params *fem = &chip->fem;
+       u8 wiring_id = fem->wiring_id;
+
+       if (wiring_id == FEM_WIRING_2_TCV0_6_TCV1_6 ||
+           wiring_id == FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2 ||
+           wiring_id == FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2 ||
+           wiring_id == FEM_WIRING_8_TCV0_4_TCV1_4) {
+               /* Need to be approved by Menashe - so for now it's unsupported. */
+               cl_dbg_chip_err(chip, "Unsupported wiring id [%u]\n", wiring_id);
+               return -1;
+       }
+
+       _cl_fem_conf_gpio(chip,
+                         &lna_enable_gpio[wiring_id],
+                         &pa_enable_gpio[wiring_id],
+                         &rx_active_gpio[wiring_id]);
+
+       if (wiring_id == FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2 ||
+           wiring_id == FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2 ||
+           wiring_id == FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2 ||
+           wiring_id == FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2)
+               update_formation_1_band_select(chip);
+
+       return 0;
+}
+
+int cl_fem_set_system_mode(struct cl_hw *cl_hw, u8 fem_system_mode, u8 fem_ant)
+{
+       struct cl_chip *chip = cl_hw->chip;
+
+       if (fem_system_mode > FEM_MODE_MAX && fem_system_mode != FEM_MODE_OPERETIONAL)
+               return -1;
+
+       cl_dbg_trace(cl_hw, "fem_system_mode: old value = %u -> new value = %u\n",
+                    cl_hw->fem_system_mode, fem_system_mode);
+
+       if (fem_system_mode == FEM_MODE_OPERETIONAL) {
+               cl_fem_conf_gpio(chip);
+               chip->lna_bypass_mode_set = 0;
+       } else if (!chip->lna_bypass_mode_set) {
+               cl_dbg_trace(cl_hw, "fem_system_mode: Set GPIO to LNA Bypass Mode.\n");
+               set_lna_bypass_gpio(chip);
+               chip->lna_bypass_mode_set = 1;
+       }
+
+       cl_hw->fem_system_mode = fem_system_mode;
+       cl_hw->fem_ant = fem_ant;
+       return 0;
+}
+
+int cl_fem_update_conf_params(struct cl_chip *chip)
+{
+       u32 ricu_fem_conf_0, ricu_fem_conf_1 = 0;
+
+       if (cl_fem_read_lut(chip))
+               return -1;
+
+       if (cl_fem_check_lut_validity(chip, chip->fem.wiring_id))
+               return -1;
+
+       /* In case of invalid platform id, don't update FEM conf params*/
+       if (cl_fem_set_lut_off(chip))
+               return -1;
+
+       cl_fem_get_conf_params(chip, &ricu_fem_conf_0, &ricu_fem_conf_1);
+       ricu_fem_conf_0_set(chip, ricu_fem_conf_0);
+       ricu_fem_conf_1_set(chip, ricu_fem_conf_1);
+
+       if (cl_fem_conf_gpio(chip))
+               return -1;
+
+       cl_fem_set_registers(chip);
+
+       return 0;
+}
+
+static int cl_fem_write_wiring_id(struct cl_chip *chip, u8 wiring_id)
+{
+       if (wiring_id >= FEM_WIRING_MAX) {
+               cl_dbg_chip_err(chip, "wiring_id %u is not valid. [0..%u] are valid values\n",
+                               wiring_id, (FEM_WIRING_MAX - 1));
+               return -1;
+       }
+
+       if (cl_fem_check_lut_validity(chip, wiring_id))
+               return -1;
+
+       /* Write wiring ID to eeprom */
+       if (cl_e2p_write(chip, &wiring_id, SIZE_FEM_WIRING_ID, ADDR_FEM_WIRING_ID))
+               return -1;
+
+       chip->fem.wiring_id = wiring_id;
+       cl_dbg_chip_verbose(chip, "wiring_id is %u\n", chip->fem.wiring_id);
+
+       return 0;
+}
+
+static void update_set_channel_fem(struct cl_chip *chip, struct cl_hw *cl_hw)
+{
+       if (cl_hw && cl_chip_is_tcv_enabled(chip, cl_hw->tcv_idx))
+               cl_msg_tx_set_channel(cl_hw, cl_hw->channel, cl_hw->bw, cl_hw->primary_freq,
+                                     cl_hw->center_freq);
+}
+
+int cl_fem_set_wiring_id(struct cl_chip *chip, u8 wiring_id)
+{
+       int ret = cl_fem_write_wiring_id(chip, wiring_id);
+
+       if (ret)
+               return ret;
+
+       ret = cl_fem_update_conf_params(chip);
+
+       if (ret) {
+               cl_dbg_chip_err(chip, "Error occurred while updating configuration parameters.\n");
+               return ret;
+       }
+
+       update_set_channel_fem(chip, chip->cl_hw_tcv0);
+       update_set_channel_fem(chip, chip->cl_hw_tcv1);
+
+       cl_dbg_chip_trace(chip, "wiring_id = %u\n", chip->fem.wiring_id);
+
+       return 0;
+}
--
2.30.0

________________________________
The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any retransmission, dissemination, copying or other use of, or taking of any action in reliance upon this information is prohibited. If you received this in error, please contact the sender and delete the material from any computer. Nothing contained herein shall be deemed as a representation, warranty or a commitment by Celeno. No warranties are expressed or implied, including, but not limited to, any implied warranties of non-infringement, merchantability and fitness for a particular purpose.
________________________________






[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux