Commit | Line | Data |
---|---|---|
1716c5cf MB |
1 | /* |
2 | * Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | */ | |
15 | #include "ssp.h" | |
16 | #include <linux/math64.h> | |
17 | #include <linux/sched.h> | |
18 | ||
19 | /* SSP -> AP Instruction */ | |
20 | #define MSG2AP_INST_BYPASS_DATA 0x37 | |
21 | #define MSG2AP_INST_LIBRARY_DATA 0x01 | |
22 | #define MSG2AP_INST_DEBUG_DATA 0x03 | |
23 | #define MSG2AP_INST_BIG_DATA 0x04 | |
24 | #define MSG2AP_INST_META_DATA 0x05 | |
25 | #define MSG2AP_INST_TIME_SYNC 0x06 | |
26 | #define MSG2AP_INST_RESET 0x07 | |
27 | #define MSG2AP_INST_GYRO_CAL 0x08 | |
28 | #define MSG2AP_INST_MAG_CAL 0x09 | |
29 | #define MSG2AP_INST_SENSOR_INIT_DONE 0x0a | |
30 | #define MSG2AP_INST_COLLECT_BIGDATA 0x0b | |
31 | #define MSG2AP_INST_SCONTEXT_DATA 0x0c | |
32 | ||
33 | #define CAL_DATA_FOR_BIG 0x01 | |
34 | ||
35 | #ifdef CONFIG_SENSORS_SSP_HIFI_BATCHING // HIFI batch | |
36 | #define U64_MS2NS 1000000ULL | |
37 | #define U64_US2NS 1000ULL | |
38 | #define U64_MS2US 1000ULL | |
39 | #define MS_IDENTIFIER 1000000000U | |
40 | #endif | |
41 | ||
42 | u64 get_delay(u64 kernel_delay) | |
43 | { | |
44 | u64 ret = kernel_delay; | |
45 | u64 ms_delay = kernel_delay/1000000; | |
46 | ||
47 | if (ms_delay == 200) | |
48 | ret = 180 * 1000000; | |
49 | else if (ms_delay >= 60 && ms_delay < 70) | |
50 | ret = 60 * 1000000; | |
51 | ||
52 | return ret; | |
53 | } | |
54 | ||
55 | /*Compensate timestamp for jitter.*/ | |
56 | u64 get_leveling_timestamp(u64 timestamp, struct ssp_data *data, u64 time_delta, int sensor_type) | |
57 | { | |
58 | u64 ret = timestamp; | |
59 | u64 base_time = get_delay(data->adDelayBuf[sensor_type]); | |
60 | u64 prev_time = data->lastTimestamp[sensor_type]; | |
61 | u64 threshold = base_time + prev_time + ((base_time / 10000) * data->timestamp_factor); | |
62 | u64 level_threshold = base_time + prev_time + ((base_time / 10) * 19); | |
63 | ||
64 | if (data->first_sensor_data[sensor_type] == true) { | |
65 | if (time_delta == 1) { | |
66 | // check first data for base_time | |
67 | //pr_err("[SSP_DEBUG_TIME] sensor_type: %2d first_timestamp: %lld\n", sensor_type, timestamp); | |
68 | data->first_sensor_data[sensor_type] = false; | |
69 | } | |
70 | goto exit_current; | |
71 | } | |
72 | ||
73 | if (threshold < timestamp && level_threshold > timestamp) | |
74 | return timestamp - threshold < 30 * 1000000 ? threshold : timestamp; | |
75 | ||
76 | ||
77 | exit_current: | |
78 | return ret; | |
79 | } | |
80 | ||
81 | static void get_timestamp(struct ssp_data *data, char *pchRcvDataFrame, | |
82 | int *iDataIdx, struct sensor_value *sensorsdata, | |
83 | u16 batch_mode, int sensor_type) | |
84 | { | |
85 | u64 time_delta_ns = 0; | |
86 | u64 update_timestamp = 0; | |
87 | u64 current_timestamp = get_current_timestamp(); | |
88 | ||
89 | memset(&time_delta_ns, 0, 8); | |
90 | memcpy(&time_delta_ns, pchRcvDataFrame + *iDataIdx, 8); | |
91 | ||
92 | update_timestamp = time_delta_ns; | |
93 | ssp_debug_time("[SSP_DEBUG_TIME] sensor_type: %2d update_ts: %lld current_ts: %lld diff: %lld latency: %lld\n", | |
94 | sensor_type, update_timestamp, current_timestamp, | |
95 | update_timestamp - data->lastTimestamp[sensor_type], current_timestamp - update_timestamp); | |
96 | ||
97 | data->lastTimestamp[sensor_type] = time_delta_ns; | |
98 | ||
99 | sensorsdata->timestamp = data->lastTimestamp[sensor_type]; | |
100 | *iDataIdx += 8; | |
101 | } | |
102 | ||
103 | static void get_3axis_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
104 | struct sensor_value *sensorsdata) | |
105 | { | |
106 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 6); | |
107 | *iDataIdx += 6; | |
108 | } | |
109 | ||
110 | static void get_gyro_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
111 | struct sensor_value *sensorsdata) | |
112 | { | |
113 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 12); | |
114 | *iDataIdx += 12; | |
115 | } | |
116 | ||
117 | static void get_uncal_gyro_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
118 | struct sensor_value *sensorsdata) | |
119 | { | |
120 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 24); | |
121 | *iDataIdx += 24; | |
122 | } | |
123 | ||
124 | static void get_geomagnetic_uncaldata(char *pchRcvDataFrame, int *iDataIdx, | |
125 | struct sensor_value *sensorsdata) | |
126 | { | |
127 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, UNCAL_MAGNETIC_SIZE); | |
128 | *iDataIdx += UNCAL_MAGNETIC_SIZE; | |
129 | } | |
130 | ||
131 | static void get_geomagnetic_caldata(char *pchRcvDataFrame, int *iDataIdx, | |
132 | struct sensor_value *sensorsdata) | |
133 | { | |
134 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, MAGNETIC_SIZE); | |
135 | *iDataIdx += MAGNETIC_SIZE; | |
136 | } | |
137 | static void get_geomagnetic_rawdata(char *pchRcvDataFrame, int *iDataIdx, | |
138 | struct sensor_value *sensorsdata) | |
139 | { | |
140 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 6); | |
141 | *iDataIdx += 6; | |
142 | } // this func gather sensor data, but not report to HAL | |
143 | ||
144 | static void get_rot_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
145 | struct sensor_value *sensorsdata) | |
146 | { | |
147 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 17); | |
148 | *iDataIdx += 17; | |
149 | } | |
150 | ||
151 | static void get_step_det_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
152 | struct sensor_value *sensorsdata) | |
153 | { | |
154 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1); | |
155 | *iDataIdx += 1; | |
156 | } | |
157 | ||
158 | static void get_light_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
159 | struct sensor_value *sensorsdata) | |
160 | { | |
161 | #ifdef CONFIG_SENSORS_SSP_LIGHT_REPORT_LUX | |
162 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 18); | |
163 | *iDataIdx += 18; | |
164 | #else | |
165 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 10); | |
166 | *iDataIdx += 10; | |
167 | #endif | |
168 | } | |
169 | ||
170 | #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA | |
171 | static void get_light_ir_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
172 | struct sensor_value *sensorsdata) | |
173 | { | |
174 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 12); | |
175 | *iDataIdx += 12; | |
176 | } | |
177 | #endif | |
178 | ||
179 | static void get_light_flicker_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
180 | struct sensor_value *sensorsdata) | |
181 | { | |
182 | memcpy(&sensorsdata->light_flicker, pchRcvDataFrame + *iDataIdx, 2); | |
183 | *iDataIdx += 2; | |
184 | } | |
185 | #if ANDROID_VERSION >= 80000 | |
186 | static void get_light_cct_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
187 | struct sensor_value *sensorsdata) | |
188 | { | |
189 | #ifdef CONFIG_SENSORS_SSP_LIGHT_REPORT_LUX | |
190 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 18); | |
191 | *iDataIdx += 18; | |
192 | #else | |
193 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 10); | |
194 | *iDataIdx += 10; | |
195 | #endif | |
196 | } | |
197 | #endif | |
198 | static void get_pressure_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
199 | struct sensor_value *sensorsdata) | |
200 | { | |
201 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 6); | |
202 | *iDataIdx += 6; | |
203 | } | |
204 | ||
205 | static void get_gesture_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
206 | struct sensor_value *sensorsdata) | |
207 | { | |
208 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 20); | |
209 | *iDataIdx += 20; | |
210 | } | |
211 | ||
212 | static void get_proximity_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
213 | struct sensor_value *sensorsdata) | |
214 | { | |
215 | #if defined(CONFIG_SENSORS_SSP_TMG399x) | |
216 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 2); | |
217 | *iDataIdx += 2; | |
218 | #else //CONFIG_SENSORS_SSP_TMD4903, CONFIG_SENSORS_SSP_TMD3782, CONFIG_SENSORS_SSP_TMD4904 | |
219 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 3); | |
220 | *iDataIdx += 3; | |
221 | #endif | |
222 | } | |
223 | ||
224 | static void get_proximity_alert_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
225 | struct sensor_value *sensorsdata) | |
226 | { | |
227 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 3); | |
228 | *iDataIdx += 3; | |
229 | } | |
230 | ||
231 | static void get_proximity_rawdata(char *pchRcvDataFrame, int *iDataIdx, | |
232 | struct sensor_value *sensorsdata) | |
233 | { | |
234 | #if defined(CONFIG_SENSORS_SSP_TMG399x) | |
235 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1); | |
236 | *iDataIdx += 1; | |
237 | #else //CONFIG_SENSORS_SSP_TMD4903, CONFIG_SENSORS_SSP_TMD3782, CONFIG_SENSORS_SSP_TMD4904 | |
238 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 2); | |
239 | *iDataIdx += 2; | |
240 | #endif | |
241 | } | |
242 | ||
243 | #ifdef CONFIG_SENSORS_SSP_SX9306 | |
244 | static void get_grip_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
245 | struct sensor_value *sensorsdata) | |
246 | { | |
247 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 9); | |
248 | *iDataIdx += 9; | |
249 | } | |
250 | #endif | |
251 | ||
252 | static void get_temp_humidity_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
253 | struct sensor_value *sensorsdata) | |
254 | { | |
255 | memset(&sensorsdata->data[2], 0, 2); | |
256 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 5); | |
257 | *iDataIdx += 5; | |
258 | } | |
259 | ||
260 | static void get_sig_motion_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
261 | struct sensor_value *sensorsdata) | |
262 | { | |
263 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1); | |
264 | *iDataIdx += 1; | |
265 | } | |
266 | ||
267 | static void get_step_cnt_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
268 | struct sensor_value *sensorsdata) | |
269 | { | |
270 | memcpy(&sensorsdata->step_diff, pchRcvDataFrame + *iDataIdx, 4); | |
271 | *iDataIdx += 4; | |
272 | } | |
273 | ||
274 | static void get_shake_cam_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
275 | struct sensor_value *sensorsdata) | |
276 | { | |
277 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1); | |
278 | *iDataIdx += 1; | |
279 | } | |
280 | ||
281 | static void get_tilt_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
282 | struct sensor_value *sensorsdata) | |
283 | { | |
284 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1); | |
285 | *iDataIdx += 1; | |
286 | } | |
287 | ||
288 | static void get_pickup_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
289 | struct sensor_value *sensorsdata) | |
290 | { | |
291 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 1); | |
292 | *iDataIdx += 1; | |
293 | } | |
294 | #if ANDROID_VERSION >= 80000 | |
295 | static void get_wakeup_motion_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
296 | struct sensor_value *sensorsdata) | |
297 | { | |
298 | memcpy(&sensorsdata->wakeup_event, pchRcvDataFrame + *iDataIdx, 1); | |
299 | *iDataIdx += 1; | |
300 | } | |
301 | static void get_ucal_accel_sensordata(char *pchRcvDataFrame, int *iDataIdx, | |
302 | struct sensor_value *sensorsdata) | |
303 | { | |
304 | memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, 12); | |
305 | *iDataIdx += 12; | |
306 | } | |
307 | #endif | |
308 | #ifdef CONFIG_SENSORS_SSP_HIFI_BATCHING // HIFI batch | |
309 | ||
310 | /* | |
311 | *static void get_sensor_data(char *pchRcvDataFrame, int *iDataIdx, | |
312 | * struct sensor_value *sensorsdata, int data_size) | |
313 | *{ | |
314 | * memcpy(sensorsdata, pchRcvDataFrame + *iDataIdx, data_size); | |
315 | * *iDataIdx += data_size; | |
316 | *} | |
317 | */ | |
318 | ||
319 | ||
320 | bool ssp_check_buffer(struct ssp_data *data) | |
321 | { | |
322 | int idx_data = 0; | |
323 | u8 sensor_type = 0; | |
324 | bool res = true; | |
325 | u64 ts = get_current_timestamp(); | |
326 | ||
327 | pr_err("[SSP_BUF] start check %lld\n", ts); | |
328 | do { | |
329 | sensor_type = data->batch_event.batch_data[idx_data++]; | |
330 | ||
331 | if ((sensor_type != ACCELEROMETER_SENSOR) && | |
332 | (sensor_type != GEOMAGNETIC_UNCALIB_SENSOR) && | |
333 | (sensor_type != PRESSURE_SENSOR) && | |
334 | (sensor_type != GAME_ROTATION_VECTOR) && | |
335 | (sensor_type != PROXIMITY_SENSOR) && | |
336 | (sensor_type != META_SENSOR) | |
337 | #if ANDROID_VERSION >= 80000 | |
338 | && (sensor_type != ACCEL_UNCALIB_SENSOR) | |
339 | #endif | |
340 | ) { | |
341 | pr_err("[SSP]: %s - Mcu data frame1 error %d, idx_data %d\n", __func__, | |
342 | sensor_type, idx_data - 1); | |
343 | res = false; | |
344 | break; | |
345 | } | |
346 | ||
347 | switch (sensor_type) { | |
348 | case ACCELEROMETER_SENSOR: | |
349 | idx_data += 14; | |
350 | break; | |
351 | case GEOMAGNETIC_UNCALIB_SENSOR: | |
352 | #ifdef CONFIG_SSP_SUPPORT_MAGNETIC_OVERFLOW | |
353 | idx_data += 21; | |
354 | #else | |
355 | idx_data += 20; | |
356 | #endif | |
357 | break; | |
358 | #if ANDROID_VERSION >= 80000 | |
359 | case ACCEL_UNCALIB_SENSOR: | |
360 | idx_data += 20; | |
361 | break; | |
362 | #endif | |
363 | case PRESSURE_SENSOR: | |
364 | idx_data += 14; | |
365 | break; | |
366 | case GAME_ROTATION_VECTOR: | |
367 | idx_data += 25; | |
368 | break; | |
369 | case PROXIMITY_SENSOR: | |
370 | idx_data += 11; | |
371 | break; | |
372 | case META_SENSOR: | |
373 | idx_data += 1; | |
374 | break; | |
375 | } | |
376 | ||
377 | if (idx_data > data->batch_event.batch_length) { | |
378 | //stop index over max length | |
379 | pr_info("[SSP_CHK] invalid data1\n"); | |
380 | res = false; | |
381 | break; | |
382 | } | |
383 | ||
384 | // run until max length | |
385 | if (idx_data == data->batch_event.batch_length) { | |
386 | //pr_info("[SSP_CHK] valid data\n"); | |
387 | break; | |
388 | } else if (idx_data + 1 == data->batch_event.batch_length) { | |
389 | //stop if only sensor type exist | |
390 | pr_info("[SSP_CHK] invalid data2\n"); | |
391 | res = false; | |
392 | break; | |
393 | } | |
394 | } while (true); | |
395 | ts = get_current_timestamp(); | |
396 | pr_err("[SSP_BUF] finish check %lld\n", ts); | |
397 | ||
398 | return res; | |
399 | } | |
400 | ||
401 | void ssp_batch_resume_check(struct ssp_data *data) | |
402 | { | |
a4c1a6ba | 403 | #if SSP_DBG |
1716c5cf | 404 | u64 acc_offset = 0, uncal_mag_offset = 0, press_offset = 0, grv_offset = 0, proxi_offset = 0; |
a4c1a6ba | 405 | #endif |
1716c5cf MB |
406 | //if suspend -> wakeup case. calc. FIFO last timestamp |
407 | if (data->bIsResumed) { | |
408 | u8 sensor_type = 0; | |
409 | struct sensor_value sensor_data; | |
410 | u64 delta_time_us = 0; | |
411 | int idx_data = 0; | |
412 | u64 timestamp = get_current_timestamp(); | |
413 | //ssp_dbg("[SSP_BAT] LENGTH = %d, start index = %d ts %lld resume %lld\n", | |
414 | //data->batch_event.batch_length, idx_data, timestamp, data->resumeTimestamp); | |
415 | ||
416 | timestamp = data->resumeTimestamp = data->timestamp; | |
417 | ||
418 | while (idx_data < data->batch_event.batch_length) { | |
419 | sensor_type = data->batch_event.batch_data[idx_data++]; | |
420 | if (sensor_type == META_SENSOR) { | |
421 | sensor_data.meta_data.sensor = data->batch_event.batch_data[idx_data++]; | |
422 | continue; | |
423 | } | |
424 | ||
425 | if ((sensor_type != ACCELEROMETER_SENSOR) && | |
426 | (sensor_type != GEOMAGNETIC_UNCALIB_SENSOR) && | |
427 | (sensor_type != PRESSURE_SENSOR) && | |
428 | (sensor_type != GAME_ROTATION_VECTOR) && | |
429 | (sensor_type != PROXIMITY_SENSOR) | |
430 | #if ANDROID_VERSION >= 80000 | |
431 | && (sensor_type != ACCEL_UNCALIB_SENSOR) | |
432 | #endif | |
433 | ) { | |
434 | pr_err("[SSP]: %s - Mcu data frame1 error %d, idx_data %d\n", __func__, | |
435 | sensor_type, idx_data - 1); | |
436 | data->bIsResumed = false; | |
437 | data->resumeTimestamp = 0ULL; | |
438 | return; | |
439 | } | |
440 | ||
441 | data->get_sensor_data[sensor_type](data->batch_event.batch_data, &idx_data, &sensor_data); | |
442 | ||
443 | memset(&delta_time_us, 0, 8); | |
444 | memcpy(&delta_time_us, data->batch_event.batch_data + idx_data, 8); | |
445 | ||
446 | switch (sensor_type) { | |
447 | case ACCELEROMETER_SENSOR: | |
448 | case GEOMAGNETIC_UNCALIB_SENSOR: | |
449 | case GAME_ROTATION_VECTOR: | |
450 | case PRESSURE_SENSOR: | |
451 | case PROXIMITY_SENSOR: | |
452 | #if ANDROID_VERSION >= 80000 | |
453 | case ACCEL_UNCALIB_SENSOR: | |
454 | #endif | |
455 | data->lastTimestamp[sensor_type] = delta_time_us; | |
456 | break; | |
457 | } | |
458 | idx_data += 8; | |
459 | } | |
460 | ||
461 | ssp_dbg("[SSP_BAT] resume calc. acc %lld. uncalmag %lld. pressure %lld. GRV %lld proxi %lld\n", | |
462 | acc_offset, uncal_mag_offset, press_offset, grv_offset, proxi_offset); | |
463 | } | |
464 | data->bIsResumed = false; | |
465 | data->resumeTimestamp = 0ULL; | |
466 | } | |
467 | ||
468 | void ssp_batch_report(struct ssp_data *data) | |
469 | { | |
470 | u8 sensor_type = 0; | |
471 | struct sensor_value sensor_data; | |
472 | int idx_data = 0; | |
473 | int count = 0; | |
474 | u64 timestamp = get_current_timestamp(); | |
475 | ||
476 | ssp_dbg("[SSP_BAT] LENGTH = %d, start index = %d ts %lld\n", | |
477 | data->batch_event.batch_length, idx_data, timestamp); | |
478 | ||
479 | while (idx_data < data->batch_event.batch_length) { | |
480 | //ssp_dbg("[SSP_BAT] bcnt %d\n", count); | |
481 | sensor_type = data->batch_event.batch_data[idx_data++]; | |
482 | ||
483 | if (sensor_type == META_SENSOR) { | |
484 | sensor_data.meta_data.sensor = data->batch_event.batch_data[idx_data++]; | |
485 | report_meta_data(data, &sensor_data); | |
486 | count++; | |
487 | continue; | |
488 | } | |
489 | ||
490 | if ((sensor_type != ACCELEROMETER_SENSOR) && | |
491 | (sensor_type != GEOMAGNETIC_UNCALIB_SENSOR) && | |
492 | (sensor_type != PRESSURE_SENSOR) && | |
493 | (sensor_type != GAME_ROTATION_VECTOR) && | |
494 | (sensor_type != PROXIMITY_SENSOR) | |
495 | #if ANDROID_VERSION >= 80000 | |
496 | && (sensor_type != ACCEL_UNCALIB_SENSOR) | |
497 | #endif | |
498 | ) { | |
499 | pr_err("[SSP]: %s - Mcu data frame1 error %d, idx_data %d\n", __func__, | |
500 | sensor_type, idx_data - 1); | |
501 | return; | |
502 | } | |
503 | ||
504 | usleep_range(150, 151); | |
505 | //ssp_dbg("[SSP_BAT] cnt %d\n", count); | |
506 | data->get_sensor_data[sensor_type](data->batch_event.batch_data, &idx_data, &sensor_data); | |
507 | ||
508 | get_timestamp(data, data->batch_event.batch_data, &idx_data, &sensor_data, BATCH_MODE_RUN, sensor_type); | |
509 | ssp_debug_time("[SSP_BAT]: sensor %d, AP %lld MCU %lld, diff %lld, count: %d\n", | |
510 | sensor_type, timestamp, sensor_data.timestamp, timestamp - sensor_data.timestamp, count); | |
511 | ||
512 | data->report_sensor_data[sensor_type](data, &sensor_data); | |
513 | data->reportedData[sensor_type] = true; | |
514 | count++; | |
515 | } | |
516 | ssp_dbg("[SSP_BAT] max cnt %d\n", count); | |
517 | } | |
518 | ||
519 | ||
520 | // Control batched data with long term | |
521 | // Ref ssp_read_big_library_task | |
522 | void ssp_batch_data_read_task(struct work_struct *work) | |
523 | { | |
524 | struct ssp_big *big = container_of(work, struct ssp_big, work); | |
525 | struct ssp_data *data = big->data; | |
526 | struct ssp_msg *msg; | |
527 | int buf_len, residue, ret = 0, index = 0, pos = 0; | |
528 | u64 ts = 0; | |
529 | ||
530 | mutex_lock(&data->batch_events_lock); | |
531 | wake_lock(&data->ssp_wake_lock); | |
532 | ||
533 | residue = big->length; | |
534 | data->batch_event.batch_length = big->length; | |
535 | data->batch_event.batch_data = vmalloc(big->length); | |
536 | if (data->batch_event.batch_data == NULL) { | |
537 | ssp_dbg("[SSP_BAT] batch data alloc fail\n"); | |
538 | kfree(big); | |
539 | wake_unlock(&data->ssp_wake_lock); | |
540 | mutex_unlock(&data->batch_events_lock); | |
541 | return; | |
542 | } | |
543 | ||
544 | //ssp_dbg("[SSP_BAT] IN : LENGTH = %d\n", big->length); | |
545 | ||
546 | while (residue > 0) { | |
547 | buf_len = residue > DATA_PACKET_SIZE | |
548 | ? DATA_PACKET_SIZE : residue; | |
549 | ||
550 | msg = kzalloc(sizeof(*msg), GFP_ATOMIC); | |
551 | msg->cmd = MSG2SSP_AP_GET_BIG_DATA; | |
552 | msg->length = buf_len; | |
553 | msg->options = AP2HUB_READ | (index++ << SSP_INDEX); | |
554 | msg->data = big->addr; | |
555 | msg->buffer = data->batch_event.batch_data + pos; | |
556 | msg->free_buffer = 0; | |
557 | ||
558 | ret = ssp_spi_sync(big->data, msg, 1000); | |
559 | if (ret != SUCCESS) { | |
560 | pr_err("[SSP_BAT] read batch data err(%d) ignor\n", ret); | |
561 | vfree(data->batch_event.batch_data); | |
562 | data->batch_event.batch_data = NULL; | |
563 | data->batch_event.batch_length = 0; | |
564 | kfree(big); | |
565 | wake_unlock(&data->ssp_wake_lock); | |
566 | mutex_unlock(&data->batch_events_lock); | |
567 | return; | |
568 | } | |
569 | ||
570 | pos += buf_len; | |
571 | residue -= buf_len; | |
572 | pr_info("[SSP_BAT] read batch data (%5d / %5d)\n", pos, big->length); | |
573 | } | |
574 | ||
575 | // TODO: Do not parse, jut put in to FIFO, and wake_up thread. | |
576 | ||
577 | // READ DATA FROM MCU COMPLETED | |
578 | //Wake up check | |
579 | if (ssp_check_buffer(data)) { | |
580 | ssp_batch_resume_check(data); | |
581 | ||
582 | // PARSE DATA FRAMES, Should run loop | |
583 | ts = get_current_timestamp(); | |
584 | pr_info("[SSP] report start %lld\n", ts); | |
585 | ssp_batch_report(data); | |
586 | ts = get_current_timestamp(); | |
587 | pr_info("[SSP] report finish %lld\n", ts); | |
588 | } | |
589 | ||
590 | vfree(data->batch_event.batch_data); | |
591 | data->batch_event.batch_data = NULL; | |
592 | data->batch_event.batch_length = 0; | |
593 | kfree(big); | |
594 | wake_unlock(&data->ssp_wake_lock); | |
595 | mutex_unlock(&data->batch_events_lock); | |
596 | } | |
597 | #endif | |
598 | int handle_big_data(struct ssp_data *data, char *pchRcvDataFrame, int *pDataIdx) | |
599 | { | |
600 | u8 bigType = 0; | |
601 | struct ssp_big *big = kzalloc(sizeof(*big), GFP_KERNEL); | |
602 | ||
603 | big->data = data; | |
604 | bigType = pchRcvDataFrame[(*pDataIdx)++]; | |
605 | memcpy(&big->length, pchRcvDataFrame + *pDataIdx, 4); | |
606 | *pDataIdx += 4; | |
607 | memcpy(&big->addr, pchRcvDataFrame + *pDataIdx, 4); | |
608 | *pDataIdx += 4; | |
609 | ||
610 | if (bigType >= BIG_TYPE_MAX) { | |
611 | kfree(big); | |
612 | return FAIL; | |
613 | } | |
614 | ||
615 | INIT_WORK(&big->work, data->ssp_big_task[bigType]); | |
616 | #ifdef CONFIG_SENSORS_SSP_HIFI_BATCHING // HIFI batch | |
617 | if (bigType != BIG_TYPE_READ_HIFI_BATCH) | |
618 | queue_work(data->debug_wq, &big->work); | |
619 | else | |
620 | queue_work(data->batch_wq, &big->work); | |
621 | #else | |
622 | queue_work(data->debug_wq, &big->work); | |
623 | #endif | |
624 | return SUCCESS; | |
625 | } | |
626 | ||
627 | void handle_timestamp_sync(struct ssp_data *data, char *pchRcvDataFrame, int *index) | |
628 | { | |
629 | u64 mcu_timestamp; | |
630 | u64 current_timestamp = get_current_timestamp(); | |
631 | ||
632 | memcpy(&mcu_timestamp, pchRcvDataFrame + *index, sizeof(mcu_timestamp)); | |
633 | data->timestamp_offset = current_timestamp - mcu_timestamp; | |
634 | schedule_delayed_work(&data->work_ssp_tiemstamp_sync, msecs_to_jiffies(100)); | |
635 | ||
636 | *index += 8; | |
637 | } | |
638 | ||
639 | ||
640 | /*************************************************************************/ | |
641 | /* SSP parsing the dataframe */ | |
642 | /*************************************************************************/ | |
643 | int parse_dataframe(struct ssp_data *data, char *pchRcvDataFrame, int iLength) | |
644 | { | |
645 | int iDataIdx; | |
646 | int sensor_type; | |
647 | u16 length = 0; | |
648 | ||
649 | struct sensor_value sensorsdata; | |
650 | s32 caldata[3] = { 0, }; | |
651 | char msg_inst = 0; | |
652 | u64 timestampforReset; | |
653 | ||
654 | data->uIrqCnt++; | |
655 | ||
656 | for (iDataIdx = 0; iDataIdx < iLength;) { | |
657 | switch (msg_inst = pchRcvDataFrame[iDataIdx++]) { | |
658 | case MSG2AP_INST_TIMESTAMP_OFFSET: | |
659 | handle_timestamp_sync(data, pchRcvDataFrame, &iDataIdx); | |
660 | break; | |
661 | ||
662 | case MSG2AP_INST_SENSOR_INIT_DONE: | |
663 | pr_err("[SSP]: MCU sensor init done\n"); | |
664 | complete(&data->hub_data->mcu_init_done); | |
665 | break; | |
666 | // HIFI batch | |
667 | case MSG2AP_INST_BYPASS_DATA: | |
668 | sensor_type = pchRcvDataFrame[iDataIdx++]; | |
669 | if ((sensor_type < 0) || (sensor_type >= SENSOR_MAX)) { | |
670 | pr_err("[SSP]: %s - Mcu data frame1 error %d\n", __func__, | |
671 | sensor_type); | |
672 | return ERROR; | |
673 | } | |
674 | ||
675 | timestampforReset = get_current_timestamp(); | |
676 | data->LastSensorTimeforReset[sensor_type] = timestampforReset; | |
677 | ||
678 | if (data->get_sensor_data[sensor_type] == NULL) | |
679 | goto error_return; | |
680 | ||
681 | data->get_sensor_data[sensor_type](pchRcvDataFrame, &iDataIdx, &sensorsdata); | |
682 | data->skipEventReport = false; | |
683 | ||
684 | get_timestamp(data, pchRcvDataFrame, &iDataIdx, &sensorsdata, 0, sensor_type); | |
685 | if (data->skipEventReport == false) { | |
686 | //Check sensor is enabled, before report sensordata | |
687 | u64 AddedSensorState = (u64)atomic64_read(&data->aSensorEnable); | |
688 | ||
689 | if (AddedSensorState & (1ULL << sensor_type) | |
690 | || sensor_type == GEOMAGNETIC_RAW | |
691 | || sensor_type == PROXIMITY_RAW) | |
692 | data->report_sensor_data[sensor_type](data, &sensorsdata); | |
693 | else { | |
694 | if (data->skipSensorData == 30) { | |
695 | pr_info("[SSP]: sensor not added,but sensor(%d) came", sensor_type); | |
696 | data->skipSensorData = 0; | |
697 | } | |
698 | data->skipSensorData++; | |
699 | } | |
700 | } | |
701 | ||
702 | data->reportedData[sensor_type] = true; | |
703 | //pr_err("[SSP]: (%d / %d)\n", iDataIdx, iLength); | |
704 | break; | |
705 | case MSG2AP_INST_DEBUG_DATA: | |
706 | sensor_type = print_mcu_debug(pchRcvDataFrame, &iDataIdx, iLength); | |
707 | if (sensor_type) { | |
708 | pr_err("[SSP]: %s - Mcu data frame3 error %d\n", __func__, | |
709 | sensor_type); | |
710 | return ERROR; | |
711 | } | |
712 | break; | |
713 | case MSG2AP_INST_LIBRARY_DATA: | |
714 | memcpy(&length, pchRcvDataFrame + iDataIdx, 2); | |
715 | iDataIdx += 2; | |
716 | ssp_sensorhub_handle_data(data, pchRcvDataFrame, iDataIdx, | |
717 | iDataIdx + length); | |
718 | iDataIdx += length; | |
719 | break; | |
720 | case MSG2AP_INST_BIG_DATA: | |
721 | handle_big_data(data, pchRcvDataFrame, &iDataIdx); | |
722 | break; | |
723 | case MSG2AP_INST_META_DATA: | |
724 | sensorsdata.meta_data.what = pchRcvDataFrame[iDataIdx++]; | |
725 | sensorsdata.meta_data.sensor = pchRcvDataFrame[iDataIdx++]; | |
726 | ||
727 | if (sensorsdata.meta_data.what != 1) | |
728 | goto error_return; | |
729 | ||
730 | if ((sensorsdata.meta_data.sensor < 0) || (sensorsdata.meta_data.sensor >= SENSOR_MAX)) { | |
731 | pr_err("[SSP]: %s - Mcu meta_data frame1 error %d\n", __func__, | |
732 | sensorsdata.meta_data.sensor); | |
733 | return ERROR; | |
734 | } | |
735 | report_meta_data(data, &sensorsdata); | |
736 | break; | |
737 | case MSG2AP_INST_TIME_SYNC: | |
738 | data->bTimeSyncing = true; | |
739 | break; | |
740 | case MSG2AP_INST_GYRO_CAL: | |
741 | pr_info("[SSP]: %s - Gyro caldata received from MCU\n", __func__); | |
742 | memcpy(caldata, pchRcvDataFrame + iDataIdx, sizeof(caldata)); | |
743 | wake_lock(&data->ssp_wake_lock); | |
744 | save_gyro_caldata(data, caldata); | |
745 | wake_unlock(&data->ssp_wake_lock); | |
746 | iDataIdx += sizeof(caldata); | |
747 | break; | |
748 | case MSG2AP_INST_MAG_CAL: | |
749 | wake_lock(&data->ssp_wake_lock); | |
750 | save_magnetic_cal_param_to_nvm(data, pchRcvDataFrame, &iDataIdx); | |
751 | wake_unlock(&data->ssp_wake_lock); | |
752 | break; | |
753 | case MSG2AP_INST_COLLECT_BIGDATA: | |
754 | switch (pchRcvDataFrame[iDataIdx++]) { | |
755 | case CAL_DATA_FOR_BIG: | |
756 | sensor_type = pchRcvDataFrame[iDataIdx++]; | |
757 | if (sensor_type == ACCELEROMETER_SENSOR) | |
758 | set_AccelCalibrationInfoData(pchRcvDataFrame, &iDataIdx); | |
759 | else if (sensor_type == GYROSCOPE_SENSOR) | |
760 | set_GyroCalibrationInfoData(pchRcvDataFrame, &iDataIdx); | |
761 | break; | |
762 | default: | |
763 | pr_info("[SSP] wrong sub inst for big data\n"); | |
764 | break; | |
765 | } | |
766 | break; | |
767 | #if ANDROID_VERSION >= 80000 | |
768 | case MSG2AP_INST_SCONTEXT_DATA: | |
769 | memcpy(sensorsdata.scontext_buf, pchRcvDataFrame + iDataIdx, SCONTEXT_DATA_SIZE); | |
770 | report_scontext_data(data, &sensorsdata); | |
771 | iDataIdx += SCONTEXT_DATA_SIZE; | |
772 | break; | |
773 | #endif | |
774 | default: | |
775 | goto error_return; | |
776 | } | |
777 | } | |
778 | if (data->pktErrCnt >= 1) // if input error packet doesn't comes continually, do not reset | |
779 | data->pktErrCnt = 0; | |
780 | return SUCCESS; | |
781 | error_return: | |
782 | pr_err("[SSP] %s err Inst 0x%02x\n", __func__, msg_inst); | |
783 | data->pktErrCnt++; | |
784 | if (data->pktErrCnt >= 2) { | |
785 | pr_err("[SSP] %s packet is polluted\n", __func__); | |
786 | data->mcuAbnormal = true; | |
787 | data->pktErrCnt = 0; | |
788 | data->errorCount++; | |
789 | } | |
790 | return ERROR; | |
791 | } | |
792 | ||
793 | void initialize_function_pointer(struct ssp_data *data) | |
794 | { | |
795 | data->get_sensor_data[ACCELEROMETER_SENSOR] = get_3axis_sensordata; | |
796 | data->get_sensor_data[GYROSCOPE_SENSOR] = get_gyro_sensordata; | |
797 | data->get_sensor_data[GEOMAGNETIC_UNCALIB_SENSOR] = | |
798 | get_geomagnetic_uncaldata; | |
799 | data->get_sensor_data[GEOMAGNETIC_RAW] = get_geomagnetic_rawdata; | |
800 | data->get_sensor_data[GEOMAGNETIC_SENSOR] = | |
801 | get_geomagnetic_caldata; | |
802 | data->get_sensor_data[PRESSURE_SENSOR] = get_pressure_sensordata; | |
803 | data->get_sensor_data[GESTURE_SENSOR] = get_gesture_sensordata; | |
804 | data->get_sensor_data[PROXIMITY_SENSOR] = get_proximity_sensordata; | |
805 | data->get_sensor_data[PROXIMITY_ALERT_SENSOR] = get_proximity_alert_sensordata; | |
806 | data->get_sensor_data[LIGHT_FLICKER_SENSOR] = get_light_flicker_sensordata; | |
807 | ||
808 | data->get_sensor_data[PROXIMITY_RAW] = get_proximity_rawdata; | |
809 | #ifdef CONFIG_SENSORS_SSP_SX9306 | |
810 | data->get_sensor_data[GRIP_SENSOR] = get_grip_sensordata; | |
811 | #endif | |
812 | data->get_sensor_data[LIGHT_SENSOR] = get_light_sensordata; | |
813 | #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA | |
814 | data->get_sensor_data[LIGHT_IR_SENSOR] = get_light_ir_sensordata; | |
815 | #endif | |
816 | #if ANDROID_VERSION >= 80000 | |
817 | data->get_sensor_data[LIGHT_CCT_SENSOR] = get_light_cct_sensordata; | |
818 | data->get_sensor_data[ACCEL_UNCALIB_SENSOR] = get_ucal_accel_sensordata; | |
819 | #endif | |
820 | data->get_sensor_data[TEMPERATURE_HUMIDITY_SENSOR] = | |
821 | get_temp_humidity_sensordata; | |
822 | data->get_sensor_data[ROTATION_VECTOR] = get_rot_sensordata; | |
823 | data->get_sensor_data[GAME_ROTATION_VECTOR] = get_rot_sensordata; | |
824 | data->get_sensor_data[STEP_DETECTOR] = get_step_det_sensordata; | |
825 | data->get_sensor_data[SIG_MOTION_SENSOR] = get_sig_motion_sensordata; | |
826 | data->get_sensor_data[GYRO_UNCALIB_SENSOR] = get_uncal_gyro_sensordata; | |
827 | data->get_sensor_data[STEP_COUNTER] = get_step_cnt_sensordata; | |
828 | data->get_sensor_data[SHAKE_CAM] = get_shake_cam_sensordata; | |
829 | #ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR | |
830 | data->get_sensor_data[INTERRUPT_GYRO_SENSOR] = get_gyro_sensordata; | |
831 | #endif | |
832 | data->get_sensor_data[TILT_DETECTOR] = get_tilt_sensordata; | |
833 | data->get_sensor_data[PICKUP_GESTURE] = get_pickup_sensordata; | |
834 | ||
835 | data->get_sensor_data[WAKE_UP_MOTION] = get_wakeup_motion_sensordata; | |
836 | data->get_sensor_data[BULK_SENSOR] = NULL; | |
837 | data->get_sensor_data[GPS_SENSOR] = NULL; | |
838 | ||
839 | data->report_sensor_data[ACCELEROMETER_SENSOR] = report_acc_data; | |
840 | data->report_sensor_data[GYROSCOPE_SENSOR] = report_gyro_data; | |
841 | data->report_sensor_data[GEOMAGNETIC_UNCALIB_SENSOR] = | |
842 | report_mag_uncaldata; | |
843 | data->report_sensor_data[GEOMAGNETIC_RAW] = report_geomagnetic_raw_data; | |
844 | data->report_sensor_data[GEOMAGNETIC_SENSOR] = | |
845 | report_mag_data; | |
846 | data->report_sensor_data[PRESSURE_SENSOR] = report_pressure_data; | |
847 | data->report_sensor_data[GESTURE_SENSOR] = report_gesture_data; | |
848 | data->report_sensor_data[PROXIMITY_SENSOR] = report_prox_data; | |
849 | data->report_sensor_data[PROXIMITY_ALERT_SENSOR] = report_prox_alert_data; | |
850 | data->report_sensor_data[LIGHT_FLICKER_SENSOR] = report_light_flicker_data; | |
851 | ||
852 | data->report_sensor_data[PROXIMITY_RAW] = report_prox_raw_data; | |
853 | #ifdef CONFIG_SENSORS_SSP_SX9306 | |
854 | data->report_sensor_data[GRIP_SENSOR] = report_grip_data; | |
855 | #endif | |
856 | data->report_sensor_data[LIGHT_SENSOR] = report_light_data; | |
857 | #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA | |
858 | data->report_sensor_data[LIGHT_IR_SENSOR] = report_light_ir_data; | |
859 | #endif | |
860 | data->report_sensor_data[TEMPERATURE_HUMIDITY_SENSOR] = | |
861 | report_temp_humidity_data; | |
862 | data->report_sensor_data[ROTATION_VECTOR] = report_rot_data; | |
863 | data->report_sensor_data[GAME_ROTATION_VECTOR] = report_game_rot_data; | |
864 | data->report_sensor_data[STEP_DETECTOR] = report_step_det_data; | |
865 | data->report_sensor_data[SIG_MOTION_SENSOR] = report_sig_motion_data; | |
866 | data->report_sensor_data[GYRO_UNCALIB_SENSOR] = report_uncalib_gyro_data; | |
867 | data->report_sensor_data[STEP_COUNTER] = report_step_cnt_data; | |
868 | data->report_sensor_data[SHAKE_CAM] = report_shake_cam_data; | |
869 | #ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR | |
870 | data->report_sensor_data[INTERRUPT_GYRO_SENSOR] = report_interrupt_gyro_data; | |
871 | #endif | |
872 | data->report_sensor_data[TILT_DETECTOR] = report_tilt_data; | |
873 | data->report_sensor_data[PICKUP_GESTURE] = report_pickup_data; | |
874 | ||
875 | data->report_sensor_data[BULK_SENSOR] = NULL; | |
876 | data->report_sensor_data[GPS_SENSOR] = NULL; | |
877 | #if ANDROID_VERSION >= 80000 | |
878 | data->report_sensor_data[LIGHT_CCT_SENSOR] = report_light_cct_data; | |
879 | data->report_sensor_data[ACCEL_UNCALIB_SENSOR] = report_uncalib_accel_data; | |
880 | data->report_sensor_data[WAKE_UP_MOTION] = report_wakeup_motion_data; | |
881 | #endif | |
882 | data->ssp_big_task[BIG_TYPE_DUMP] = ssp_dump_task; | |
883 | data->ssp_big_task[BIG_TYPE_READ_LIB] = ssp_read_big_library_task; | |
884 | #ifdef CONFIG_SENSORS_SSP_HIFI_BATCHING // HIFI batch | |
885 | data->ssp_big_task[BIG_TYPE_READ_HIFI_BATCH] = ssp_batch_data_read_task; | |
886 | #endif | |
887 | data->ssp_big_task[BIG_TYPE_VOICE_NET] = ssp_send_big_library_task; | |
888 | data->ssp_big_task[BIG_TYPE_VOICE_GRAM] = ssp_send_big_library_task; | |
889 | data->ssp_big_task[BIG_TYPE_VOICE_PCM] = ssp_pcm_dump_task; | |
890 | data->ssp_big_task[BIG_TYPE_TEMP] = ssp_temp_task; | |
891 | } |