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_available_frequencies (int s)
438 int dev_num = sensor[s].dev_num, err, i;
439 char avail_sysfs_path[PATH_MAX], freqs_buf[100];
443 sensor[s].avail_freqs_count = 0;
444 sensor[s].avail_freqs = 0;
446 sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num);
448 err = sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf));
452 for (p = freqs_buf, f = strtof(p, &end); p != end; p = end, f = strtof(p, &end))
453 sensor[s].avail_freqs_count++;
455 if (sensor[s].avail_freqs_count) {
456 sensor[s].avail_freqs = (float*) calloc(sensor[s].avail_freqs_count, sizeof(float));
458 for (p = freqs_buf, f = strtof(p, &end), i = 0; p != end; p = end, f = strtof(p, &end), i++)
459 sensor[s].avail_freqs[i] = f;
465 int sensor_get_mounting_matrix (int s, float mm[9])
467 int dev_num = sensor[s].dev_num, err, i;
468 char mm_path[PATH_MAX], mm_buf[100];
469 char *tmp1 = mm_buf, *tmp2;
471 switch (sensor[s].type) {
472 case SENSOR_TYPE_ACCELEROMETER:
473 case SENSOR_TYPE_MAGNETIC_FIELD:
474 case SENSOR_TYPE_GYROSCOPE:
475 case SENSOR_TYPE_PROXIMITY:
481 sprintf(mm_path, MOUNTING_MATRIX_PATH, dev_num);
483 err = sysfs_read_str(mm_path, mm_buf, sizeof(mm_buf));
487 for(i = 0; i < 9; i++) {
490 f = strtof(tmp1, &tmp2);
491 if (!f && tmp1 == tmp2)
498 * 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
499 * 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
500 * 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.
502 if (sensor[s].type == SENSOR_TYPE_PROXIMITY) {
504 sensor[s].quirks |= QUIRK_SECONDARY;
509 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]);
514 char* sensor_get_string_type (int s)
516 switch (sensor_desc[s].type) {
517 case SENSOR_TYPE_ACCELEROMETER:
518 return SENSOR_STRING_TYPE_ACCELEROMETER;
520 case SENSOR_TYPE_MAGNETIC_FIELD:
521 return SENSOR_STRING_TYPE_MAGNETIC_FIELD;
523 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
524 return SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
526 case SENSOR_TYPE_ORIENTATION:
527 return SENSOR_STRING_TYPE_ORIENTATION;
529 case SENSOR_TYPE_GYROSCOPE:
530 return SENSOR_STRING_TYPE_GYROSCOPE;
532 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
533 return SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
535 case SENSOR_TYPE_LIGHT:
536 return SENSOR_STRING_TYPE_LIGHT;
538 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
539 return SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
541 case SENSOR_TYPE_TEMPERATURE:
542 return SENSOR_STRING_TYPE_TEMPERATURE;
544 case SENSOR_TYPE_PROXIMITY:
545 return SENSOR_STRING_TYPE_PROXIMITY;
547 case SENSOR_TYPE_PRESSURE:
548 return SENSOR_STRING_TYPE_PRESSURE;
550 case SENSOR_TYPE_RELATIVE_HUMIDITY:
551 return SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
559 flag_t sensor_get_flags (int s)
563 switch (sensor_desc[s].type) {
564 case SENSOR_TYPE_LIGHT:
565 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
566 case SENSOR_TYPE_TEMPERATURE:
567 case SENSOR_TYPE_RELATIVE_HUMIDITY:
568 case SENSOR_TYPE_STEP_COUNTER:
569 flags |= SENSOR_FLAG_ON_CHANGE_MODE;
573 case SENSOR_TYPE_PROXIMITY:
574 flags |= SENSOR_FLAG_WAKE_UP;
575 flags |= SENSOR_FLAG_ON_CHANGE_MODE;
577 case SENSOR_TYPE_STEP_DETECTOR:
578 flags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
587 static int get_cdd_freq (int s, int must)
589 switch (sensor_desc[s].type) {
590 case SENSOR_TYPE_ACCELEROMETER:
591 return (must ? 100 : 200); /* must 100 Hz, should 200 Hz, CDD compliant */
593 case SENSOR_TYPE_GYROSCOPE:
594 return (must ? 200 : 200); /* must 200 Hz, should 200 Hz, CDD compliant */
596 case SENSOR_TYPE_MAGNETIC_FIELD:
597 return (must ? 10 : 50); /* must 10 Hz, should 50 Hz, CDD compliant */
599 case SENSOR_TYPE_LIGHT:
600 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
601 case SENSOR_TYPE_TEMPERATURE:
602 return (must ? 1 : 2); /* must 1 Hz, should 2Hz, not mentioned in CDD */
605 return 1; /* Use 1 Hz by default, e.g. for proximity */
610 * 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
611 * this sensor supports. When lower frequencies are requested through batch()/setDelay() the events will be generated at this frequency instead. It can be used
612 * 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
613 * 64 bit on 64 bit architectures only for binary compatibility reasons. Availability: SENSORS_DEVICE_API_VERSION_1_3
615 max_delay_t sensor_get_max_delay (int s)
617 int dev_num = sensor[s].dev_num, i;
618 float min_supported_rate;
622 * continuous, on-change: maximum sampling period allowed in microseconds.
623 * one-shot, special : 0
625 switch (REPORTING_MODE(sensor_desc[s].flags)) {
626 case SENSOR_FLAG_ONE_SHOT_MODE:
627 case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
630 case SENSOR_FLAG_ON_CHANGE_MODE:
631 return MAX_ON_CHANGE_SAMPLING_PERIOD_US;
637 if (sensor[s].is_virtual) {
638 switch (sensor[s].type) {
639 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
640 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
641 return sensor_desc[sensor[s].base[0]].maxDelay;
647 switch (sensor[s].mode) {
649 /* For interrupt-based devices, obey the list of supported sampling rates */
650 if (!(sensor_get_quirks(s) & QUIRK_HRTIMER) &&
651 sensor[s].avail_freqs_count) {
652 min_supported_rate = 1000;
653 for (i = 0; i < sensor[s].avail_freqs_count; i++) {
654 if (sensor[s].avail_freqs[i] < min_supported_rate)
655 min_supported_rate = sensor[s].avail_freqs[i];
659 /* Fall through ... */
663 min_supported_rate = 1;
667 /* Check if a minimum rate was specified for this sensor */
668 rate_cap = sensor_get_min_freq(s);
670 if (min_supported_rate < rate_cap)
671 min_supported_rate = rate_cap;
673 /* return 0 for wrong values */
674 if (min_supported_rate < 0.1)
677 /* Return microseconds */
678 return (max_delay_t) (1000000.0 / min_supported_rate);
682 int32_t sensor_get_min_delay (int s)
684 int dev_num = sensor[s].dev_num, i;
685 float max_supported_rate = 0;
686 float max_from_prop = sensor_get_max_freq(s);
687 int hrtimer_quirk_enabled = sensor_get_quirks(s) & QUIRK_HRTIMER;
689 /* continuous, on change: minimum sampling period allowed in microseconds.
690 * special : 0, unless otherwise noted
693 switch (REPORTING_MODE(sensor_desc[s].flags)) {
694 case SENSOR_FLAG_ON_CHANGE_MODE:
695 return MIN_ON_CHANGE_SAMPLING_PERIOD_US;
697 case SENSOR_FLAG_SPECIAL_REPORTING_MODE:
700 case SENSOR_FLAG_ONE_SHOT_MODE:
707 if (sensor[s].is_virtual) {
708 switch (sensor[s].type) {
709 case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
710 case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
711 return sensor_desc[sensor[s].base[0]].minDelay;
717 if (hrtimer_quirk_enabled || !sensor[s].avail_freqs_count) {
718 if (hrtimer_quirk_enabled || (sensor[s].mode == MODE_POLL)) {
719 /* If we have max specified via a property use it */
720 if (max_from_prop != ANDROID_MAX_FREQ)
721 max_supported_rate = max_from_prop;
723 /* The should rate */
724 max_supported_rate = get_cdd_freq(s, 0);
727 for (i = 0; i < sensor[s].avail_freqs_count; i++) {
728 if (sensor[s].avail_freqs[i] > max_supported_rate &&
729 sensor[s].avail_freqs[i] <= max_from_prop) {
730 max_supported_rate = sensor[s].avail_freqs[i];
735 /* return 0 for wrong values */
736 if (max_supported_rate < 0.1)
739 /* Return microseconds */
740 return (int32_t) (1000000.0 / max_supported_rate);