1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "oslo_config_test"
18
19 #include <errno.h>
20 #include <getopt.h>
21 #include <inttypes.h>
22 #include <limits.h>
23 #include <log/log.h>
24 #include <math.h>
25 #include <stdbool.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/ioctl.h>
30 #include <time.h>
31 #include <unistd.h>
32
33 #include "oslo_iaxxx_sensor_control.h"
34 #include "oslo_sound_model_control.h"
35
36 #define GETOPT_HELP_CHAR (CHAR_MIN - 2)
37
38 #define BGT60TR24C_NUM_REGISTERS 0x60
39
40 /* Oslo Calibration */
41 #define CAL_FILE "/mnt/vendor/persist/oslo/oslo.cal"
42 #define CAL_MODES_MAX 10
43 #define CAL_INVALID_MODE -1
44 #define CAL_MODE_IS_VALID(x) (x >= 0 && x < CAL_MODES_MAX)
45 #define CAL_VERSION_DEFAULT 1.0f
46
47 /* Transmit power */
48 #define TX_CAL_FILE "/mnt/vendor/persist/oslo/tx_power.cal"
49
50 typedef enum {
51 INJECT_MODE_OFF = 0,
52 INJECT_MODE_PRESENCE,
53 INJECT_MODE_REACH,
54 INJECT_MODE_NUM,
55 } oslo_inject_mode_t;
56
57 typedef struct {
58 int setting_id;
59 char *setting_name;
60 } oslo_settings_t;
61
62 /* map oslo driver setting name to param id */
63 static const oslo_settings_t oslo_driver_settings[] =
64 {
65 {SENSOR_PARAM_FRAMES_PROCESSED, "frames_processed"},
66 {SENSOR_PARAM_PRESET_RADAR_CONFIG, "preset_radar_config"},
67 {OSLO_CONFIG_DEFAULT, "config_default"},
68 {OSLO_CONFIG_PRESENCE, "config_presence"},
69 {OSLO_CONFIG_CONTINUOUS, "config_continuous"},
70 {OSLO_CONFIG_PRESENCE_SLOW, "config_presence_slow"},
71 {OSLO_CONFIG_FACTORY_PRESENCE, "config_factory_presence"},
72 {OSLO_CONFIG_FACTORY_REACH, "config_factory_reach"},
73 {OSLO_CONFIG_CW_MODE, "config_cw_mode"},
74 {OSLO_CONFIG_FACTORY_PRESENCE_V1, "config_factory_presence_v1"},
75 {OSLO_CONFIG_FACTORY_REACH_V1, "config_factory_reach_v1"},
76 {OSLO_CONFIG_REACH, "config_reach"},
77 {OSLO_CONFIG_PRESENCE_V1, "config_presence_v1"},
78 {OSLO_CONFIG_REACH_V1, "config_reach_v1"},
79 {OSLO_CONFIG_OFF, "config_off"},
80 {OSLO_CONTROL_RESTART, "oslo_control_restart"},
81 {OSLO_CONTROL_STRIP_HEADERS, "oslo_control_strip_headers"},
82 {OSLO_CONTROL_SLPI_INT, "oslo_control_slpi_interrupt"},
83 {OSLO_CONTROL_STOP, "oslo_control_stop"},
84 {OSLO_CONTROL_SIMULATE_RADAR_DATA, "oslo_control_simulate_radar_data"},
85 {OSLO_CONTROL_ASSERT_RESET, "oslo_control_assert_reset"},
86 {OSLO_PARAM_REQUEST_RATE, "param_request_rate"},
87 {OSLO_PARAM_REQUEST_ANTENNA_MASK, "param_request_antenna_mask"},
88 {OSLO_PARAM_TX_POWER, "param_tx_power"},
89 {OSLO_PARAM_LOWER_FREQ, "param_lower_freq"},
90 {OSLO_PARAM_UPPER_FREQ, "param_upper_freq"},
91 {OSLO_PARAM_SAMPLES_PER_CHIRP, "param_samples_per_chirp"},
92 {OSLO_PARAM_VGA_GAIN_CH1, "param_vga_gain_ch1"},
93 {OSLO_PARAM_VGA_GAIN_CH2, "param_vga_gain_ch2"},
94 {OSLO_PARAM_VGA_GAIN_CH3, "param_vga_gain_ch3"},
95 {OSLO_PARAM_VGA_GAIN_CH4, "param_vga_gain_ch4"},
96 {OSLO_PARAM_BURST_CHIRP_COUNT, "param_burst_chirp_count"},
97 {OSLO_PARAM_BURST_CHIRP_RATE, "param_burst_chirp_rate"},
98 {OSLO_PARAM_BURST_POWER_MODE, "param_burst_power_mode"},
99 {OSLO_PARAM_BURST_INTERCHIRP_POWER_MODE, "param_burst_interchirp_power_mode"},
100 {OSLO_PARAM_STARTUP_TIMING_WAKE_UP_TIME_100NS, "param_startup_timing_wake_up_time_100ns"},
101 {OSLO_PARAM_STARTUP_TIMING_PLL_SETTLE_TIME_COARSE_100NS,"param_startup_timing_pll_settle_time_coarse_100ns"},
102 {OSLO_PARAM_STARTUP_TIMING_PLL_SETTLE_TIME_FINE_100NS, "param_startup_timing_pll_settle_time_fine_100ns"},
103 {OSLO_PARAM_STARTUP_TIMING_OSCILLATOR_USEC, "param_startup_timing_oscillator_usec"},
104 {OSLO_PARAM_PRE_CHIRP_DELAY_100NS, "param_pre_chirp_delay_100ns"},
105 {OSLO_PARAM_POST_CHIRP_DELAY_100NS, "param_post_chirp_delay_100ns"},
106 {OSLO_PARAM_CHIRP_PA_DELAY_100NS, "param_chirp_pa_delay_100ns"},
107 {OSLO_PARAM_CHIRP_ADC_DELAY_100NS, "param_chirp_adc_delay_100ns"},
108 {OSLO_PARAM_VISUALIZER_DATA_TYPE, "param_visualizer_data_type"},
109 {OSLO_PARAM_OSCILLATOR_MODE, "param_oscillator_mode"},
110 {OSLO_PARAM_HP_GAIN_CH1, "param_hp_gain_ch1"},
111 {OSLO_PARAM_HP_GAIN_CH2, "param_hp_gain_ch2"},
112 {OSLO_PARAM_HP_GAIN_CH3, "param_hp_gain_ch3"},
113 {OSLO_PARAM_HP_GAIN_CH4, "param_hp_gain_ch4"},
114 {OSLO_PARAM_BASEBAND_RESET_PERIOD_1NS, "param_baseband_reset_period_1ns"},
115 {OSLO_PARAM_HP_CUTOFF_CH1, "param_hp_cutoff_ch1"},
116 {OSLO_PARAM_HP_CUTOFF_CH2, "param_hp_cutoff_ch2"},
117 {OSLO_PARAM_HP_CUTOFF_CH3, "param_hp_cutoff_ch3"},
118 {OSLO_PARAM_HP_CUTOFF_CH4, "param_hp_cutoff_ch4"},
119 {OSLO_PARAM_PHASE_CONFIG, "param_phase_config"},
120 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_PLL, "param_idle_settings_enable_pll"},
121 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_VCO, "param_idle_settings_enable_vco"},
122 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_FDIV, "param_idle_settings_enable_fdiv"},
123 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_BASEBAND, "param_idle_settings_enable_baseband"},
124 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_RF, "param_idle_settings_enable_rf"},
125 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_MADC, "param_idle_settings_enable_madc"},
126 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_MADC_BANDGAP, "param_idle_settings_enable_madc_bandgap"},
127 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_SADC, "param_idle_settings_enable_sadc"},
128 {OSLO_PARAM_IDLE_SETTINGS_ENABLE_SADC_BANDGAP, "param_idle_settings_enable_sadc_bandgap"},
129 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_PLL, "param_deep_sleep_settings_enable_pll"},
130 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_VCO, "param_deep_sleep_settings_enable_vco"},
131 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_FDIV, "param_deep_sleep_settings_enable_fdiv"},
132 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_BASEBAND, "param_deep_sleep_settings_enable_baseband"},
133 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_RF, "param_deep_sleep_settings_enable_rf"},
134 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_MADC, "param_deep_sleep_settings_enable_madc"},
135 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_MADC_BANDGAP, "param_deep_sleep_settings_enable_madc_bandgap"},
136 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_SADC, "param_deep_sleep_settings_enable_sadc"},
137 {OSLO_PARAM_DEEP_SLEEP_SETTINGS_ENABLE_SADC_BANDGAP, "param_deep_sleep_settings_enable_sadc_bandgap"},
138 {OSLO_PARAM_CHIRP_DIRECTION, "param_chirp_direction"},
139 {OSLO_PARAM_ADC_SAMPLE_RATE, "param_adc_sample_rate"},
140 {OSLO_PARAM_CHARGE_PUMP, "param_charge_pump"},
141 };
142
143 /* map oslo plugin setting name to param id */
144 static const oslo_settings_t oslo_plugin_settings[] =
145 {
146 {OSLO_SENSOR_PARAM_MODE, "plugin_mode"},
147 {OSLO_SENSOR_PARAM_SLPY_STATE, "plugin_slpy_state"},
148 {OSLO_SENSOR_PARAM_ENABLE_SLPY_RAW, "plugin_slpy_raw"},
149 {OSLO_SENSOR_PARAM_HOST, "plugin_set_host"},
150 {OSLO_SENSOR_STATE, "plugin_oslo_state"},
151 {OSLO_SENSOR_CONFIG_RECOVERY_COUNTER, "plugin_config_retries"},
152 {OSLO_SENSOR_PARAM_ENABLE_PRESENCE, "plugin_enable_presence"},
153 {OSLO_SENSOR_PARAM_ENABLE_REACH, "plugin_enable_reach"},
154 {OSLO_SENSOR_PARAM_ENABLE_FLICK, "plugin_enable_flick"},
155 {OSLO_SENSOR_PARAM_ENABLE_SWIPE, "plugin_enable_swipe"},
156 {OSLO_SENSOR_PARAM_ENABLE_TAP, "plugin_enable_tap"},
157 {OSLO_SENSOR_PARAM_ENABLE_AUDIO_FILTER, "plugin_enable_audio_filter"},
158 {OSLO_SENSOR_PARAM_ENABLE_WLC_FILTER, "plugin_enable_wlc_filter"},
159 {OSLO_SENSOR_PARAM_CPS, "plugin_cps"},
160 {OSLO_SENSOR_MAX_POWER_MODE, "plugin_max_power_mode"},
161 {OSLO_SENSOR_PARAM_SLPY_TEST_MODE, "plugin_slpy_test_mode"},
162 };
163
164 /* map oslo plugin test mode name to param id */
165 static const oslo_settings_t oslo_plugin_test_mode[] =
166 {
167 {OSLO_TESTMODE_RESET, "reset"},
168 {OSLO_TESTMODE_PRESENCE_ON, "presence_on"},
169 {OSLO_TESTMODE_PRESENCE_OFF, "presence_off"},
170 {OSLO_TESTMODE_SWIPE, "swipe"},
171 {OSLO_TESTMODE_FLICK, "flick"},
172 {OSLO_TESTMODE_REACH_IN, "reach_in"},
173 {OSLO_TESTMODE_REACH_OUT, "reach_out"},
174 {OSLO_TESTMODE_REACH_SWIPE, "reach+swipe"},
175 {OSLO_TESTMODE_REACH_FLICK, "reach+flick"},
176 {OSLO_TESTMODE_REACH_SWIPE_FLICK, "reach+swipe+flick"},
177 };
178 #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
179 #define OSLO_DRIVER_SETTINGS_SIZE COUNT_OF(oslo_driver_settings)
180 #define OSLO_PLUGIN_SETTINGS_SIZE COUNT_OF(oslo_plugin_settings)
181 #define OSLO_PLUGIN_TESTMODE_SIZE COUNT_OF(oslo_plugin_test_mode)
182
183 struct cal_coefficient {
184 float version;
185 int mode;
186 float ch1_i_val;
187 float ch1_q_val;
188 float ch2_i_val;
189 float ch2_q_val;
190 float ch3_i_val;
191 float ch3_q_val;
192 };
193 static struct cal_coefficient cal_table[CAL_MODES_MAX];
194 static uint32_t tx_power_cal;
195
196 static struct option const long_options[] =
197 {
198 {"setparamid", required_argument, NULL, 's'},
199 {"value", required_argument, NULL, 'v'},
200 {"getparamid", required_argument, NULL, 'g'},
201 {"ping", required_argument, NULL, 'p'},
202 {"route", required_argument, NULL, 'r'},
203 {"readregister", required_argument, NULL, 'd'},
204 {"writeregister", required_argument, NULL, 'w'},
205 {"calibration", required_argument, NULL, 'c'},
206 {"tx power cal", required_argument, NULL, 'e'},
207 {"injection", required_argument, NULL, 'i'},
208 {"help", no_argument, NULL, GETOPT_HELP_CHAR},
209 {NULL, 0, NULL, 0}
210 };
211
usage()212 void usage() {
213 fputs("\
214 USAGE -\n\
215 -------\n\
216 1) oslo_config_test -s <param_name> -v <param_val>\n\
217 2) oslo_config_test -g <param_name>\n\
218 \n\
219 In the first form, set a parameter with a value.\n\
220 In the second form, get a value of a parameter\n\
221 \n\
222 3) oslo_config_test -p <timeout>\n\
223 4) oslo_config_test -r <1/0>\n\
224 5) oslo_config_test -d <reg_addr>\n\
225 6) oslo_config_test -w <reg_addr> -v <reg_val>\n\
226 7) oslo_config_test -c 'V:<ver> M:<mode> <ch1 I_val> <ch1 Q_val> <ch2 I_val> <ch2 Q_val> <ch3 I_val> <ch3 Q_val>' \n\
227 8) oslo_config_test -t <test_mode> -v <elapsed time>\n\
228 9) oslo_config_test -i <0/1/2> # 0:off 1:entrance 2:interactive \n\
229 10) oslo_config_test -e '<tx_val>'\n\
230 ", stdout);
231
232 fputs("\n\
233 OPTIONS - \n\
234 ---------\n\
235 -s Set a parameter using its <param_name>.\n\
236 -v Set this value for the parameter ID that was passed with\n\
237 the option '-s'. Using this option alone is invalid.\n\
238 -g Get the value of a parameter using its <param_name>.\n\
239 -p Ping oslo sensor.\n\
240 -r Set sensor route.\n\
241 -d Read register.\n\
242 -w Write register.\n\
243 -c Store Calibration coefficients to persist file.\n\
244 -t Set the system into a test mode with optional gesture detection spoofing.\n\
245 -i Set the system into data injection mode.\n\
246 -e Store Tx power calibration to persist file.\n\
247 ", stdout);
248
249 fputs("\n\
250 List of all <param_name>\n\
251 ---------\
252 ", stdout);
253 fputs("\n", stdout);
254
255 unsigned int i;
256 for (i = 0; i < OSLO_DRIVER_SETTINGS_SIZE; i++) {
257 fprintf(stdout, " %s\n", oslo_driver_settings[i].setting_name, stdout);
258 }
259 for (i = 0; i < OSLO_PLUGIN_SETTINGS_SIZE; i++) {
260 fprintf(stdout, " %s\n", oslo_plugin_settings[i].setting_name, stdout);
261 }
262
263 fputs("\n\
264 List of all <test_mode>\n\
265 ---------\
266 ", stdout);
267 fputs("\n", stdout);
268
269 for (i = 0; i < OSLO_PLUGIN_TESTMODE_SIZE; i++) {
270 fprintf(stdout, " %s\n", oslo_plugin_test_mode[i].setting_name, stdout);
271 }
272
273 exit(EXIT_FAILURE);
274 }
275
oslo_driver_setting_lookup(char * in)276 int oslo_driver_setting_lookup(char *in)
277 {
278 unsigned int i;
279 int ret = -1;
280
281 for (i = 0; i < OSLO_DRIVER_SETTINGS_SIZE; i++)
282 {
283 if (strcmp(in, oslo_driver_settings[i].setting_name) == 0)
284 {
285 ret = oslo_driver_settings[i].setting_id;
286 break;
287 }
288 }
289
290 return ret;
291 }
292
oslo_plugin_setting_lookup(char * in)293 int oslo_plugin_setting_lookup(char *in)
294 {
295 unsigned int i;
296 int ret = -1;
297
298 for (i = 0; i < OSLO_PLUGIN_SETTINGS_SIZE; i++)
299 {
300 if (strcmp(in, oslo_plugin_settings[i].setting_name) == 0)
301 {
302 ret = oslo_plugin_settings[i].setting_id;
303 break;
304 }
305 }
306
307 return ret;
308 }
309
oslo_plugin_test_mode_lookup(char * in)310 int oslo_plugin_test_mode_lookup(char *in)
311 {
312 unsigned int i;
313 int ret = -1;
314
315 for (i = 0; i < OSLO_PLUGIN_TESTMODE_SIZE; i++)
316 {
317 if (strcmp(in, oslo_plugin_test_mode[i].setting_name) == 0)
318 {
319 ret = oslo_plugin_test_mode[i].setting_id;
320 break;
321 }
322 }
323
324 return ret;
325 }
326
oslo_enable(struct ia_sensor_mgr * smd,bool enable)327 void oslo_enable(struct ia_sensor_mgr *smd, bool enable) {
328 if (enable) {
329 osloSoundModelEnable(true);
330 oslo_driver_set_param(smd, OSLO_CONTROL_RESTART, 1);
331 }
332 else {
333 oslo_driver_set_param(smd, OSLO_CONTROL_STOP, 0);
334 sleep(1);
335 osloSoundModelEnable(false);
336 }
337 }
338
ping_test(struct ia_sensor_mgr * smd,uint32_t ping_timeout_sec)339 bool ping_test(struct ia_sensor_mgr *smd, uint32_t ping_timeout_sec) {
340 bool ret = false;
341 uint32_t radar_frames_initial;
342 time_t start_time;
343
344 oslo_enable(smd, true);
345
346 start_time = time(NULL);
347 radar_frames_initial = oslo_driver_get_param(smd, SENSOR_PARAM_FRAMES_PROCESSED);
348
349 do {
350 uint32_t radar_frames = oslo_driver_get_param(smd, SENSOR_PARAM_FRAMES_PROCESSED);
351 if (radar_frames > radar_frames_initial) {
352 ALOGD("%s: frame number increased (%d, %d)",
353 __func__, radar_frames_initial, radar_frames);
354 ret = true;
355 break;
356 }
357 else
358 usleep(50 * 1000); // 50ms
359 } while (difftime(time(NULL), start_time) <= ping_timeout_sec);
360
361 oslo_enable(smd, false);
362
363 ALOGD("%s: %s", __func__, (ret ? "PASS" : "FAIL"));
364 fprintf(stdout, "%s: %s\n", __func__, (ret ? "PASS" : "FAIL"));
365
366 return ret;
367 }
368
read_register(struct ia_sensor_mgr * smd,uint32_t reg_addr)369 void read_register(struct ia_sensor_mgr *smd, uint32_t reg_addr) {
370 uint32_t reg_val;
371
372 if (reg_addr >= BGT60TR24C_NUM_REGISTERS) {
373 fprintf(stdout, "Invalid reg addr:0x%02x\n", reg_addr);
374 return;
375 }
376
377 reg_val = oslo_driver_get_param(smd, OSLO_REGISTER_MIN + reg_addr);
378
379 ALOGD("reg[0x%02x]: 0x%06x\n", reg_addr, reg_val);
380 fprintf(stdout, "reg[0x%02x]: 0x%06x\n", reg_addr, reg_val);
381 }
382
write_register(struct ia_sensor_mgr * smd,uint32_t reg_addr,uint32_t reg_val)383 void write_register(struct ia_sensor_mgr *smd, uint32_t reg_addr, uint32_t reg_val) {
384 if (reg_addr >= BGT60TR24C_NUM_REGISTERS) {
385 fprintf(stdout, "Invalid reg addr:0x%02x\n", reg_addr);
386 return;
387 }
388
389 oslo_driver_set_param(smd, OSLO_REGISTER_MIN + reg_addr, reg_val);
390
391 ALOGD("Write reg[0x%02x] val:0x%06x\n", reg_addr, reg_val);
392 fprintf(stdout, "Write reg[0x%02x] val:0x%06x\n", reg_addr, reg_val);
393 }
394
cal_read_persist(void)395 int cal_read_persist(void) {
396 FILE *fid;
397 struct cal_coefficient coef;
398
399 fid = fopen(CAL_FILE, "r");
400 if (fid == NULL) {
401 ALOGD("%s: Cannot open '%s'\n", __func__, CAL_FILE);
402 return -errno;
403 }
404
405 while (!feof(fid)) {
406 int num;
407
408 memset(&coef, 0, sizeof(coef));
409 coef.mode = CAL_INVALID_MODE;
410
411 num = fscanf(fid, "Version: %f\n", &coef.version);
412 if (num != 1) {
413 ALOGE("%s: Parse Version failed, num:%d\n", __func__, num);
414 coef.version = CAL_VERSION_DEFAULT;
415 }
416
417 num = fscanf(fid, "Mode: %d\n", &coef.mode);
418 if (num != 1) {
419 ALOGE("%s: Parse Mode failed, num:%d\n", __func__, num);
420 break;
421 }
422
423 num = fscanf(fid, "ch1: %f %f\n", &coef.ch1_i_val, &coef.ch1_q_val);
424 if (num != 2) {
425 ALOGE("%s: Parse ch1 failed, num:%d\n", __func__, num);
426 break;
427 }
428
429 num = fscanf(fid, "ch2: %f %f\n", &coef.ch2_i_val, &coef.ch2_q_val);
430 if (num != 2) {
431 ALOGE("%s: Parse ch2 failed, num:%d\n", __func__, num);
432 break;
433 }
434
435 num = fscanf(fid, "ch3: %f %f\n", &coef.ch3_i_val, &coef.ch3_q_val);
436 if (num != 2) {
437 ALOGE("%s: Parse ch3 failed, num:%d\n", __func__, num);
438 break;
439 }
440
441 if (CAL_MODE_IS_VALID(coef.mode)) {
442 memcpy(&cal_table[coef.mode], &coef, sizeof(coef));
443 ALOGD("%s: %.1f %d %f %f %f %f %f %f\n", __func__,
444 coef.version,
445 coef.mode,
446 coef.ch1_i_val, coef.ch1_q_val,
447 coef.ch2_i_val, coef.ch2_q_val,
448 coef.ch3_i_val, coef.ch3_q_val);
449 } else {
450 ALOGE("%s: Invalid mode:%d\n", __func__, coef.mode);
451 }
452 }
453
454 fclose(fid);
455
456 return 0;
457 }
458
cal_write_persist(const struct cal_coefficient * coef)459 int cal_write_persist(const struct cal_coefficient* coef) {
460 FILE *fid;
461
462 if (!coef) {
463 ALOGE("%s: Invalid coef", __func__);
464 fprintf(stdout, "%s: Invalid coef\n", __func__);
465 return -EINVAL;
466 }
467
468 if (!CAL_MODE_IS_VALID(coef->mode)) {
469 ALOGE("%s: Invalid mode:%d", __func__, coef->mode);
470 fprintf(stdout, "%s: Invalid mode:%d\n", __func__, coef->mode);
471 return -EINVAL;
472 }
473
474 fid = fopen(CAL_FILE, "w");
475 if (fid == NULL) {
476 ALOGE("Cannot open '%s' (%s)\n", CAL_FILE, strerror(errno));
477 fprintf(stdout, "Cannot open '%s' (%s)\n", CAL_FILE, strerror(errno));
478 return -errno;
479 }
480
481 memcpy(&cal_table[coef->mode], coef, sizeof(struct cal_coefficient));
482 for (int i = 0; i < CAL_MODES_MAX; i++) {
483 if (CAL_MODE_IS_VALID(cal_table[i].mode)) {
484 fprintf(fid, "Version: %.1f\n", cal_table[i].version);
485 fprintf(fid, "Mode: %u\n", cal_table[i].mode);
486 fprintf(fid, "ch1: %f %f\n",
487 cal_table[i].ch1_i_val,
488 cal_table[i].ch1_q_val);
489 fprintf(fid, "ch2: %f %f\n",
490 cal_table[i].ch2_i_val,
491 cal_table[i].ch2_q_val);
492 fprintf(fid, "ch3: %f %f\n",
493 cal_table[i].ch3_i_val,
494 cal_table[i].ch3_q_val);
495 ALOGD("%s: %.1f %d %f %f %f %f %f %f\n", __func__,
496 cal_table[i].version,
497 cal_table[i].mode,
498 cal_table[i].ch1_i_val, cal_table[i].ch1_q_val,
499 cal_table[i].ch2_i_val, cal_table[i].ch2_q_val,
500 cal_table[i].ch3_i_val, cal_table[i].ch3_q_val);
501 }
502 }
503
504 fclose(fid);
505
506 return 0;
507 }
508
read_tx_power_from_persist(void)509 static int read_tx_power_from_persist(void) {
510 FILE *fid;
511 uint32_t tx_power = 0;
512
513 fid = fopen(TX_CAL_FILE, "r");
514 if (fid == NULL) {
515 ALOGD("%s: Cannot open '%s'\n", __func__, TX_CAL_FILE);
516 return -errno;
517 }
518
519 while (!feof(fid)) {
520 int num;
521 num = fscanf(fid, "tx_power: %d\n", &tx_power);
522 if (num != 1) {
523 ALOGE("%s: Parse tx power failed, num:%d\n", __func__, num);
524 break;
525 }
526
527 memcpy(&tx_power_cal, &tx_power, sizeof(tx_power));
528 ALOGD("%s: tx_power: %d\n", __func__, tx_power);
529 }
530
531 fclose(fid);
532 return 0;
533 }
534
write_tx_power_to_persist(const uint32_t * tx_power)535 static int write_tx_power_to_persist(const uint32_t* tx_power) {
536 FILE *fid;
537
538 if (!tx_power) {
539 ALOGE("%s: Invalid tx power", __func__);
540 fprintf(stdout, "%s: Invalid tx power\n", __func__);
541 return -EINVAL;
542 }
543
544 fid = fopen(TX_CAL_FILE, "w");
545 if (fid == NULL) {
546 ALOGE("Cannot open '%s' (%s)\n", TX_CAL_FILE, strerror(errno));
547 fprintf(stdout, "Cannot open '%s' (%s)\n", TX_CAL_FILE, strerror(errno));
548 return -errno;
549 }
550
551 memcpy(&tx_power_cal, tx_power, sizeof(tx_power_cal));
552 fprintf(fid, "tx_power: %u\n", tx_power_cal);
553 ALOGD("%s: %d\n", __func__, tx_power_cal);
554 fclose(fid);
555 return 0;
556 }
557
main(int argc,char * argv[])558 int main(int argc, char *argv[]) {
559 struct ia_sensor_mgr * smd;
560 char use_case;
561 int driver_param_id = -1;
562 int plugin_param_id = -1;
563 int c;
564 float param_val = 0.0;
565 uint32_t ping_timeout_sec;
566 bool route_enable;
567 uint32_t reg_addr;
568 uint32_t reg_val;
569 bool reg_val_set = false;
570 struct cal_coefficient cal_coef = { .mode = CAL_INVALID_MODE };
571 uint32_t tx_power = 0;
572 int test_mode_param_id = -1;
573 oslo_inject_mode_t inject_mode = INJECT_MODE_OFF;
574
575 if (argc <= 1) {
576 usage();
577 }
578
579 while ((c = getopt_long (argc, argv, "s:v:g:p:r:d:w:c:t:i:e:", long_options, NULL)) != -1) {
580 switch (c) {
581 case 's':
582 if (NULL == optarg) {
583 fprintf(stderr, "Incorrect usage, s option requires an argument");
584 usage();
585 } else {
586 driver_param_id = oslo_driver_setting_lookup(optarg);
587 plugin_param_id = oslo_plugin_setting_lookup(optarg);
588 if (driver_param_id == -1 && plugin_param_id == -1) {
589 fprintf(stderr, "Invalid setting %s", optarg);
590 usage();
591 } else {
592 use_case = 's';
593 }
594 }
595 break;
596 case 'v':
597 if (NULL == optarg) {
598 fprintf(stderr, "Incorrect usage, v option requires an argument");
599 usage();
600 } else {
601 if ('s' == use_case) {
602 param_val = strtof(optarg, NULL);
603 use_case = 'v';
604 } else if ('w' == use_case) {
605 reg_val = strtoul(optarg, NULL, 0);
606 reg_val_set = true;
607 } else if ('t' == use_case) {
608 param_val = strtof(optarg, NULL);
609 use_case = 'v';
610 } else {
611 fprintf(stderr, "Incorrect usage, v option should be the second option");
612 usage();
613 }
614 }
615 break;
616 case 'g':
617 if (NULL == optarg) {
618 fprintf(stderr, "Incorrect usage, g option requires an argument");
619 usage();
620 } else {
621 driver_param_id = oslo_driver_setting_lookup(optarg);
622 plugin_param_id = oslo_plugin_setting_lookup(optarg);
623 if (driver_param_id == -1 && plugin_param_id == -1) {
624 fprintf(stderr, "Invalid setting %s", optarg);
625 usage();
626 } else {
627 use_case = 'g';
628 }
629 }
630 break;
631 case 'p':
632 if (NULL == optarg) {
633 fprintf(stderr, "Incorrect usage, p option requires an argument");
634 usage();
635 } else {
636 ping_timeout_sec = strtoul(optarg, NULL, 0);
637 use_case = 'p';
638 }
639 break;
640 case 'r':
641 if (NULL == optarg) {
642 fprintf(stderr, "Incorrect usage, r option requires an argument");
643 usage();
644 } else {
645 route_enable = (strtoul(optarg, NULL, 0) != 0) ? true : false;
646 use_case = 'r';
647 }
648 break;
649 case 'd':
650 if (NULL == optarg) {
651 fprintf(stderr, "Incorrect usage, d option requires an argument");
652 usage();
653 } else {
654 reg_addr = strtoul(optarg, NULL, 0);
655 use_case = 'd';
656 }
657 break;
658 case 'w':
659 if (NULL == optarg) {
660 fprintf(stderr, "Incorrect usage, w option requires an argument");
661 usage();
662 } else {
663 reg_addr = strtoul(optarg, NULL, 0);
664 use_case = 'w';
665 }
666 break;
667 case 'c':
668 if (NULL == optarg) {
669 fprintf(stderr, "Incorrect usage, c option requires an argument");
670 usage();
671 } else {
672 int num_matched;
673 num_matched = sscanf(optarg, "V:%f M:%d %f %f %f %f %f %f",
674 &cal_coef.version,
675 &cal_coef.mode,
676 &cal_coef.ch1_i_val, &cal_coef.ch1_q_val,
677 &cal_coef.ch2_i_val, &cal_coef.ch2_q_val,
678 &cal_coef.ch3_i_val, &cal_coef.ch3_q_val);
679 if (num_matched == 8) {
680 use_case = 'c';
681 } else {
682 fprintf(stderr, "Incorrect -c arguments %s\n", optarg);
683 usage();
684 }
685 }
686 break;
687 case 'e':
688 if (NULL == optarg) {
689 fprintf(stderr, "Incorrect usage, e option requires an argument");
690 usage();
691 } else {
692 int num_matched;
693 num_matched = sscanf(optarg, "%d", &tx_power);
694 if (num_matched == 1) {
695 use_case = 'e';
696 } else {
697 fprintf(stderr, "Incorrect -e arguments %s \n", optarg);
698 usage();
699 }
700 }
701 break;
702 case 't':
703 if (NULL == optarg) {
704 fprintf(stderr, "Incorrect usage, t option requires an argument");
705 usage();
706 } else {
707 test_mode_param_id = oslo_plugin_test_mode_lookup(optarg);
708 if (test_mode_param_id == -1) {
709 fprintf(stderr, "Invalid setting %s", optarg);
710 usage();
711 } else {
712 use_case = 't';
713 fprintf(stderr, "Executing test mode %s\n", optarg);
714 }
715 }
716 break;
717 case 'i':
718 if (NULL == optarg) {
719 fprintf(stderr, "Incorrect usage, i option requires an argument");
720 usage();
721 } else {
722 inject_mode = strtoul(optarg, NULL, 0);
723 if (inject_mode >= INJECT_MODE_NUM) {
724 fprintf(stderr, "Invalid setting %s", optarg);
725 usage();
726 } else {
727 use_case = 'i';
728 }
729 }
730 break;
731 case GETOPT_HELP_CHAR:
732 default:
733 usage();
734 break;
735 }
736
737 smd = iaxxx_sensor_mgr_init();
738 if (NULL == smd) {
739 ALOGE("%s: ERROR Failed to init ia_sensor_mgr", __func__);
740 return -EINVAL;
741 }
742
743 if ('v' == use_case) {
744 if (driver_param_id != -1) {
745 oslo_driver_set_param(smd, driver_param_id, param_val);
746 } else if (plugin_param_id != -1) {
747 oslo_plugin_set_param(plugin_param_id, param_val);
748 } else if (test_mode_param_id != -1) {
749 uint32_t integer_param = (uint32_t)lrintf(param_val);
750 if (param_val < 0) {
751 ALOGD("%s: Test mode: %d with no event", __func__, test_mode_param_id);
752 integer_param = UINT32_MAX;
753 } else if (param_val > 0) {
754 ALOGD("%s: Test mode: %d with duration: %" PRIu32, __func__, test_mode_param_id, integer_param);
755 } else {
756 ALOGD("%s: Test mode: %d with no duration", __func__, test_mode_param_id);
757 }
758 oslo_plugin_set_param(test_mode_param_id, integer_param);
759 }
760 } else if ('g' == use_case) {
761 if (driver_param_id != -1) {
762 oslo_driver_get_param(smd, driver_param_id);
763 } else if (plugin_param_id != -1) {
764 oslo_plugin_get_param(plugin_param_id);
765 }
766 } else if ('p' == use_case) {
767 ping_test(smd, ping_timeout_sec);
768 } else if ('r' == use_case) {
769 route_enable ? osloSoundModelEnable(true) : oslo_enable(smd, false);
770 } else if ('d' == use_case) {
771 read_register(smd, reg_addr);
772 } else if ('w' == use_case) {
773 if (reg_val_set)
774 write_register(smd, reg_addr, reg_val);
775 } else if ('c' == use_case) {
776 for (int i = 0; i < CAL_MODES_MAX; i++) {
777 cal_table[i].mode = CAL_INVALID_MODE;
778 }
779 cal_read_persist();
780 cal_write_persist(&cal_coef);
781 } else if ('e' == use_case) {
782 read_tx_power_from_persist();
783 write_tx_power_to_persist(&tx_power);
784 } else if ('i' == use_case) {
785 oslo_plugin_set_param(OSLO_SENSOR_PARAM_SLPY_STATE, 0);
786 oslo_driver_set_param(smd, OSLO_CONTROL_INJECT_RADAR_DATA, inject_mode);
787 oslo_plugin_set_param(OSLO_SENSOR_PARAM_SLPY_STATE, inject_mode);
788 }
789
790 iaxxx_sensor_mgr_deinit(smd);
791 }
792
793 return 0;
794 }
795