OSDN Git Service

STPK-1429 Add support for custom trigger names
[android-x86/hardware-intel-libsensors.git] / description.c
1 /*
2  * Copyright (C) 2014 Intel Corporation.
3  */
4
5 #include <stdlib.h>
6 #include <utils/Log.h>
7 #include <cutils/properties.h>
8 #include <hardware/sensors.h>
9 #include "enumeration.h"
10 #include "description.h"
11
12 #define IIO_SENSOR_HAL_VERSION  1
13
14 /*
15  * About properties
16  *
17  * We acquire a number of parameters about sensors by reading properties.
18  * The idea here is that someone (either a script, or daemon, sets them
19  * depending on the set of sensors present on the machine.
20  *
21  * There are fallback paths in case the properties are not defined, but it is
22  * highly desirable to at least have the following for each sensor:
23  *
24  * ro.iio.anglvel.name = Gyroscope
25  * ro.iio.anglvel.vendor = Intel
26  * ro.iio.anglvel.max_range = 35
27  * ro.iio.anglvel.resolution = 0.002
28  * ro.iio.anglvel.power = 6.1
29  *
30  * Besides these, we have a couple of knobs initially used to cope with Intel
31  * Sensor Hub oddities, such as HID inspired units or firmware bugs:
32  *
33  * ro.iio.anglvel.transform = ISH
34  * ro.iio.anglvel.quirks = init-rate
35  *
36  * This one is used specifically to pass a calibration scale to ALS drivers:
37  *
38  * ro.iio.illuminance.name = CPLM3218x Ambient Light Sensor
39  * ro.iio.illuminance.vendor = Capella Microsystems
40  * ro.iio.illuminance.max_range = 167000
41  * ro.iio.illuminance.resolution = 1
42  * ro.iio.illuminance.power = .001
43  * ro.iio.illuminance.illumincalib = 7400
44  *
45  * Finally there's a 'opt_scale' specifier, documented as follows:
46  *
47  *  This adds support for a scaling factor that can be expressed
48  *  using properties, for all sensors, on a channel basis. That
49  *  scaling factor is applied after all other transforms have been
50  *  applied, and is intended as a way to compensate for problems
51  *  such as an incorrect axis polarity for a given sensor.
52  *
53  *  The syntax is <usual property prefix>.<channel>.opt_scale, e.g.
54  *  ro.iio.accel.y.opt_scale = -1 to negate the sign of the y readings
55  *  for the accelerometer.
56  *
57  *  For sensors using a single channel - and only those - the channel
58  *  name is implicitly void and a syntax such as ro.iio.illuminance.
59  *  opt_scale = 3 has to be used.
60  */
61
62 static int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE])
63 {
64         char prop_name[PROP_NAME_MAX];
65         char prop_val[PROP_VALUE_MAX];
66         int i                   = sensor_info[s].catalog_index;
67         const char *prefix      = sensor_catalog[i].tag;
68
69         sprintf(prop_name, PROP_BASE, prefix, sel);
70
71         if (property_get(prop_name, prop_val, "")) {
72                 strncpy(val, prop_val, MAX_NAME_SIZE-1);
73                 val[MAX_NAME_SIZE-1] = '\0';
74                 return 0;
75         }
76
77         return -1;
78 }
79
80
81 int sensor_get_fl_prop (int s, const char* sel, float* val)
82 {
83         char buf[MAX_NAME_SIZE];
84
85         if (sensor_get_st_prop(s, sel, buf))
86                 return -1;
87
88         *val = (float) strtod(buf, NULL);
89         return 0;
90 }
91
92
93 char* sensor_get_name (int s)
94 {
95         if (sensor_info[s].friendly_name[0] != '\0' ||
96                 !sensor_get_st_prop(s, "name", sensor_info[s].friendly_name))
97                         return sensor_info[s].friendly_name;
98
99         /* If we got a iio device name from sysfs, use it */
100         if (sensor_info[s].internal_name[0]) {
101                 snprintf(sensor_info[s].friendly_name, MAX_NAME_SIZE, "S%d-%s",
102                          s, sensor_info[s].internal_name);
103         } else {
104                 sprintf(sensor_info[s].friendly_name, "S%d", s);
105         }
106
107         return sensor_info[s].friendly_name;
108 }
109
110
111 char* sensor_get_vendor (int s)
112 {
113         if (sensor_info[s].vendor_name[0] ||
114                 !sensor_get_st_prop(s, "vendor", sensor_info[s].vendor_name))
115                         return sensor_info[s].vendor_name;
116
117         return "";
118 }
119
120
121 int sensor_get_version (int s)
122 {
123         return IIO_SENSOR_HAL_VERSION;
124 }
125
126
127 float sensor_get_max_range (int s)
128 {
129         int catalog_index;
130         int sensor_type;
131
132         if (sensor_info[s].max_range != 0.0 ||
133                 !sensor_get_fl_prop(s, "max_range", &sensor_info[s].max_range))
134                         return sensor_info[s].max_range;
135
136         /* Try returning a sensible value given the sensor type */
137
138         /* We should cap returned samples accordingly... */
139
140         catalog_index = sensor_info[s].catalog_index;
141         sensor_type = sensor_catalog[catalog_index].type;
142
143         switch (sensor_type) {
144                 case SENSOR_TYPE_ACCELEROMETER:         /* m/s^2        */
145                         return 50;
146
147                 case SENSOR_TYPE_MAGNETIC_FIELD:        /* micro-tesla  */
148                         return 500;
149
150                 case SENSOR_TYPE_ORIENTATION:           /* degrees      */
151                         return 360;
152
153                 case SENSOR_TYPE_GYROSCOPE:             /* radians/s    */
154                         return 10;
155
156                 case SENSOR_TYPE_LIGHT:                 /* SI lux units */
157                         return 50000;
158
159                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:   /* °C          */
160                 case SENSOR_TYPE_TEMPERATURE:           /* °C          */
161                 case SENSOR_TYPE_PROXIMITY:             /* centimeters  */
162                 case SENSOR_TYPE_PRESSURE:              /* hecto-pascal */
163                 case SENSOR_TYPE_RELATIVE_HUMIDITY:     /* percent */
164                         return 100;
165
166                 default:
167                         return 0.0;
168                 }
169 }
170
171
172 float sensor_get_resolution (int s)
173 {
174         if (sensor_info[s].resolution != 0.0 ||
175                 !sensor_get_fl_prop(s, "resolution", &sensor_info[s].resolution))
176                         return sensor_info[s].resolution;
177
178         return 0;
179 }
180
181
182 float sensor_get_power (int s)
183 {
184         /* mA used while sensor is in use ; not sure about volts :) */
185         if (sensor_info[s].power != 0.0 ||
186                 !sensor_get_fl_prop(s, "power", &sensor_info[s].power))
187                         return sensor_info[s].power;
188
189         return 0;
190 }
191
192
193 float sensor_get_illumincalib (int s)
194 {
195         /* calibrating the ALS Sensor*/
196         if (sensor_info[s].illumincalib != 0.0 ||
197                 !sensor_get_fl_prop(s, "illumincalib", &sensor_info[s].illumincalib)) {
198                         return sensor_info[s].illumincalib;
199         }
200
201         return 0;
202 }
203
204
205 uint32_t sensor_get_quirks (int s)
206 {
207         char quirks_buf[MAX_NAME_SIZE];
208
209         /* Read and decode quirks property on first reference */
210         if (!(sensor_info[s].quirks & QUIRKS_ALREADY_DECODED)) {
211                 quirks_buf[0] = '\0';
212                 sensor_get_st_prop(s, "quirks", quirks_buf);
213
214                 if (strstr(quirks_buf, "init-rate"))
215                         sensor_info[s].quirks |= QUIRKS_INITIAL_RATE;
216
217                 sensor_info[s].quirks |= QUIRKS_ALREADY_DECODED;
218         }
219
220         return sensor_info[s].quirks;
221 }
222
223
224 int sensor_get_order (int s, unsigned char map[MAX_CHANNELS])
225 {
226         char buf[MAX_NAME_SIZE];
227         int i;
228         int count = sensor_catalog[sensor_info[s].catalog_index].num_channels;
229
230         memset(map, 0, MAX_CHANNELS);
231
232         if  (sensor_get_st_prop(s, "order", buf))
233                 return 0; /* No order property */
234
235         /* Assume ASCII characters, in the '0'..'9' range */
236
237         for (i=0; i<count; i++)
238                 map[i] = buf[i] - '0';
239
240         /* Check that our indices are in range */
241         for (i=0; i<count; i++)
242                 if (map[i] >= count) {
243                         ALOGE("Order index out of range for sensor %d\n", s);
244                         return 0;
245                 }
246
247         return 1;       /* OK to use modified ordering map */
248 }