1 /* 2 * This file is part of wl1271 3 * 4 * Copyright (C) 2010 Nokia Corporation 5 * 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 * 22 */ 23 24 #ifndef __INI_H__ 25 #define __INI_H__ 26 27 #include <linux/limits.h> 28 29 #define WL1271_INI_MAX_SMART_REFLEX_PARAM 16 30 31 struct wl1271_ini_general_params { 32 unsigned char ref_clock; 33 unsigned char settling_time; 34 unsigned char clk_valid_on_wakeup; 35 unsigned char dc2dc_mode; 36 unsigned char dual_mode_select; 37 unsigned char tx_bip_fem_auto_detect; 38 unsigned char tx_bip_fem_manufacturer; 39 unsigned char general_settings; 40 unsigned char sr_state; 41 unsigned char srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM]; 42 unsigned char srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM]; 43 unsigned char srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM]; 44 } __attribute__((packed)); 45 46 #define WL128X_INI_MAX_SETTINGS_PARAM 4 47 48 struct wl128x_ini_general_params { 49 unsigned char ref_clock; 50 unsigned char settling_time; 51 unsigned char clk_valid_on_wakeup; 52 unsigned char tcxo_ref_clock; 53 unsigned char tcxo_settling_time; 54 unsigned char tcxo_valid_on_wakeup; 55 unsigned char tcxo_ldo_voltage; 56 unsigned char xtal_itrim_val; 57 unsigned char platform_conf; 58 unsigned char dual_mode_select; 59 unsigned char tx_bip_fem_auto_detect; 60 unsigned char tx_bip_fem_manufacturer; 61 unsigned char general_settings[WL128X_INI_MAX_SETTINGS_PARAM]; 62 unsigned char sr_state; 63 unsigned char srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM]; 64 unsigned char srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM]; 65 unsigned char srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM]; 66 } __attribute__((packed)); 67 68 #define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15 69 70 struct wl1271_ini_band_params_2 { 71 unsigned char rx_trace_insertion_loss; 72 unsigned char tx_trace_loss; 73 unsigned char 74 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; 75 } __attribute__((packed)); 76 77 #define WL1271_INI_CHANNEL_COUNT_2 14 78 79 struct wl128x_ini_band_params_2 { 80 unsigned char rx_trace_insertion_loss; 81 unsigned char tx_trace_loss[WL1271_INI_CHANNEL_COUNT_2]; 82 unsigned char 83 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; 84 } __attribute__((packed)); 85 86 #define WL1271_INI_RATE_GROUP_COUNT 6 87 88 struct wl1271_ini_fem_params_2 { 89 __le16 tx_bip_ref_pd_voltage; 90 unsigned char tx_bip_ref_power; 91 unsigned char tx_bip_ref_offset; 92 unsigned char 93 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT]; 94 unsigned char 95 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT]; 96 unsigned char 97 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT]; 98 unsigned char tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2]; 99 unsigned char tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2]; 100 unsigned char tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT]; 101 unsigned char tx_ibias[WL1271_INI_RATE_GROUP_COUNT]; 102 unsigned char rx_fem_insertion_loss; 103 unsigned char degraded_low_to_normal_thr; 104 unsigned char normal_to_degraded_high_thr; 105 } __attribute__((packed)); 106 107 #define WL128X_INI_RATE_GROUP_COUNT 7 108 /* low and high temperatures*/ 109 #define WL128X_INI_PD_VS_TEMPERATURE_RANGES 2 110 111 struct wl128x_ini_fem_params_2 { 112 __le16 tx_bip_ref_pd_voltage; 113 unsigned char tx_bip_ref_power; 114 unsigned char tx_bip_ref_offset; 115 unsigned char 116 tx_per_rate_pwr_limits_normal [WL128X_INI_RATE_GROUP_COUNT]; 117 unsigned char 118 tx_per_rate_pwr_limits_degraded [WL128X_INI_RATE_GROUP_COUNT]; 119 unsigned char 120 tx_per_rate_pwr_limits_extreme [WL128X_INI_RATE_GROUP_COUNT]; 121 unsigned char tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2]; 122 unsigned char tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2]; 123 unsigned char tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT]; 124 unsigned char tx_ibias[WL128X_INI_RATE_GROUP_COUNT + 1]; 125 unsigned char tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_2]; 126 unsigned char tx_pd_vs_temperature[WL128X_INI_PD_VS_TEMPERATURE_RANGES]; 127 unsigned char rx_fem_insertion_loss; 128 unsigned char degraded_low_to_normal_thr; 129 unsigned char normal_to_degraded_high_thr; 130 } __attribute__((packed)); 131 132 #define WL1271_INI_CHANNEL_COUNT_5 35 133 #define WL1271_INI_SUB_BAND_COUNT_5 7 134 135 struct wl1271_ini_band_params_5 { 136 unsigned char rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; 137 unsigned char tx_trace_loss[WL1271_INI_SUB_BAND_COUNT_5]; 138 unsigned char 139 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; 140 } __attribute__((packed)); 141 142 struct wl128x_ini_band_params_5 { 143 unsigned char rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; 144 unsigned char tx_trace_loss[WL1271_INI_CHANNEL_COUNT_5]; 145 unsigned char 146 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; 147 } __attribute__((packed)); 148 149 struct wl1271_ini_fem_params_5 { 150 __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5]; 151 unsigned char tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5]; 152 unsigned char tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5]; 153 unsigned char 154 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT]; 155 unsigned char 156 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT]; 157 unsigned char 158 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT]; 159 unsigned char tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5]; 160 unsigned char tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT]; 161 unsigned char tx_ibias[WL1271_INI_RATE_GROUP_COUNT]; 162 unsigned char rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; 163 unsigned char degraded_low_to_normal_thr; 164 unsigned char normal_to_degraded_high_thr; 165 } __attribute__((packed)); 166 167 struct wl128x_ini_fem_params_5 { 168 __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5]; 169 unsigned char tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5]; 170 unsigned char tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5]; 171 unsigned char 172 tx_per_rate_pwr_limits_normal [WL128X_INI_RATE_GROUP_COUNT]; 173 unsigned char 174 tx_per_rate_pwr_limits_degraded [WL128X_INI_RATE_GROUP_COUNT]; 175 unsigned char 176 tx_per_rate_pwr_limits_extreme [WL128X_INI_RATE_GROUP_COUNT]; 177 unsigned char tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5]; 178 unsigned char tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT]; 179 unsigned char tx_ibias[WL128X_INI_RATE_GROUP_COUNT]; 180 unsigned char tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_5]; 181 unsigned char tx_pd_vs_temperature[WL1271_INI_SUB_BAND_COUNT_5 * 182 WL128X_INI_PD_VS_TEMPERATURE_RANGES]; 183 unsigned char rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; 184 unsigned char degraded_low_to_normal_thr; 185 unsigned char normal_to_degraded_high_thr; 186 } __attribute__((packed)); 187 188 /* NVS data structure */ 189 #define WL1271_INI_NVS_SECTION_SIZE 468 190 #define WL1271_INI_FEM_MODULE_COUNT 2 191 192 #define WL1271_INI_LEGACY_NVS_FILE_SIZE 800 193 194 struct wl1271_nvs_file { 195 /* NVS section */ 196 unsigned char nvs[WL1271_INI_NVS_SECTION_SIZE]; 197 198 /* INI section */ 199 struct wl1271_ini_general_params general_params; 200 unsigned char padding1; 201 struct wl1271_ini_band_params_2 stat_radio_params_2; 202 unsigned char padding2; 203 struct { 204 struct wl1271_ini_fem_params_2 params; 205 unsigned char padding; 206 } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; 207 struct wl1271_ini_band_params_5 stat_radio_params_5; 208 unsigned char padding3; 209 struct { 210 struct wl1271_ini_fem_params_5 params; 211 unsigned char padding; 212 } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; 213 } __attribute__((packed)); 214 215 struct wl128x_nvs_file { 216 /* NVS section */ 217 unsigned char nvs[WL1271_INI_NVS_SECTION_SIZE]; 218 219 /* INI section */ 220 struct wl128x_ini_general_params general_params; 221 unsigned char fem_vendor_and_options; 222 struct wl128x_ini_band_params_2 stat_radio_params_2; 223 unsigned char padding2; 224 struct { 225 struct wl128x_ini_fem_params_2 params; 226 unsigned char padding; 227 } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; 228 struct wl128x_ini_band_params_5 stat_radio_params_5; 229 unsigned char padding3; 230 struct { 231 struct wl128x_ini_fem_params_5 params; 232 unsigned char padding; 233 } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; 234 } __attribute__((packed)); 235 236 struct wl1271_ini { 237 struct wl1271_ini_general_params general_params; 238 unsigned char padding1; 239 struct wl1271_ini_band_params_2 stat_radio_params_2; 240 unsigned char padding2; 241 struct { 242 struct wl1271_ini_fem_params_2 params; 243 unsigned char padding; 244 } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; 245 struct wl1271_ini_band_params_5 stat_radio_params_5; 246 unsigned char padding3; 247 struct { 248 struct wl1271_ini_fem_params_5 params; 249 unsigned char padding; 250 } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; 251 } __attribute__((packed)); 252 253 struct wl128x_ini { 254 struct wl128x_ini_general_params general_params; 255 unsigned char fem_vendor_and_options; 256 struct wl128x_ini_band_params_2 stat_radio_params_2; 257 unsigned char padding2; 258 struct { 259 struct wl128x_ini_fem_params_2 params; 260 unsigned char padding; 261 } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; 262 struct wl128x_ini_band_params_5 stat_radio_params_5; 263 unsigned char padding3; 264 struct { 265 struct wl128x_ini_fem_params_5 params; 266 unsigned char padding; 267 } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; 268 } __attribute__((packed)); 269 270 enum wl1271_ini_section { 271 UKNOWN_SECTION, 272 GENERAL_PRMS, 273 FEM_PRMS, 274 BAND2_PRMS, 275 BAND5_PRMS, 276 FEM0_BAND2_PRMS, 277 FEM1_BAND2_PRMS, 278 FEM1_BAND5_PRMS 279 }; 280 281 enum wl12xx_arch { 282 UNKNOWN_ARCH, 283 WL1271_ARCH, 284 WL128X_ARCH 285 }; 286 287 struct wl12xx_ini { 288 union { 289 struct wl1271_ini ini1271; 290 struct wl128x_ini ini128x; 291 }; 292 }; 293 294 #define DUAL_MODE_UNSET 0xff 295 #define NO_FEM_PARSED 0xff 296 297 struct wl12xx_common { 298 enum wl12xx_arch arch; 299 unsigned char dual_mode; 300 unsigned char done_fem; /* Number of FEM already parsed */ 301 struct wl12xx_parse_ops *parse_ops; 302 struct wl12xx_nvs_ops *nvs_ops; 303 struct wl12xx_ini ini; 304 }; 305 306 struct wl12xx_parse_ops { 307 int (*prs_general_prms)(char *l, struct wl12xx_common *cmn, 308 struct wl12xx_ini *p); 309 /* int (*prs_fem_prms)(char *l, void *gp); */ 310 int (*prs_band2_prms)(char *l, struct wl12xx_ini *p); 311 int (*prs_band5_prms)(char *l, struct wl12xx_ini *p); 312 int (*prs_fem0_band2_prms)(char *l, struct wl12xx_ini *p); 313 int (*prs_fem1_band2_prms)(char *l, struct wl12xx_ini *p); 314 int (*prs_fem1_band5_prms)(char *l, struct wl12xx_ini *p); 315 }; 316 317 struct wl12xx_nvs_ops { 318 int (*nvs_fill_radio_prms)(int fd, struct wl12xx_ini *p, char *buf); 319 int (*nvs_set_autofem)(int fd, char *buf, unsigned char val); 320 int (*nvs_set_fem_manuf)(int fd, char *buf, unsigned char val); 321 }; 322 323 int nvs_get_arch(int file_size, struct wl12xx_common *cmn); 324 325 int read_ini(const char *filename, struct wl12xx_common *cmn); 326 327 #endif 328