OSDN Git Service

Move module path to vendor
[android-x86/hardware-intel-libsensors.git] / description.c
1 /*
2  * Copyright (C) 2014-2015 Intel Corporation.
3  */
4
5 #include <stdlib.h>
6 #include <ctype.h>
7 #include <utils/Log.h>
8 #include <cutils/properties.h>
9 #include <hardware/sensors.h>
10 #include "common.h"
11 #include "enumeration.h"
12 #include "description.h"
13 #include "utils.h"
14 #include "transform.h"
15
16 #define IIO_SENSOR_HAL_VERSION  1
17
18 #define MIN_ON_CHANGE_SAMPLING_PERIOD_US   200000 /* For on change sensors (temperature, proximity, ALS, etc.) report we support 5 Hz max (0.2 s min period) */
19 #define MAX_ON_CHANGE_SAMPLING_PERIOD_US 10000000 /* 0.1 Hz min (10 s max period)*/
20 #define ANDROID_MAX_FREQ 1000 /* 1000 Hz - This is how much Android requests for the fastest frequency */
21
22 /*
23  * About properties
24  *
25  * We acquire a number of parameters about sensors by reading properties.
26  * The idea here is that someone (either a script, or daemon, sets them
27  * depending on the set of sensors present on the machine.
28  *
29  * There are fallback paths in case the properties are not defined, but it is
30  * highly desirable to at least have the following for each sensor:
31  *
32  * ro.iio.anglvel.name = Gyroscope
33  * ro.iio.anglvel.vendor = Intel
34  * ro.iio.anglvel.max_range = 35
35  * ro.iio.anglvel.resolution = 0.002
36  * ro.iio.anglvel.power = 6.1
37  *
38  * Besides these, we have a couple of knobs initially used to cope with Intel
39  * Sensor Hub oddities, such as HID inspired units or firmware bugs:
40  *
41  * ro.iio.anglvel.transform = ISH
42  * ro.iio.anglvel.quirks = init-rate
43  *
44  * The "terse" quirk indicates that the underlying driver only sends events
45  * when the sensor reports a change. The HAL then periodically generates
46  * duplicate events so the sensor behaves as a continously firing one.
47  *
48  * The "noisy" quirk indicates that the underlying driver has a unusually high
49  * level of noise in its readings, and that the HAL has to accomodate it
50  * somehow, e.g. in the magnetometer calibration code path.
51  *
52  * This one is used specifically to pass a calibration scale to ALS drivers:
53  *
54  * ro.iio.illuminance.name = CPLM3218x Ambient Light Sensor
55  * ro.iio.illuminance.vendor = Capella Microsystems
56  * ro.iio.illuminance.max_range = 167000
57  * ro.iio.illuminance.resolution = 1
58  * ro.iio.illuminance.power = .001
59  * ro.iio.illuminance.illumincalib = 7400
60  *
61  * There's a 'opt_scale' specifier, documented as follows:
62  *
63  *  This adds support for a scaling factor that can be expressed
64  *  using properties, for all sensors, on a channel basis. That
65  *  scaling factor is applied after all other transforms have been
66  *  applied, and is intended as a way to compensate for problems
67  *  such as an incorrect axis polarity for a given sensor.
68  *
69  *  The syntax is <usual property prefix>.<channel>.opt_scale, e.g.
70  *  ro.iio.accel.y.opt_scale = -1 to negate the sign of the y readings
71  *  for the accelerometer.
72  *
73  *  For sensors using a single channel - and only those - the channel
74  *  name is implicitly void and a syntax such as ro.iio.illuminance.
75  *  opt_scale = 3 has to be used.
76  *
77  * 'panel' and 'rotation' specifiers can be used to express ACPI PLD placement
78  * information ; if found they will be used in priority over the actual ACPI
79  * data. That is intended as a way to verify values during development.
80  *
81  * It's possible to use the contents of the iio device name as a way to
82  * discriminate between sensors. Several sensors of the same type can coexist:
83  * e.g. ro.iio.temp.bmg160.name = BMG160 Thermometer will be used in priority
84  * over ro.iio.temp.name = BMC150 Thermometer if the sensor for which we query
85  * properties values happen to have its iio device name set to bmg160.
86  */
87
88 int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE])
89 {
90         char prop_name[PROP_NAME_MAX];
91         char prop_val[PROP_VALUE_MAX];
92         char extended_sel[PROP_VALUE_MAX];
93
94         int i                   = sensor[s].catalog_index;
95         const char *prefix      = sensor_catalog[i].tag;
96         const char *shorthand = sensor_catalog[i].shorthand;
97
98         /* First try most specialized form, like ro.iio.anglvel.bmg160.name */
99
100         snprintf(extended_sel, PROP_NAME_MAX, "%s.%s",
101                  sensor[s].internal_name, sel);
102
103         snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, prefix, extended_sel);
104
105         if (property_get(prop_name, prop_val, "")) {
106                 strncpy(val, prop_val, MAX_NAME_SIZE-1);
107                 val[MAX_NAME_SIZE-1] = '\0';
108                 return 0;
109         }
110
111         if (shorthand[0] != '\0') {
112                 /* Try with shorthand instead of prefix */
113                 snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, shorthand, extended_sel);
114
115                 if (property_get(prop_name, prop_val, "")) {
116                         strncpy(val, prop_val, MAX_NAME_SIZE-1);
117                         val[MAX_NAME_SIZE-1] = '\0';
118                         return 0;
119                 }
120         }
121         /* Fall back to simple form, like ro.iio.anglvel.name */
122
123         snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, prefix, sel);
124
125         if (property_get(prop_name, prop_val, "")) {
126                 strncpy(val, prop_val, MAX_NAME_SIZE-1);
127                 val[MAX_NAME_SIZE-1] = '\0';
128                 return 0;
129         }
130
131         return -1;
132 }
133
134
135 int sensor_get_prop (int s, const char* sel, int* val)
136 {
137         char buf[MAX_NAME_SIZE];
138
139         if (sensor_get_st_prop(s, sel, buf))
140                 return -1;
141
142         *val = atoi(buf);
143         return 0;
144 }
145
146
147 int sensor_get_fl_prop (int s, const char* sel, float* val)
148 {
149         char buf[MAX_NAME_SIZE];
150
151         if (sensor_get_st_prop(s, sel, buf))
152                 return -1;
153
154         *val = (float) strtod(buf, NULL);
155         return 0;
156 }
157
158
159 char* sensor_get_name (int s)
160 {
161         char buf[MAX_NAME_SIZE];
162
163         if (sensor[s].is_virtual) {
164                 switch (sensor[s].type) {
165                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
166                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
167                                 strcpy(buf, sensor[sensor[s].base[0]].friendly_name);
168                                 snprintf(sensor[s].friendly_name,
169                                          MAX_NAME_SIZE,
170                                          "%s %s", "Uncalibrated", buf);
171                                 return sensor[s].friendly_name;
172
173                         default:
174                                 return "";
175                 }
176         }
177
178         if (sensor[s].friendly_name[0] != '\0' ||
179                 !sensor_get_st_prop(s, "name", sensor[s].friendly_name))
180                         return sensor[s].friendly_name;
181
182         /* If we got a iio device name from sysfs, use it */
183         if (sensor[s].internal_name[0]) {
184                 snprintf(sensor[s].friendly_name, MAX_NAME_SIZE, "S%d-%s",
185                          s, sensor[s].internal_name);
186         } else {
187                 sprintf(sensor[s].friendly_name, "S%d", s);
188         }
189
190         return sensor[s].friendly_name;
191 }
192
193
194 char* sensor_get_vendor (int s)
195 {
196         if (sensor[s].is_virtual) {
197                 switch (sensor[s].type) {
198                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
199                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
200                                 return sensor[sensor[s].base[0]].vendor_name;
201                         break;
202
203                         default:
204                                 return "";
205
206                 }
207         }
208
209         if (sensor[s].vendor_name[0] ||
210                 !sensor_get_st_prop(s, "vendor", sensor[s].vendor_name))
211                         return sensor[s].vendor_name;
212
213         return "";
214 }
215
216
217 int sensor_get_version (__attribute__((unused)) int s)
218 {
219         return IIO_SENSOR_HAL_VERSION;
220 }
221
222 void sensor_update_max_range(int s)
223 {
224         if (sensor[s].max_range)
225                 return;
226
227         if (sensor[s].num_channels && sensor[s].channel[0].type_info.realbits) {
228                 switch (sensor[s].type) {
229                 case SENSOR_TYPE_MAGNETIC_FIELD:
230                         sensor[s].max_range = (1ULL << sensor[s].channel[0].type_info.realbits) *
231                                         CONVERT_MICROTESLA_TO_GAUSS(sensor[s].resolution) +
232                                         (sensor[s].offset || sensor[s].channel[0].offset);
233                         sensor[s].max_range = CONVERT_GAUSS_TO_MICROTESLA(sensor[s].max_range);
234                         break;
235                 case SENSOR_TYPE_PROXIMITY:
236                         break;
237                 default:
238                         sensor[s].max_range =  (1ULL << sensor[s].channel[0].type_info.realbits) *
239                                 sensor[s].resolution + (sensor[s].offset || sensor[s].channel[0].offset);
240                         break;
241                 }
242         }
243
244         if (!sensor[s].max_range) {
245                 /* Try returning a sensible value given the sensor type */
246                 /* We should cap returned samples accordingly... */
247                 switch (sensor[s].type) {
248                 case SENSOR_TYPE_ACCELEROMETER:         /* m/s^2        */
249                         sensor[s].max_range = 50;
250                         break;
251                 case SENSOR_TYPE_MAGNETIC_FIELD:        /* micro-tesla  */
252                         sensor[s].max_range = 500;
253                         break;
254                 case SENSOR_TYPE_ORIENTATION:           /* degrees      */
255                         sensor[s].max_range = 360;
256                         break;
257                 case SENSOR_TYPE_GYROSCOPE:             /* radians/s    */
258                         sensor[s].max_range = 10;
259                         break;
260                 case SENSOR_TYPE_LIGHT:                 /* SI lux units */
261                         sensor[s].max_range = 50000;
262                         break;
263                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:   /* Â°C          */
264                 case SENSOR_TYPE_TEMPERATURE:           /* Â°C          */
265                 case SENSOR_TYPE_PROXIMITY:             /* centimeters  */
266                 case SENSOR_TYPE_PRESSURE:              /* hecto-pascal */
267                 case SENSOR_TYPE_RELATIVE_HUMIDITY:     /* percent */
268                         sensor[s].max_range = 100;
269                         break;
270                 }
271         }
272
273         if (sensor[s].max_range)
274                 sensor_desc[s].maxRange = sensor[s].max_range;
275 }
276
277 float sensor_get_max_range (int s)
278 {
279         if (sensor[s].is_virtual) {
280                 switch (sensor[s].type) {
281                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
282                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
283                                 return sensor[sensor[s].base[0]].max_range;
284
285                         default:
286                                 return 0.0;
287                 }
288         }
289
290         if (sensor[s].max_range != 0.0 ||
291                 !sensor_get_fl_prop(s, "max_range", &sensor[s].max_range))
292                         return sensor[s].max_range;
293
294         return 0;
295 }
296
297 static float sensor_get_min_freq (int s)
298 {
299         /*
300          * Check if a low cap has been specified for this sensor sampling rate.
301          * In some case, even when the driver supports lower rate, we still
302          * wish to receive a certain number of samples per seconds for various
303          * reasons (calibration, filtering, no change in power consumption...).
304          */
305
306         float min_freq;
307
308         if (!sensor_get_fl_prop(s, "min_freq", &min_freq))
309                 return min_freq;
310
311         return 0;
312 }
313
314
315 float sensor_get_max_freq (int s)
316 {
317         float max_freq;
318
319         if (!sensor_get_fl_prop(s, "max_freq", &max_freq))
320                 return max_freq;
321
322         return ANDROID_MAX_FREQ;
323 }
324
325 int sensor_get_cal_steps (int s)
326 {
327         int cal_steps;
328         if (!sensor_get_prop(s, "cal_steps", &cal_steps))
329                 return cal_steps;
330
331         return 0;
332 }
333
334 float sensor_get_resolution (int s)
335 {
336         if (sensor[s].is_virtual) {
337                 switch (sensor[s].type) {
338                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
339                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
340                                 return sensor[sensor[s].base[0]].resolution;
341
342                         default:
343                                 return 0;
344                 }
345         }
346
347         if (sensor[s].resolution != 0.0 ||
348             !sensor_get_fl_prop(s, "resolution", &sensor[s].resolution)) {
349                 return sensor[s].resolution;
350         }
351
352         sensor[s].resolution = sensor[s].scale;
353         if (!sensor[s].resolution && sensor[s].num_channels)
354                 sensor[s].resolution = sensor[s].channel[0].scale;
355
356         if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
357                 sensor[s].resolution = CONVERT_GAUSS_TO_MICROTESLA(sensor[s].resolution);
358
359         return sensor[s].resolution ? : 1;
360 }
361
362
363 float sensor_get_power (int s)
364 {
365
366         if (sensor[s].is_virtual) {
367                 switch (sensor[s].type) {
368                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
369                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
370                                 return sensor[sensor[s].base[0]].power;
371
372                         default:
373                                 return 0;
374                 }
375         }
376
377         /* mA used while sensor is in use ; not sure about volts :) */
378         if (sensor[s].power != 0.0 ||
379                 !sensor_get_fl_prop(s, "power", &sensor[s].power))
380                         return sensor[s].power;
381
382         return 0;
383 }
384
385
386 float sensor_get_illumincalib (int s)
387 {
388         /* calibrating the ALS Sensor*/
389         if (sensor[s].illumincalib != 0.0 ||
390                 !sensor_get_fl_prop(s, "illumincalib", &sensor[s].illumincalib)) {
391                         return sensor[s].illumincalib;
392         }
393
394         return 0;
395 }
396
397
398 uint32_t sensor_get_quirks (int s)
399 {
400         char quirks_buf[MAX_NAME_SIZE];
401
402         /* Read and decode quirks property on first reference */
403         if (!(sensor[s].quirks & QUIRK_ALREADY_DECODED)) {
404                 quirks_buf[0] = '\0';
405                 sensor_get_st_prop(s, "quirks", quirks_buf);
406
407                 if (strstr(quirks_buf, "init-rate"))
408                         sensor[s].quirks |= QUIRK_INITIAL_RATE;
409
410                 if (strstr(quirks_buf, "continuous"))
411                         sensor[s].quirks |= QUIRK_FORCE_CONTINUOUS;
412
413                 if (strstr(quirks_buf, "terse"))
414                         sensor[s].quirks |= QUIRK_TERSE_DRIVER;
415
416                 if (strstr(quirks_buf, "noisy"))
417                         sensor[s].quirks |= QUIRK_NOISY;
418
419                 if (strstr(quirks_buf, "biased"))
420                         sensor[s].quirks |= QUIRK_BIASED;
421
422                 if (strstr(quirks_buf, "spotty"))
423                         sensor[s].quirks |= QUIRK_SPOTTY;
424
425                 if (strstr(quirks_buf, "no-event"))
426                         sensor[s].quirks |= QUIRK_NO_EVENT_MODE;
427
428                 if (strstr(quirks_buf, "no-trig"))
429                         sensor[s].quirks |= QUIRK_NO_TRIG_MODE;
430
431                 if (strstr(quirks_buf, "no-poll"))
432                         sensor[s].quirks |= QUIRK_NO_POLL_MODE;
433
434                 if (strstr(quirks_buf, "hrtimer"))
435                         sensor[s].quirks |= QUIRK_HRTIMER;
436
437                 if (strstr(quirks_buf, "secondary"))
438                         sensor[s].quirks |= QUIRK_SECONDARY;
439
440                 sensor[s].quirks |= QUIRK_ALREADY_DECODED;
441         }
442
443         return sensor[s].quirks;
444 }
445
446
447 int sensor_get_order (int s, unsigned char map[MAX_CHANNELS])
448 {
449         char buf[MAX_NAME_SIZE];
450         int i;
451         int count = sensor_catalog[sensor[s].catalog_index].num_channels;
452
453         if (sensor_get_st_prop(s, "order", buf))
454                 return 0; /* No order property */
455
456         /* Assume ASCII characters, in the '0'..'9' range */
457
458         for (i=0; i<count; i++)
459                 if (buf[i] - '0' >= count) {
460                         ALOGE("Order index out of range for sensor %d\n", s);
461                         return 0;
462                 }
463
464         for (i=0; i<count; i++)
465                 map[i] = buf[i] - '0';
466
467         return 1;       /* OK to use modified ordering map */
468 }
469
470 int sensor_get_available_frequencies (int s)
471 {
472         int dev_num = sensor[s].dev_num, err, i;
473         char avail_sysfs_path[PATH_MAX], freqs_buf[100];
474         char *p, *end;
475         float f;
476
477         sensor[s].avail_freqs_count = 0;
478         sensor[s].avail_freqs = 0;
479
480         sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num);
481
482         err = sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf));
483         if (err < 0)
484                 return 0;
485
486         for (p = freqs_buf, f = strtof(p, &end); p != end; p = end, f = strtof(p, &end))
487                 sensor[s].avail_freqs_count++;
488
489         if (sensor[s].avail_freqs_count) {
490                 sensor[s].avail_freqs = (float*) calloc(sensor[s].avail_freqs_count, sizeof(float));
491
492                 for (p = freqs_buf, f = strtof(p, &end), i = 0; p != end; p = end, f = strtof(p, &end), i++)
493                         sensor[s].avail_freqs[i] = f;
494         }
495
496         return 0;
497 }
498
499 int sensor_get_mounting_matrix (int s, float mm[9])
500 {
501         int dev_num = sensor[s].dev_num, err, i;
502         char mm_path[PATH_MAX], mm_buf[100];
503         char *tmp1 = mm_buf, *tmp2;
504
505         switch (sensor[s].type) {
506                 case SENSOR_TYPE_ACCELEROMETER:
507                 case SENSOR_TYPE_MAGNETIC_FIELD:
508                 case SENSOR_TYPE_GYROSCOPE:
509                 case SENSOR_TYPE_PROXIMITY:
510                         break;
511                 default:
512                         return 0;
513         }
514
515         sprintf(mm_path, MOUNTING_MATRIX_PATH, dev_num);
516
517         err = sysfs_read_str(mm_path, mm_buf, sizeof(mm_buf));
518         if (err < 0)
519                 return 0;
520
521         for(i = 0; i < 9; i++) {
522                 float f;
523
524                 f = strtof(tmp1, &tmp2);
525                 if (!f && tmp1 == tmp2)
526                         return 0;
527                 mm[i] = f;
528                 tmp1 = tmp2 + 1;
529         }
530
531         /*
532          * For proximity sensors, interpret a negative final z value as a hint that the sensor is back mounted. In that case, mark the sensor as secondary to
533          * ensure that it gets listed after other sensors of same type that would be front-mounted. Most applications will only ask for the default proximity
534          * sensor and it makes more sense to point to, say, the IR based proximity sensor rather than SAR based one if we have both, as on SoFIA LTE MRD boards.
535          */
536          if (sensor[s].type == SENSOR_TYPE_PROXIMITY) {
537                 if (mm[8] < 0) {
538                         sensor[s].quirks |= QUIRK_SECONDARY;
539                 }
540                 return 0;
541         }
542
543         ALOGI("%s: %f %f %f %f %f %f %f %f %f\n", __func__, mm[0], mm[1], mm[2], mm[3], mm[4], mm[5], mm[6], mm[7], mm[8]);
544         return 1;
545 }
546
547
548 char* sensor_get_string_type (int s)
549 {
550         switch (sensor_desc[s].type) {
551                 case SENSOR_TYPE_ACCELEROMETER:
552                         return SENSOR_STRING_TYPE_ACCELEROMETER;
553
554                 case SENSOR_TYPE_MAGNETIC_FIELD:
555                         return SENSOR_STRING_TYPE_MAGNETIC_FIELD;
556
557                 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
558                         return SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
559
560                 case SENSOR_TYPE_ORIENTATION:
561                         return SENSOR_STRING_TYPE_ORIENTATION;
562
563                 case SENSOR_TYPE_GYROSCOPE:
564                         return SENSOR_STRING_TYPE_GYROSCOPE;
565
566                 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
567                         return SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
568
569                 case SENSOR_TYPE_LIGHT:
570                         return SENSOR_STRING_TYPE_LIGHT;
571
572                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
573                         return SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
574
575                 case SENSOR_TYPE_TEMPERATURE:
576                         return SENSOR_STRING_TYPE_TEMPERATURE;
577
578                 case SENSOR_TYPE_PROXIMITY:
579                         return SENSOR_STRING_TYPE_PROXIMITY;
580
581                 case SENSOR_TYPE_PRESSURE:
582                         return SENSOR_STRING_TYPE_PRESSURE;
583
584                 case SENSOR_TYPE_RELATIVE_HUMIDITY:
585                         return SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
586
587                 default:
588                         return "";
589                 }
590 }
591
592
593 flag_t sensor_get_flags (int s)
594 {
595         flag_t flags = 0;
596
597         switch (sensor_desc[s].type) {
598                 case SENSOR_TYPE_LIGHT:
599                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
600                 case SENSOR_TYPE_TEMPERATURE:
601                 case SENSOR_TYPE_RELATIVE_HUMIDITY:
602                 case SENSOR_TYPE_STEP_COUNTER:
603                         flags |= SENSOR_FLAG_ON_CHANGE_MODE;
604                         break;
605
606
607                 case SENSOR_TYPE_PROXIMITY:
608                         flags |= SENSOR_FLAG_WAKE_UP;
609                         flags |= SENSOR_FLAG_ON_CHANGE_MODE;
610                         break;
611                 case SENSOR_TYPE_STEP_DETECTOR:
612                         flags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
613                         break;
614                 default:
615                         break;
616                 }
617         return flags;
618 }
619
620
621 static int get_cdd_freq (int s, int must)
622 {
623         switch (sensor_desc[s].type) {
624                 case SENSOR_TYPE_ACCELEROMETER:
625                         return (must ? 100 : 200); /* must 100 Hz, should 200 Hz, CDD compliant */
626
627                 case SENSOR_TYPE_GYROSCOPE:
628                         return (must ? 200 : 200); /* must 200 Hz, should 200 Hz, CDD compliant */
629
630                 case SENSOR_TYPE_MAGNETIC_FIELD:
631                         return (must ? 10 : 50);   /* must 10 Hz, should 50 Hz, CDD compliant */
632
633                 case SENSOR_TYPE_LIGHT:
634                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
635                 case SENSOR_TYPE_TEMPERATURE:
636                         return (must ? 1 : 2);     /* must 1 Hz, should 2Hz, not mentioned in CDD */
637
638                 default:
639                         return 1; /* Use 1 Hz by default, e.g. for proximity */
640         }
641 }
642
643 /* 
644  * This value is defined only for continuous mode and on-change sensors. It is the delay between two sensor events corresponding to the lowest frequency that
645  * this sensor supports. When lower frequencies are requested through batch()/setDelay() the events will be generated at this frequency instead. It can be used
646  * by the framework or applications to estimate when the batch FIFO may be full. maxDelay should always fit within a 32 bit signed integer. It is declared as
647  * 64 bit on 64 bit architectures only for binary compatibility reasons. Availability: SENSORS_DEVICE_API_VERSION_1_3
648  */
649 max_delay_t sensor_get_max_delay (int s)
650 {
651         int dev_num = sensor[s].dev_num, i;
652         float min_supported_rate;
653         float rate_cap;
654
655         /*
656          * continuous, on-change: maximum sampling period allowed in microseconds.
657          * one-shot, special : 0
658          */
659         switch (REPORTING_MODE(sensor_desc[s].flags)) {
660                 case SENSOR_FLAG_ONE_SHOT_MODE:
661                 case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
662                         return 0;
663
664                 case SENSOR_FLAG_ON_CHANGE_MODE:
665                         return MAX_ON_CHANGE_SAMPLING_PERIOD_US;
666
667                 default:
668                         break;
669         }
670
671         if (sensor[s].is_virtual) {
672                 switch (sensor[s].type) {
673                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
674                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
675                                 return sensor_desc[sensor[s].base[0]].maxDelay;
676                         default:
677                                 return 0;
678                 }
679         }
680
681         switch (sensor[s].mode) {
682                 case MODE_TRIGGER:
683                         /* For interrupt-based devices, obey the list of supported sampling rates */
684                         if (!(sensor_get_quirks(s) & QUIRK_HRTIMER) &&
685                                         sensor[s].avail_freqs_count) {
686                                 min_supported_rate = 1000;
687                                 for (i = 0; i < sensor[s].avail_freqs_count; i++) {
688                                         if (sensor[s].avail_freqs[i] < min_supported_rate)
689                                                 min_supported_rate = sensor[s].avail_freqs[i];
690                                 }
691                                 break;
692                         }
693                         /* Fall through ... */
694
695                 default:
696                         /* Report 1 Hz */
697                         min_supported_rate = 1;
698                         break;
699         }
700
701         /* Check if a minimum rate was specified for this sensor */
702         rate_cap = sensor_get_min_freq(s);
703
704         if (min_supported_rate < rate_cap)
705                 min_supported_rate = rate_cap;
706
707         /* return 0 for wrong values */
708         if (min_supported_rate < 0.1)
709                 return 0;
710
711         /* Return microseconds */
712         return (max_delay_t) (1000000.0 / min_supported_rate);
713 }
714
715
716 int32_t sensor_get_min_delay (int s)
717 {
718         int dev_num = sensor[s].dev_num, i;
719         float max_supported_rate = 0;
720         float max_from_prop = sensor_get_max_freq(s);
721         int hrtimer_quirk_enabled = sensor_get_quirks(s) & QUIRK_HRTIMER;
722
723         /* continuous, on change: minimum sampling period allowed in microseconds.
724          * special : 0, unless otherwise noted
725          * one-shot:-1
726          */
727         switch (REPORTING_MODE(sensor_desc[s].flags)) {
728                 case SENSOR_FLAG_ON_CHANGE_MODE:
729                         return MIN_ON_CHANGE_SAMPLING_PERIOD_US;
730
731                 case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
732                         return 0;
733
734                 case SENSOR_FLAG_ONE_SHOT_MODE:
735                         return -1;
736
737                 default:
738                         break;
739         }
740
741         if (sensor[s].is_virtual) {
742                 switch (sensor[s].type) {
743                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
744                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
745                                 return sensor_desc[sensor[s].base[0]].minDelay;
746                         default:
747                                 return 0;
748                 }
749         }
750
751         if (hrtimer_quirk_enabled || !sensor[s].avail_freqs_count) {
752                 if (hrtimer_quirk_enabled || (sensor[s].mode == MODE_POLL)) {
753                         /* If we have max specified via a property use it */
754                         if (max_from_prop != ANDROID_MAX_FREQ)
755                                 max_supported_rate = max_from_prop;
756                         else
757                                 /* The should rate */
758                                 max_supported_rate = get_cdd_freq(s, 0);
759                 }
760         } else {
761                 for (i = 0; i < sensor[s].avail_freqs_count; i++) {
762                         if (sensor[s].avail_freqs[i] > max_supported_rate &&
763                                 sensor[s].avail_freqs[i] <= max_from_prop) {
764                                 max_supported_rate = sensor[s].avail_freqs[i];
765                         }
766                 }
767         }
768
769         /* return 0 for wrong values */
770         if (max_supported_rate < 0.1)
771                 return 0;
772
773         /* Return microseconds */
774         return (int32_t) (1000000.0 / max_supported_rate);
775 }