OSDN Git Service

Reverse the default orientation of accelerometer
[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         char avail_sysfs_path[PATH_MAX], freqs_buf[100];
486         char *p, *end;
487         float f;
488
489         sensor[s].avail_freqs_count = 0;
490         sensor[s].avail_freqs = 0;
491
492         sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num);
493
494         err = sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf));
495         if (err < 0)
496                 return 0;
497
498         for (p = freqs_buf, f = strtof(p, &end); p != end; p = end, f = strtof(p, &end))
499                 sensor[s].avail_freqs_count++;
500
501         if (sensor[s].avail_freqs_count) {
502                 sensor[s].avail_freqs = (float*) calloc(sensor[s].avail_freqs_count, sizeof(float));
503
504                 for (p = freqs_buf, f = strtof(p, &end), i = 0; p != end; p = end, f = strtof(p, &end), i++)
505                         sensor[s].avail_freqs[i] = f;
506         }
507
508         return 0;
509 }
510
511 int sensor_get_mounting_matrix (int s, float mm[9])
512 {
513         int dev_num = sensor[s].dev_num, err, i;
514         char mm_path[PATH_MAX], mm_buf[100];
515         char *tmp1 = mm_buf, *tmp2;
516
517         switch (sensor[s].type) {
518                 case SENSOR_TYPE_ACCELEROMETER:
519                 case SENSOR_TYPE_MAGNETIC_FIELD:
520                 case SENSOR_TYPE_GYROSCOPE:
521                 case SENSOR_TYPE_PROXIMITY:
522                         break;
523                 default:
524                         return 0;
525         }
526
527         sprintf(mm_path, MOUNTING_MATRIX_PATH, dev_num);
528
529         err = sysfs_read_str(mm_path, mm_buf, sizeof(mm_buf));
530         if (err < 0)
531                 return 0;
532
533         for(i = 0; i < 9; i++) {
534                 float f;
535
536                 f = strtof(tmp1, &tmp2);
537                 if (!f && tmp1 == tmp2)
538                         return 0;
539                 mm[i] = f;
540                 tmp1 = tmp2 + 1;
541         }
542
543         /*
544          * 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
545          * 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
546          * 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.
547          */
548          if (sensor[s].type == SENSOR_TYPE_PROXIMITY) {
549                 if (mm[8] < 0) {
550                         sensor[s].quirks |= QUIRK_SECONDARY;
551                 }
552                 return 0;
553         }
554
555         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]);
556         return 1;
557 }
558
559
560 char* sensor_get_string_type (int s)
561 {
562         switch (sensor_desc[s].type) {
563                 case SENSOR_TYPE_ACCELEROMETER:
564                         return SENSOR_STRING_TYPE_ACCELEROMETER;
565
566                 case SENSOR_TYPE_MAGNETIC_FIELD:
567                         return SENSOR_STRING_TYPE_MAGNETIC_FIELD;
568
569                 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
570                         return SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
571
572                 case SENSOR_TYPE_ORIENTATION:
573                         return SENSOR_STRING_TYPE_ORIENTATION;
574
575                 case SENSOR_TYPE_GYROSCOPE:
576                         return SENSOR_STRING_TYPE_GYROSCOPE;
577
578                 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
579                         return SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
580
581                 case SENSOR_TYPE_LIGHT:
582                         return SENSOR_STRING_TYPE_LIGHT;
583
584                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
585                         return SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
586
587                 case SENSOR_TYPE_TEMPERATURE:
588                         return SENSOR_STRING_TYPE_TEMPERATURE;
589
590                 case SENSOR_TYPE_PROXIMITY:
591                         return SENSOR_STRING_TYPE_PROXIMITY;
592
593                 case SENSOR_TYPE_PRESSURE:
594                         return SENSOR_STRING_TYPE_PRESSURE;
595
596                 case SENSOR_TYPE_RELATIVE_HUMIDITY:
597                         return SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
598
599                 default:
600                         return "";
601                 }
602 }
603
604
605 flag_t sensor_get_flags (int s)
606 {
607         flag_t flags = 0;
608
609         switch (sensor_desc[s].type) {
610                 case SENSOR_TYPE_LIGHT:
611                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
612                 case SENSOR_TYPE_TEMPERATURE:
613                 case SENSOR_TYPE_RELATIVE_HUMIDITY:
614                 case SENSOR_TYPE_STEP_COUNTER:
615                         flags |= SENSOR_FLAG_ON_CHANGE_MODE;
616                         break;
617
618
619                 case SENSOR_TYPE_PROXIMITY:
620                         flags |= SENSOR_FLAG_WAKE_UP;
621                         flags |= SENSOR_FLAG_ON_CHANGE_MODE;
622                         break;
623                 case SENSOR_TYPE_STEP_DETECTOR:
624                         flags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
625                         break;
626                 default:
627                         break;
628                 }
629         return flags;
630 }
631
632
633 static int get_cdd_freq (int s, int must)
634 {
635         switch (sensor_desc[s].type) {
636                 case SENSOR_TYPE_ACCELEROMETER:
637                         return (must ? 100 : 200); /* must 100 Hz, should 200 Hz, CDD compliant */
638
639                 case SENSOR_TYPE_GYROSCOPE:
640                         return (must ? 200 : 200); /* must 200 Hz, should 200 Hz, CDD compliant */
641
642                 case SENSOR_TYPE_MAGNETIC_FIELD:
643                         return (must ? 10 : 50);   /* must 10 Hz, should 50 Hz, CDD compliant */
644
645                 case SENSOR_TYPE_LIGHT:
646                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
647                 case SENSOR_TYPE_TEMPERATURE:
648                         return (must ? 1 : 2);     /* must 1 Hz, should 2Hz, not mentioned in CDD */
649
650                 default:
651                         return 1; /* Use 1 Hz by default, e.g. for proximity */
652         }
653 }
654
655 /*
656  * 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
657  * this sensor supports. When lower frequencies are requested through batch()/setDelay() the events will be generated at this frequency instead. It can be used
658  * 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
659  * 64 bit on 64 bit architectures only for binary compatibility reasons. Availability: SENSORS_DEVICE_API_VERSION_1_3
660  */
661 max_delay_t sensor_get_max_delay (int s)
662 {
663         int i;
664         float min_supported_rate;
665         float rate_cap;
666
667         /*
668          * continuous, on-change: maximum sampling period allowed in microseconds.
669          * one-shot, special : 0
670          */
671         switch (REPORTING_MODE(sensor_desc[s].flags)) {
672                 case SENSOR_FLAG_ONE_SHOT_MODE:
673                 case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
674                         return 0;
675
676                 case SENSOR_FLAG_ON_CHANGE_MODE:
677                         return MAX_ON_CHANGE_SAMPLING_PERIOD_US;
678
679                 default:
680                         break;
681         }
682
683         if (sensor[s].is_virtual) {
684                 switch (sensor[s].type) {
685                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
686                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
687                                 return sensor_desc[sensor[s].base[0]].maxDelay;
688                         default:
689                                 return 0;
690                 }
691         }
692
693         switch (sensor[s].mode) {
694                 case MODE_TRIGGER:
695                         /* For interrupt-based devices, obey the list of supported sampling rates */
696                         if (sensor[s].avail_freqs_count) {
697                                 min_supported_rate = 1000;
698                                 for (i = 0; i < sensor[s].avail_freqs_count; i++) {
699                                         if (sensor[s].avail_freqs[i] < min_supported_rate)
700                                                 min_supported_rate = sensor[s].avail_freqs[i];
701                                 }
702                                 break;
703                         }
704                         /* Fall through ... */
705
706                 default:
707                         /* Report 1 Hz */
708                         min_supported_rate = 1;
709                         break;
710         }
711
712         /* Check if a minimum rate was specified for this sensor */
713         rate_cap = sensor_get_min_freq(s);
714
715         if (min_supported_rate < rate_cap)
716                 min_supported_rate = rate_cap;
717
718         /* return 0 for wrong values */
719         if (min_supported_rate < 0.1)
720                 return 0;
721
722         /* Return microseconds */
723         return (max_delay_t) (1000000.0 / min_supported_rate);
724 }
725
726 float sensor_get_max_static_freq(int s)
727 {
728         float max_from_prop = sensor_get_max_freq(s);
729
730         /* If we have max specified via a property use it */
731         if (max_from_prop != ANDROID_MAX_FREQ) {
732                 return max_from_prop;
733         } else {
734                 /* The should rate */
735                 return get_cdd_freq(s, 0);
736         }
737 }
738
739 int32_t sensor_get_min_delay (int s)
740 {
741         int i;
742         float max_supported_rate = 0;
743         float max_from_prop = sensor_get_max_freq(s);
744
745         /* continuous, on change: minimum sampling period allowed in microseconds.
746          * special : 0, unless otherwise noted
747          * one-shot:-1
748          */
749         switch (REPORTING_MODE(sensor_desc[s].flags)) {
750                 case SENSOR_FLAG_ON_CHANGE_MODE:
751                         return MIN_ON_CHANGE_SAMPLING_PERIOD_US;
752
753                 case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
754                         return 0;
755
756                 case SENSOR_FLAG_ONE_SHOT_MODE:
757                         return -1;
758
759                 default:
760                         break;
761         }
762
763         if (sensor[s].is_virtual) {
764                 switch (sensor[s].type) {
765                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
766                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
767                                 return sensor_desc[sensor[s].base[0]].minDelay;
768                         default:
769                                 return 0;
770                 }
771         }
772
773         if (!sensor[s].avail_freqs_count) {
774                 if (sensor[s].mode == MODE_POLL) {
775                         /* If we have max specified via a property use it */
776                         if (max_from_prop != ANDROID_MAX_FREQ)
777                                 max_supported_rate = max_from_prop;
778                         else
779                                 /* The should rate */
780                                 max_supported_rate = get_cdd_freq(s, 0);
781                 }
782         } else {
783                 for (i = 0; i < sensor[s].avail_freqs_count; i++) {
784                         if (sensor[s].avail_freqs[i] > max_supported_rate &&
785                                 sensor[s].avail_freqs[i] <= max_from_prop) {
786                                 max_supported_rate = sensor[s].avail_freqs[i];
787                         }
788                 }
789         }
790
791         /* return 0 for wrong values */
792         if (max_supported_rate < 0.1)
793                 return 0;
794
795         /* Return microseconds */
796         return (int32_t) (1000000.0 / max_supported_rate);
797 }