diff mbox series

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

Message ID 20210617160223.160998-84-viktor.barna@celeno.com (mailing list archive)
State RFC
Delegated to: Kalle Valo
Headers show
Series wireless: cl8k driver for Celeno IEEE 802.11ax devices | expand

Commit Message

Viktor Barna June 17, 2021, 3:59 p.m. UTC
From: Viktor Barna <viktor.barna@celeno.com>

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

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

--
2.30.0
diff mbox series

Patch

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;
+}