OSDN Git Service

STPK-1429 Enable the AOSP orientation sensor on T100
[android-x86/hardware-intel-libsensors.git] / enumeration.c
1 /*
2  * Copyright (C) 2014 Intel Corporation.
3  */
4
5 #include <dirent.h>
6 #include <utils/Log.h>
7 #include <hardware/sensors.h>
8 #include "enumeration.h"
9 #include "description.h"
10 #include "utils.h"
11 #include "transform.h"
12
13 /*
14  * This table maps syfs entries in scan_elements directories to sensor types,
15  * and will also be used to determine other sysfs names as well as the iio
16  * device number associated to a specific sensor.
17  */
18
19 struct sensor_catalog_entry_t sensor_catalog[] = {
20         DECLARE_SENSOR3("accel",      SENSOR_TYPE_ACCELEROMETER,  "x", "y", "z")
21         DECLARE_SENSOR3("anglvel",    SENSOR_TYPE_GYROSCOPE,      "x", "y", "z")
22         DECLARE_SENSOR3("magn",       SENSOR_TYPE_MAGNETIC_FIELD, "x", "y", "z")
23         DECLARE_SENSOR0("illuminance",SENSOR_TYPE_LIGHT                        )
24         DECLARE_SENSOR3("incli",      SENSOR_TYPE_ORIENTATION,    "x", "y", "z")
25         DECLARE_SENSOR4("rot",        SENSOR_TYPE_ROTATION_VECTOR,
26                                          "quat_x", "quat_y", "quat_z", "quat_w")
27         DECLARE_SENSOR0("temp",       SENSOR_TYPE_AMBIENT_TEMPERATURE          )
28 };
29
30 #define CATALOG_SIZE    ARRAY_SIZE(sensor_catalog)
31
32
33 /* We equate sensor handles to indices in these tables */
34
35 struct sensor_t      sensor_desc[MAX_SENSORS];  /* Android-level descriptors */
36 struct sensor_info_t sensor_info[MAX_SENSORS];  /* Internal descriptors      */
37 int sensor_count;                               /* Detected sensors          */
38
39
40 static void add_sensor (int dev_num, int catalog_index, int use_polling)
41 {
42         int s;
43         int sensor_type;
44         char sysfs_path[PATH_MAX];
45         const char* prefix;
46         float scale;
47
48         if (sensor_count == MAX_SENSORS) {
49                 ALOGE("Too many sensors!\n");
50                 return;
51         }
52
53         sensor_type = sensor_catalog[catalog_index].type;
54
55         /*
56          * At this point we could check that the expected sysfs attributes are
57          * present ; that would enable having multiple catalog entries with the
58          * same sensor type, accomodating different sets of sysfs attributes.
59          */
60
61         s = sensor_count;
62
63         sensor_info[s].dev_num          = dev_num;
64         sensor_info[s].catalog_index    = catalog_index;
65
66         if (use_polling)
67                 sensor_info[s].num_channels = 0;
68         else
69                 sensor_info[s].num_channels =
70                                 sensor_catalog[catalog_index].num_channels;
71
72         prefix = sensor_catalog[catalog_index].tag;
73
74         /* Read name attribute, if available */
75         sprintf(sysfs_path, NAME_PATH, dev_num);
76         sysfs_read_str(sysfs_path, sensor_info[s].internal_name, MAX_NAME_SIZE);
77
78         /* See if we have general offsets and scale values for this sensor */
79
80         sprintf(sysfs_path, SENSOR_OFFSET_PATH, dev_num, prefix);
81         sysfs_read_float(sysfs_path, &sensor_info[s].offset);
82
83         sprintf(sysfs_path, SENSOR_SCALE_PATH, dev_num, prefix);
84         if (!sysfs_read_float(sysfs_path, &scale))
85                 sensor_info[s].scale = scale;
86         else
87                 sensor_info[s].scale = 1;
88
89         /* Initialize Android-visible descriptor */
90         sensor_desc[s].name             = sensor_get_name(s);
91         sensor_desc[s].vendor           = sensor_get_vendor(s);
92         sensor_desc[s].version          = sensor_get_version(s);
93         sensor_desc[s].handle           = s;
94         sensor_desc[s].type             = sensor_type;
95         sensor_desc[s].maxRange         = sensor_get_max_range(s);
96         sensor_desc[s].resolution       = sensor_get_resolution(s);
97         sensor_desc[s].power            = sensor_get_power(s);
98
99         if (sensor_info[s].internal_name[0] == '\0') {
100                 /*
101                  * In case the kernel-mode driver doesn't expose a name for
102                  * the iio device, use (null)-dev%d as the trigger name...
103                  * This can be considered a kernel-mode iio driver bug.
104                  */
105                 ALOGW("Using null trigger on sensor %d (dev %d)\n", s, dev_num);
106                 strcpy(sensor_info[s].internal_name, "(null)");
107         }
108
109         /* Select one of the available sensor sample processing styles */
110         select_transform(s);
111
112         sensor_count++;
113 }
114
115
116 static void discover_poll_sensors (int dev_num, char map[CATALOG_SIZE])
117 {
118         char base_dir[PATH_MAX];
119         DIR *dir;
120         char sysfs_dir[PATH_MAX];
121         struct sensor *sensor;
122         struct dirent *d;
123         unsigned int i;
124         int c;
125
126         memset(map, 0, CATALOG_SIZE);
127
128         snprintf(base_dir, sizeof(base_dir), BASE_PATH, dev_num);
129
130         dir = opendir(base_dir);
131         if (!dir) {
132                return;
133         }
134
135         /* Enumerate entries in this iio device's base folder */
136
137         while ((d = readdir(dir))) {
138                 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
139                         continue;
140
141                 /* If the name matches a catalog entry, flag it */
142                 for (i = 0; i<CATALOG_SIZE; i++)
143                         for (c=0; c<sensor_catalog[i].num_channels; c++)
144                                 if (!strcmp(d->d_name,
145                                     sensor_catalog[i].channel[c].raw_path) ||
146                                     !strcmp(d->d_name,
147                                     sensor_catalog[i].channel[c].input_path)) {
148                                 map[i] = 1;
149                                 break;
150                         }
151         }
152
153         closedir(dir);
154 }
155
156
157 static void discover_trig_sensors (int dev_num, char map[CATALOG_SIZE])
158 {
159         char scan_elem_dir[PATH_MAX];
160         DIR *dir;
161         char sysfs_dir[PATH_MAX];
162         struct sensor *sensor;
163         struct dirent *d;
164         unsigned int i;
165
166         memset(map, 0, CATALOG_SIZE);
167
168         /* Enumerate entries in this iio device's scan_elements folder */
169
170         snprintf(scan_elem_dir, sizeof(scan_elem_dir), CHANNEL_PATH, dev_num);
171
172         dir = opendir(scan_elem_dir);
173         if (!dir) {
174                return;
175         }
176
177         while ((d = readdir(dir))) {
178                 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
179                         continue;
180
181                 /* Compare en entry to known ones and create matching sensors */
182
183                 for (i = 0; i<CATALOG_SIZE; i++)
184                         if (!strcmp(d->d_name,
185                                     sensor_catalog[i].channel[0].en_path)) {
186                                 map[i] = 1;
187                                 break;
188                         }
189         }
190
191         closedir(dir);
192 }
193
194
195 static void orientation_sensor_check(void)
196 {
197         /*
198          * If we have accel + gyro + magn but no rotation vector sensor,
199          * SensorService replaces the HAL provided orientation sensor by the
200          * AOSP version... provided we report one. So initialize a virtual
201          * orientation sensor with zero values, which will get replaced. See:
202          * frameworks/native/services/sensorservice/SensorService.cpp, looking
203          * for SENSOR_TYPE_ROTATION_VECTOR; that code should presumably fall
204          * back to mUserSensorList.add instead of replaceAt, but accommodate it.
205          */
206
207         int i;
208         int has_acc = 0;
209         int has_gyr = 0;
210         int has_mag = 0;
211         int has_rot = 0;
212         int has_ori = 0;
213
214         for (i=0; i<sensor_count; i++)
215                 switch (sensor_catalog[sensor_info[i].catalog_index].type) {
216                         case SENSOR_TYPE_ACCELEROMETER:
217                                 has_acc = 1;
218                                 break;
219                         case SENSOR_TYPE_GYROSCOPE:
220                                 has_gyr = 1;
221                                 break;
222                         case SENSOR_TYPE_MAGNETIC_FIELD:
223                                 has_mag = 1;
224                                 break;
225                         case SENSOR_TYPE_ORIENTATION:
226                                 has_ori = 1;
227                                 break;
228                         case SENSOR_TYPE_ROTATION_VECTOR:
229                                 has_rot = 1;
230                                 break;
231                 }
232
233         if (has_acc && has_gyr && has_mag && !has_rot && !has_ori)
234                 for (i=0; i<CATALOG_SIZE; i++)
235                         if (sensor_catalog[i].type == SENSOR_TYPE_ORIENTATION) {
236                                 ALOGI("Adding placeholder orientation sensor");
237                                 add_sensor(0, i, 1);
238                                 break;
239                         }
240 }
241
242
243 void enumerate_sensors (void)
244 {
245         /*
246          * Discover supported sensors and allocate control structures for them.
247          * Multiple sensors can potentially rely on a single iio device (each
248          * using their own channels). We can't have multiple sensors of the same
249          * type on the same device. In case of detection as both a poll-mode
250          * and trigger-based sensor, use the trigger usage mode.
251          */
252         char poll_sensors[CATALOG_SIZE];
253         char trig_sensors[CATALOG_SIZE];
254         int dev_num;
255         unsigned int i;
256
257         for (dev_num=0; dev_num<MAX_DEVICES; dev_num++) {
258                 discover_poll_sensors(dev_num, poll_sensors);
259                 discover_trig_sensors(dev_num, trig_sensors);
260
261                 for (i=0; i<CATALOG_SIZE; i++)
262                         if (trig_sensors[i])
263                                 add_sensor(dev_num, i, 0);
264                         else
265                                 if (poll_sensors[i])
266                                         add_sensor(dev_num, i, 1);
267         }
268
269         ALOGI("Discovered %d sensors\n", sensor_count);
270
271         /* Make sure Android fall backs to its own orientation sensor */
272         orientation_sensor_check();
273 }
274
275
276 void delete_enumeration_data (void)
277 {
278         /* Reset sensor count */
279         sensor_count = 0;
280 }
281
282
283 int get_sensors_list(   struct sensors_module_t* module,
284                         struct sensor_t const** list)
285 {
286         *list = sensor_desc;
287         return sensor_count;
288 }
289