From 9228ce5aeae165286eecf2945b063892034cbdc5 Mon Sep 17 00:00:00 2001 From: Yair Shapira Date: Thu, 14 Jun 2012 11:37:00 +0300 Subject: [PATCH] calibrator: HP_FEM, add support for new FEMs in nvs file nvs file is now fully supported with new FEM types (2 and 3) including all relevant calibrator commands, error checkings and printouts. While FEM manuf can be 0,1,2,3 the FEM radio params are always stored in one of two entries: 0,1 (all FEM except 1 are stored in entry 0). Auto FEM detection support is still done by driver, therefore it is still limited to FEM types 0 and 1. Signed-off-by: Yair Shapira Signed-off-by: Luciano Coelho --- misc_cmds.c | 2 +- nvs.c | 91 ++++++++++++++++++++++++++++++++++++++--------------- plt.c | 23 +++++++++++--- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/misc_cmds.c b/misc_cmds.c index a650eaf..ba6597d 100644 --- a/misc_cmds.c +++ b/misc_cmds.c @@ -278,7 +278,7 @@ static int set_fem_manuf(struct nl80211_state *state, struct nl_cb *cb, return 0; } -COMMAND(set, fem_manuf, "<0|1> []", 0, 0, CIB_NONE, set_fem_manuf, +COMMAND(set, fem_manuf, "<0|1|2|3> []", 0, 0, CIB_NONE, set_fem_manuf, "Set FEM manufacturer"); static int get_drv_info(struct nl80211_state *state, struct nl_cb *cb, diff --git a/nvs.c b/nvs.c index 849f0b5..edde530 100644 --- a/nvs.c +++ b/nvs.c @@ -114,11 +114,10 @@ int nvs_set_mac(char *nvsfile, char *mac) return 0; } - - int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf) { struct wl1271_nvs_ini gp; + int fem_idx; if (ini) { /* Reset local NVS Radio Params */ @@ -131,16 +130,37 @@ int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf) if (gp.general_params.dual_mode_select) gp.stat_radio_params_5 = ini->ini1271.stat_radio_params_5; - gp.dyn_radio_params_2[0].params = - ini->ini1271.dyn_radio_params_2[0].params; - gp.dyn_radio_params_2[1].params = - ini->ini1271.dyn_radio_params_2[1].params; - - if (gp.general_params.dual_mode_select) { - gp.dyn_radio_params_5[0].params = - ini->ini1271.dyn_radio_params_5[0].params; - gp.dyn_radio_params_5[1].params = - ini->ini1271.dyn_radio_params_5[1].params; + if (gp.general_params.tx_bip_fem_auto_detect) { + /* For backward compatibility we fill the first 2 FEM entries */ + gp.dyn_radio_params_2[0].params = + ini->ini1271.dyn_radio_params_2[0].params; + gp.dyn_radio_params_2[1].params = + ini->ini1271.dyn_radio_params_2[1].params; + + if (gp.general_params.dual_mode_select) { + gp.dyn_radio_params_5[0].params = + ini->ini1271.dyn_radio_params_5[0].params; + gp.dyn_radio_params_5[1].params = + ini->ini1271.dyn_radio_params_5[1].params; + } + } + else { + /* + * Translate to NVS FEM entry + * In case of fem manufacturer 1 (TQS) use FEM idx 1 to maintain + * backward compatibilty. For all other types use idx 0 + */ + fem_idx = WL12XX_FEM_TO_NVS_ENTRY( + gp.general_params.tx_bip_fem_manufacturer); + + gp.dyn_radio_params_2[fem_idx].params = + ini->ini1271.dyn_radio_params_2 + [gp.general_params.tx_bip_fem_manufacturer].params; + + if (gp.general_params.dual_mode_select) + gp.dyn_radio_params_5[fem_idx].params = + ini->ini1271.dyn_radio_params_5 + [gp.general_params.tx_bip_fem_manufacturer].params; } write(fd, (const void *)&gp, sizeof(gp)); @@ -155,6 +175,7 @@ int nvs_fill_radio_params(int fd, struct wl12xx_ini *ini, char *buf) static int nvs_fill_radio_params_128x(int fd, struct wl12xx_ini *ini, char *buf) { struct wl128x_nvs_ini gp; + int fem_idx; if (ini) { /* Reset local NVS Radio Params */ @@ -168,17 +189,37 @@ static int nvs_fill_radio_params_128x(int fd, struct wl12xx_ini *ini, char *buf) if (gp.general_params.dual_mode_select) gp.stat_radio_params_5 = ini->ini128x.stat_radio_params_5; - /* For backward compatibility we fill the first 2 FEM entries */ - gp.dyn_radio_params_2[0].params = - ini->ini128x.dyn_radio_params_2[0].params; - gp.dyn_radio_params_2[1].params = - ini->ini128x.dyn_radio_params_2[1].params; - - if (gp.general_params.dual_mode_select) { - gp.dyn_radio_params_5[0].params = - ini->ini128x.dyn_radio_params_5[0].params; - gp.dyn_radio_params_5[1].params = - ini->ini128x.dyn_radio_params_5[1].params; + if (gp.general_params.tx_bip_fem_auto_detect) { + /* For backward compatibility we fill the first 2 FEM entries */ + gp.dyn_radio_params_2[0].params = + ini->ini128x.dyn_radio_params_2[0].params; + gp.dyn_radio_params_2[1].params = + ini->ini128x.dyn_radio_params_2[1].params; + + if (gp.general_params.dual_mode_select) { + gp.dyn_radio_params_5[0].params = + ini->ini128x.dyn_radio_params_5[0].params; + gp.dyn_radio_params_5[1].params = + ini->ini128x.dyn_radio_params_5[1].params; + } + } + else { + /* + * Translate to NVS FEM entry + * In case of fem manufacturer 1 (TQS) use FEM idx 1 to maintain + * backward compatibilty. For all other types use idx 0 + */ + fem_idx = WL12XX_FEM_TO_NVS_ENTRY( + gp.general_params.tx_bip_fem_manufacturer); + + gp.dyn_radio_params_2[fem_idx].params = + ini->ini128x.dyn_radio_params_2 + [gp.general_params.tx_bip_fem_manufacturer].params; + + if (gp.general_params.dual_mode_select) + gp.dyn_radio_params_5[fem_idx].params = + ini->ini128x.dyn_radio_params_5 + [gp.general_params.tx_bip_fem_manufacturer].params; } write(fd, (const void *)&gp, sizeof(gp)); @@ -1135,9 +1176,9 @@ int get_fem_nr(int autodetect, int manuf, int *femcnt, int *femi) } else { *femcnt = 1; - if(manuf >= WL12XX_NVS_FEM_MODULE_COUNT) { + if(manuf >= WL1271_INI_FEM_MODULE_COUNT) { fprintf(stderr, "FEM index out of bounds (%d > %d)\n", manuf, - WL12XX_NVS_FEM_MODULE_COUNT); + WL1271_INI_FEM_MODULE_COUNT); return 1; } diff --git a/plt.c b/plt.c index c120ecf..01e7f91 100644 --- a/plt.c +++ b/plt.c @@ -1034,20 +1034,20 @@ static int plt_autocalibrate(struct nl80211_state *state, struct nl_cb *cb, goto out_removenvs; } - fems_parsed = cmn.fem0_bands + cmn.fem1_bands; + fems_parsed = cmn.fem0_bands + cmn.fem1_bands + cmn.fem2_bands + cmn.fem3_bands; /* Get nr bands from parsed ini */ single_dual = ini_get_dual_mode(&cmn); if (single_dual == 0) { - if (fems_parsed < 1 || fems_parsed > 2) { + if (fems_parsed < 1 || fems_parsed > 4) { fprintf(stderr, "Incorrect number of FEM sections %d for single mode\n", fems_parsed); return 1; } } else if (single_dual == 1) { - if (fems_parsed < 2 && fems_parsed > 4) { + if (fems_parsed < 2 && fems_parsed > 8) { fprintf(stderr, "Incorrect number of FEM sections %d for dual mode\n", fems_parsed); return 1; @@ -1060,8 +1060,15 @@ static int plt_autocalibrate(struct nl80211_state *state, struct nl_cb *cb, } /* I suppose you can have one FEM with 2.4 only and one in dual band - but it's more likely a mistake */ - if ((single_dual + 1) * (cmn.auto_fem + 1) != fems_parsed) { + but it's more likely a mistake. + + In normal situation we have: + ---------------------------- + Single Band Manual - 1 FEM + Dual Band Manual - 2 FEMs + Single Band Auto Fem - 4 FEMs + Dual Band Auto Fem - 8 FEMs */ + if ((single_dual + 1) * (cmn.auto_fem * 3 + 1) != fems_parsed) { printf("WARNING: %d FEMS for %d bands with autofem %s looks " "like a strange configuration\n", fems_parsed, single_dual + 1, @@ -1115,6 +1122,12 @@ static int plt_autocalibrate(struct nl80211_state *state, struct nl_cb *cb, if (cmn.fem1_bands) { printf("FEM1 has %d bands. ", cmn.fem1_bands); } + if (cmn.fem2_bands) { + printf("FEM2 has %d bands. ", cmn.fem2_bands); + } + if (cmn.fem3_bands) { + printf("FEM3 has %d bands. ", cmn.fem3_bands); + } printf("AutoFEM is %s. ", cmn.auto_fem ? "on" : "off");