OSDN Git Service

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