2 * Copyright (C) 2014-2015 Intel Corporation.
8 #include <cutils/properties.h>
9 #include <hardware/sensors.h>
11 #include "enumeration.h"
12 #include "description.h"
15 #define IIO_SENSOR_HAL_VERSION 1
17 #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) */
18 #define MAX_ON_CHANGE_SAMPLING_PERIOD_US 10000000 /* 0.1 Hz min (10 s max period)*/
19 #define ANDROID_MAX_FREQ 1000 /* 1000 Hz - This is how much Android requests for the fastest frequency */
24 * We acquire a number of parameters about sensors by reading properties.
25 * The idea here is that someone (either a script, or daemon, sets them
26 * depending on the set of sensors present on the machine.
28 * There are fallback paths in case the properties are not defined, but it is
29 * highly desirable to at least have the following for each sensor:
31 * ro.iio.anglvel.name = Gyroscope
32 * ro.iio.anglvel.vendor = Intel
33 * ro.iio.anglvel.max_range = 35
34 * ro.iio.anglvel.resolution = 0.002
35 * ro.iio.anglvel.power = 6.1
37 * Besides these, we have a couple of knobs initially used to cope with Intel
38 * Sensor Hub oddities, such as HID inspired units or firmware bugs:
40 * ro.iio.anglvel.transform = ISH
41 * ro.iio.anglvel.quirks = init-rate
43 * The "terse" quirk indicates that the underlying driver only sends events
44 * when the sensor reports a change. The HAL then periodically generates
45 * duplicate events so the sensor behaves as a continously firing one.
47 * The "noisy" quirk indicates that the underlying driver has a unusually high
48 * level of noise in its readings, and that the HAL has to accomodate it
49 * somehow, e.g. in the magnetometer calibration code path.
51 * This one is used specifically to pass a calibration scale to ALS drivers:
53 * ro.iio.illuminance.name = CPLM3218x Ambient Light Sensor
54 * ro.iio.illuminance.vendor = Capella Microsystems
55 * ro.iio.illuminance.max_range = 167000
56 * ro.iio.illuminance.resolution = 1
57 * ro.iio.illuminance.power = .001
58 * ro.iio.illuminance.illumincalib = 7400
60 * There's a 'opt_scale' specifier, documented as follows:
62 * This adds support for a scaling factor that can be expressed
63 * using properties, for all sensors, on a channel basis. That
64 * scaling factor is applied after all other transforms have been
65 * applied, and is intended as a way to compensate for problems
66 * such as an incorrect axis polarity for a given sensor.
68 * The syntax is <usual property prefix>.<channel>.opt_scale, e.g.
69 * ro.iio.accel.y.opt_scale = -1 to negate the sign of the y readings
70 * for the accelerometer.
72 * For sensors using a single channel - and only those - the channel
73 * name is implicitly void and a syntax such as ro.iio.illuminance.
74 * opt_scale = 3 has to be used.
76 * 'panel' and 'rotation' specifiers can be used to express ACPI PLD placement
77 * information ; if found they will be used in priority over the actual ACPI
78 * data. That is intended as a way to verify values during development.
80 * It's possible to use the contents of the iio device name as a way to
81 * discriminate between sensors. Several sensors of the same type can coexist:
82 * e.g. ro.iio.temp.bmg160.name = BMG160 Thermometer will be used in priority
83 * over ro.iio.temp.name = BMC150 Thermometer if the sensor for which we query
84 * properties values happen to have its iio device name set to bmg160.
87 int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE])
89 char prop_name[PROP_NAME_MAX];
90 char prop_val[PROP_VALUE_MAX];
91 char extended_sel[PROP_VALUE_MAX];
93 int i = sensor[s].catalog_index;
94 const char *prefix = sensor_catalog[i].tag;
95 const char *shorthand = sensor_catalog[i].shorthand;
97 /* First try most specialized form, like ro.iio.anglvel.bmg160.name */
99 snprintf(extended_sel, PROP_NAME_MAX, "%s.%s",
100 sensor[s].internal_name, sel);
102 snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, prefix, extended_sel);
104 if (property_get(prop_name, prop_val, "")) {
105 strncpy(val, prop_val, MAX_NAME_SIZE-1);
106 val[MAX_NAME_SIZE-1] = '\0';
110 if (shorthand[0] != '\0') {
111 /* Try with shorthand instead of prefix */
112 snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, shorthand, extended_sel);
114 if (property_get(prop_name, prop_val, "")) {
115 strncpy(val, prop_val, MAX_NAME_SIZE-1);
116 val[MAX_NAME_SIZE-1] = '\0';
120 /* Fall back to simple form, like ro.iio.anglvel.name */
122 snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, prefix, sel);
124 if (property_get(prop_name, prop_val, "")) {
125 strncpy(val, prop_val, MAX_NAME_SIZE-1);
126 val[MAX_NAME_SIZE-1] = '\0';
134 int sensor_get_prop (int s, const char* sel, int* val)
136 char buf[MAX_NAME_SIZE];
138 if (sensor_get_st_prop(s, sel, buf))
146 int sensor_get_fl_prop (int s, const char* sel, float* val)
148 char buf[MAX_NAME_SIZE];
150 if (sensor_get_st_prop(s, sel, buf))
153 *val = (float) strtod(buf, NULL);
158 char* sensor_get_name (int s)
160 char buf[MAX_NAME_SIZE];
162 if (sensor[s].is_virtual) {
163 switch (sensor[s].type) {
164 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
165 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
166 strcpy(buf, sensor[sensor[s].base[0]].friendly_name);
167 snprintf(sensor[s].friendly_name,
169 "%s %s", "Uncalibrated", buf);
170 return sensor[s].friendly_name;
177 if (sensor[s].friendly_name[0] != '\0' ||
178 !sensor_get_st_prop(s, "name", sensor[s].friendly_name))
179 return sensor[s].friendly_name;
181 /* If we got a iio device name from sysfs, use it */
182 if (sensor[s].internal_name[0]) {
183 snprintf(sensor[s].friendly_name, MAX_NAME_SIZE, "S%d-%s",
184 s, sensor[s].internal_name);
186 sprintf(sensor[s].friendly_name, "S%d", s);
189 return sensor[s].friendly_name;
193 char* sensor_get_vendor (int s)
195 if (sensor[s].is_virtual) {
196 switch (sensor[s].type) {
197 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
198 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
199 return sensor[sensor[s].base[0]].vendor_name;
208 if (sensor[s].vendor_name[0] ||
209 !sensor_get_st_prop(s, "vendor", sensor[s].vendor_name))
210 return sensor[s].vendor_name;
216 int sensor_get_version (__attribute__((unused)) int s)
218 return IIO_SENSOR_HAL_VERSION;
222 float sensor_get_max_range (int s)
224 if (sensor[s].is_virtual) {
225 switch (sensor[s].type) {
226 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
227 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
228 return sensor[sensor[s].base[0]].max_range;
235 if (sensor[s].max_range != 0.0 ||
236 !sensor_get_fl_prop(s, "max_range", &sensor[s].max_range))
237 return sensor[s].max_range;
239 /* Try returning a sensible value given the sensor type */
241 /* We should cap returned samples accordingly... */
243 switch (sensor_desc[s].type) {
244 case SENSOR_TYPE_ACCELEROMETER: /* m/s^2 */
247 case SENSOR_TYPE_MAGNETIC_FIELD: /* micro-tesla */
250 case SENSOR_TYPE_ORIENTATION: /* degrees */
253 case SENSOR_TYPE_GYROSCOPE: /* radians/s */
256 case SENSOR_TYPE_LIGHT: /* SI lux units */
259 case SENSOR_TYPE_AMBIENT_TEMPERATURE: /* °C */
260 case SENSOR_TYPE_TEMPERATURE: /* °C */
261 case SENSOR_TYPE_PROXIMITY: /* centimeters */
262 case SENSOR_TYPE_PRESSURE: /* hecto-pascal */
263 case SENSOR_TYPE_RELATIVE_HUMIDITY: /* percent */
271 static float sensor_get_min_freq (int s)
274 * Check if a low cap has been specified for this sensor sampling rate.
275 * In some case, even when the driver supports lower rate, we still
276 * wish to receive a certain number of samples per seconds for various
277 * reasons (calibration, filtering, no change in power consumption...).
282 if (!sensor_get_fl_prop(s, "min_freq", &min_freq))
289 float sensor_get_max_freq (int s)
293 if (!sensor_get_fl_prop(s, "max_freq", &max_freq))
296 return ANDROID_MAX_FREQ;
299 int sensor_get_cal_steps (int s)
302 if (!sensor_get_prop(s, "cal_steps", &cal_steps))
308 float sensor_get_resolution (int s)
310 if (sensor[s].is_virtual) {
311 switch (sensor[s].type) {
312 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
313 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
314 return sensor[sensor[s].base[0]].resolution;
321 if (sensor[s].resolution != 0.0 ||
322 !sensor_get_fl_prop(s, "resolution", &sensor[s].resolution))
323 return sensor[s].resolution;
329 float sensor_get_power (int s)
332 if (sensor[s].is_virtual) {
333 switch (sensor[s].type) {
334 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
335 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
336 return sensor[sensor[s].base[0]].power;
343 /* mA used while sensor is in use ; not sure about volts :) */
344 if (sensor[s].power != 0.0 ||
345 !sensor_get_fl_prop(s, "power", &sensor[s].power))
346 return sensor[s].power;
352 float sensor_get_illumincalib (int s)
354 /* calibrating the ALS Sensor*/
355 if (sensor[s].illumincalib != 0.0 ||
356 !sensor_get_fl_prop(s, "illumincalib", &sensor[s].illumincalib)) {
357 return sensor[s].illumincalib;
364 uint32_t sensor_get_quirks (int s)
366 char quirks_buf[MAX_NAME_SIZE];
368 /* Read and decode quirks property on first reference */
369 if (!(sensor[s].quirks & QUIRK_ALREADY_DECODED)) {
370 quirks_buf[0] = '\0';
371 sensor_get_st_prop(s, "quirks", quirks_buf);
373 if (strstr(quirks_buf, "init-rate"))
374 sensor[s].quirks |= QUIRK_INITIAL_RATE;
376 if (strstr(quirks_buf, "continuous"))
377 sensor[s].quirks |= QUIRK_FORCE_CONTINUOUS;
379 if (strstr(quirks_buf, "terse"))
380 sensor[s].quirks |= QUIRK_TERSE_DRIVER;
382 if (strstr(quirks_buf, "noisy"))
383 sensor[s].quirks |= QUIRK_NOISY;
385 if (strstr(quirks_buf, "biased"))
386 sensor[s].quirks |= QUIRK_BIASED;
388 if (strstr(quirks_buf, "spotty"))
389 sensor[s].quirks |= QUIRK_SPOTTY;
391 if (strstr(quirks_buf, "no-event"))
392 sensor[s].quirks |= QUIRK_NO_EVENT_MODE;
394 if (strstr(quirks_buf, "no-trig"))
395 sensor[s].quirks |= QUIRK_NO_TRIG_MODE;
397 if (strstr(quirks_buf, "no-poll"))
398 sensor[s].quirks |= QUIRK_NO_POLL_MODE;
400 if (strstr(quirks_buf, "hrtimer"))
401 sensor[s].quirks |= QUIRK_HRTIMER;
403 if (strstr(quirks_buf, "secondary"))
404 sensor[s].quirks |= QUIRK_SECONDARY;
406 sensor[s].quirks |= QUIRK_ALREADY_DECODED;
409 return sensor[s].quirks;
413 int sensor_get_order (int s, unsigned char map[MAX_CHANNELS])
415 char buf[MAX_NAME_SIZE];
417 int count = sensor_catalog[sensor[s].catalog_index].num_channels;
419 if (sensor_get_st_prop(s, "order", buf))
420 return 0; /* No order property */
422 /* Assume ASCII characters, in the '0'..'9' range */
424 for (i=0; i<count; i++)
425 if (buf[i] - '0' >= count) {
426 ALOGE("Order index out of range for sensor %d\n", s);
430 for (i=0; i<count; i++)
431 map[i] = buf[i] - '0';
433 return 1; /* OK to use modified ordering map */
436 int sensor_get_mounting_matrix (int s, float mm[9])
438 int dev_num = sensor[s].dev_num, err, i;
439 char mm_path[PATH_MAX], mm_buf[100];
440 char *tmp1 = mm_buf, *tmp2;
442 switch (sensor[s].type) {
443 case SENSOR_TYPE_ACCELEROMETER:
444 case SENSOR_TYPE_MAGNETIC_FIELD:
445 case SENSOR_TYPE_GYROSCOPE:
446 case SENSOR_TYPE_PROXIMITY:
452 sprintf(mm_path, MOUNTING_MATRIX_PATH, dev_num);
454 err = sysfs_read_str(mm_path, mm_buf, sizeof(mm_buf));
458 for(i = 0; i < 9; i++) {
461 f = strtof(tmp1, &tmp2);
462 if (!f && tmp1 == tmp2)
469 * 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
470 * 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
471 * 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.
473 if (sensor[s].type == SENSOR_TYPE_PROXIMITY) {
475 sensor[s].quirks |= QUIRK_SECONDARY;
480 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]);
485 char* sensor_get_string_type (int s)
487 switch (sensor_desc[s].type) {
488 case SENSOR_TYPE_ACCELEROMETER:
489 return SENSOR_STRING_TYPE_ACCELEROMETER;
491 case SENSOR_TYPE_MAGNETIC_FIELD:
492 return SENSOR_STRING_TYPE_MAGNETIC_FIELD;
494 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
495 return SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
497 case SENSOR_TYPE_ORIENTATION:
498 return SENSOR_STRING_TYPE_ORIENTATION;
500 case SENSOR_TYPE_GYROSCOPE:
501 return SENSOR_STRING_TYPE_GYROSCOPE;
503 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
504 return SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
506 case SENSOR_TYPE_LIGHT:
507 return SENSOR_STRING_TYPE_LIGHT;
509 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
510 return SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
512 case SENSOR_TYPE_TEMPERATURE:
513 return SENSOR_STRING_TYPE_TEMPERATURE;
515 case SENSOR_TYPE_PROXIMITY:
516 return SENSOR_STRING_TYPE_PROXIMITY;
518 case SENSOR_TYPE_PRESSURE:
519 return SENSOR_STRING_TYPE_PRESSURE;
521 case SENSOR_TYPE_RELATIVE_HUMIDITY:
522 return SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
530 flag_t sensor_get_flags (int s)
534 switch (sensor_desc[s].type) {
535 case SENSOR_TYPE_LIGHT:
536 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
537 case SENSOR_TYPE_TEMPERATURE:
538 case SENSOR_TYPE_RELATIVE_HUMIDITY:
539 case SENSOR_TYPE_STEP_COUNTER:
540 flags |= SENSOR_FLAG_ON_CHANGE_MODE;
544 case SENSOR_TYPE_PROXIMITY:
545 flags |= SENSOR_FLAG_WAKE_UP;
546 flags |= SENSOR_FLAG_ON_CHANGE_MODE;
548 case SENSOR_TYPE_STEP_DETECTOR:
549 flags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
558 static int get_cdd_freq (int s, int must)
560 switch (sensor_desc[s].type) {
561 case SENSOR_TYPE_ACCELEROMETER:
562 return (must ? 100 : 200); /* must 100 Hz, should 200 Hz, CDD compliant */
564 case SENSOR_TYPE_GYROSCOPE:
565 return (must ? 200 : 200); /* must 200 Hz, should 200 Hz, CDD compliant */
567 case SENSOR_TYPE_MAGNETIC_FIELD:
568 return (must ? 10 : 50); /* must 10 Hz, should 50 Hz, CDD compliant */
570 case SENSOR_TYPE_LIGHT:
571 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
572 case SENSOR_TYPE_TEMPERATURE:
573 return (must ? 1 : 2); /* must 1 Hz, should 2Hz, not mentioned in CDD */
576 return 1; /* Use 1 Hz by default, e.g. for proximity */
581 * 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
582 * this sensor supports. When lower frequencies are requested through batch()/setDelay() the events will be generated at this frequency instead. It can be used
583 * 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
584 * 64 bit on 64 bit architectures only for binary compatibility reasons. Availability: SENSORS_DEVICE_API_VERSION_1_3
586 max_delay_t sensor_get_max_delay (int s)
588 char avail_sysfs_path[PATH_MAX];
589 int dev_num = sensor[s].dev_num;
592 float min_supported_rate;
597 * continuous, on-change: maximum sampling period allowed in microseconds.
598 * one-shot, special : 0
600 switch (REPORTING_MODE(sensor_desc[s].flags)) {
601 case SENSOR_FLAG_ONE_SHOT_MODE:
602 case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
605 case SENSOR_FLAG_ON_CHANGE_MODE:
606 return MAX_ON_CHANGE_SAMPLING_PERIOD_US;
612 if (sensor[s].is_virtual) {
613 switch (sensor[s].type) {
614 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
615 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
616 return sensor_desc[sensor[s].base[0]].maxDelay;
622 switch (sensor[s].mode) {
624 /* For interrupt-based devices, obey the list of supported sampling rates */
625 sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num);
626 if (!(sensor_get_quirks(s) & QUIRK_HRTIMER) &&
627 sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf)) > 0) {
629 min_supported_rate = 1000;
632 while (*cursor && cursor[0]) {
634 /* Decode a single value */
635 sr = strtod(cursor, NULL);
637 if (sr < min_supported_rate)
638 min_supported_rate = sr;
641 while (cursor[0] && !isspace(cursor[0]))
645 while (cursor[0] && isspace(cursor[0]))
652 /* Fall through ... */
656 min_supported_rate = 1;
660 /* Check if a minimum rate was specified for this sensor */
661 rate_cap = sensor_get_min_freq(s);
663 if (min_supported_rate < rate_cap)
664 min_supported_rate = rate_cap;
666 /* return 0 for wrong values */
667 if (min_supported_rate < 0.1)
670 /* Return microseconds */
671 return (max_delay_t) (1000000.0 / min_supported_rate);
675 int32_t sensor_get_min_delay (int s)
677 char avail_sysfs_path[PATH_MAX];
678 int dev_num = sensor[s].dev_num;
681 float max_supported_rate = 0;
682 float max_from_prop = sensor_get_max_freq(s);
684 int hrtimer_quirk_enabled = sensor_get_quirks(s) & QUIRK_HRTIMER;
686 /* continuous, on change: minimum sampling period allowed in microseconds.
687 * special : 0, unless otherwise noted
690 switch (REPORTING_MODE(sensor_desc[s].flags)) {
691 case SENSOR_FLAG_ON_CHANGE_MODE:
692 return MIN_ON_CHANGE_SAMPLING_PERIOD_US;
694 case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
697 case SENSOR_FLAG_ONE_SHOT_MODE:
704 if (sensor[s].is_virtual) {
705 switch (sensor[s].type) {
706 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
707 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
708 return sensor_desc[sensor[s].base[0]].minDelay;
714 sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num);
716 if (hrtimer_quirk_enabled || sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf)) < 0) {
717 if (hrtimer_quirk_enabled || (sensor[s].mode == MODE_POLL)) {
718 /* If we have max specified via a property use it */
719 if (max_from_prop != ANDROID_MAX_FREQ)
720 max_supported_rate = max_from_prop;
722 /* The should rate */
723 max_supported_rate = get_cdd_freq(s, 0);
727 while (*cursor && cursor[0]) {
729 /* Decode a single value */
730 sr = strtod(cursor, NULL);
732 if (sr > max_supported_rate && sr <= max_from_prop)
733 max_supported_rate = sr;
736 while (cursor[0] && !isspace(cursor[0]))
740 while (cursor[0] && isspace(cursor[0]))
745 /* return 0 for wrong values */
746 if (max_supported_rate < 0.1)
749 /* Return microseconds */
750 return (int32_t) (1000000.0 / max_supported_rate);