OSDN Git Service

Rename MAX_REAL_DEP to MAX_BASE_SENSORS and base_idx to base
[android-x86/hardware-intel-libsensors.git] / enumeration.c
1 /*
2  * Copyright (C) 2014 Intel Corporation.
3  */
4
5 #include <ctype.h>
6 #include <dirent.h>
7 #include <stdlib.h>
8 #include <utils/Log.h>
9 #include <hardware/sensors.h>
10 #include "enumeration.h"
11 #include "description.h"
12 #include "utils.h"
13 #include "transform.h"
14 #include "description.h"
15 #include "control.h"
16 #include "calibration.h"
17
18 /*
19  * This table maps syfs entries in scan_elements directories to sensor types,
20  * and will also be used to determine other sysfs names as well as the iio
21  * device number associated to a specific sensor.
22  */
23
24  /*
25   * We duplicate entries for the uncalibrated types after their respective base
26   * sensor. This is because all sensor entries must have an associated catalog entry
27   * and also because when only the uncal sensor is active it needs to take it's data
28   * from the same iio device as the base one.
29   */
30
31 struct sensor_catalog_entry_t sensor_catalog[] = {
32         DECLARE_SENSOR3("accel",      SENSOR_TYPE_ACCELEROMETER,  "x", "y", "z")
33         DECLARE_SENSOR3("anglvel",    SENSOR_TYPE_GYROSCOPE,      "x", "y", "z")
34         DECLARE_SENSOR3("magn",       SENSOR_TYPE_MAGNETIC_FIELD, "x", "y", "z")
35         DECLARE_SENSOR1("intensity",  SENSOR_TYPE_LIGHT,          "both"       )
36         DECLARE_SENSOR0("illuminance",SENSOR_TYPE_LIGHT                        )
37         DECLARE_SENSOR3("incli",      SENSOR_TYPE_ORIENTATION,    "x", "y", "z")
38         DECLARE_SENSOR4("rot",        SENSOR_TYPE_ROTATION_VECTOR,
39                                          "quat_x", "quat_y", "quat_z", "quat_w")
40         DECLARE_SENSOR0("temp",       SENSOR_TYPE_AMBIENT_TEMPERATURE          )
41         DECLARE_SENSOR0("proximity",  SENSOR_TYPE_PROXIMITY                    )
42         DECLARE_VIRTUAL(SENSOR_TYPE_GYROSCOPE_UNCALIBRATED                     )
43 };
44
45 #define CATALOG_SIZE    ARRAY_SIZE(sensor_catalog)
46
47 /* ACPI PLD (physical location of device) definitions, as used with sensors */
48
49 #define PANEL_FRONT     4
50 #define PANEL_BACK      5
51
52 /* We equate sensor handles to indices in these tables */
53
54 struct sensor_t      sensor_desc[MAX_SENSORS];  /* Android-level descriptors */
55 struct sensor_info_t sensor[MAX_SENSORS];       /* Internal descriptors      */
56 int sensor_count;                               /* Detected sensors          */
57
58
59 static void setup_properties_from_pld (int s, int panel, int rotation,
60                                        int num_channels)
61 {
62         /*
63          * Generate suitable order and opt_scale directives from the PLD panel
64          * and rotation codes we got. This can later be superseded by the usual
65          * properties if necessary. Eventually we'll need to replace these
66          * mechanisms by a less convoluted one, such as a 3x3 placement matrix.
67          */
68
69         int x = 1;
70         int y = 1;
71         int z = 1;
72         int xy_swap = 0;
73         int angle = rotation * 45;
74
75         /* Only deal with 3 axis chips for now */
76         if (num_channels < 3)
77                 return;
78
79         if (panel == PANEL_BACK) {
80                 /* Chip placed on the back panel ; negate x and z */
81                 x = -x;
82                 z = -z;
83         }
84
85         switch (angle) {
86                 case 90: /* 90° clockwise: negate y then swap x,y */
87                         xy_swap = 1;
88                         y = -y;
89                         break;
90
91                 case 180: /* Upside down: negate x and y */
92                         x = -x;
93                         y = -y;
94                         break;
95
96                 case 270: /* 90° counter clockwise: negate x then swap x,y */
97                         x = -x;
98                         xy_swap = 1;
99                         break;
100         }
101
102         if (xy_swap) {
103                 sensor[s].order[0] = 1;
104                 sensor[s].order[1] = 0;
105                 sensor[s].order[2] = 2;
106                 sensor[s].quirks |= QUIRK_FIELD_ORDERING;
107         }
108
109         sensor[s].channel[0].opt_scale = x;
110         sensor[s].channel[1].opt_scale = y;
111         sensor[s].channel[2].opt_scale = z;
112 }
113
114
115 static int is_valid_pld (int panel, int rotation)
116 {
117         if (panel != PANEL_FRONT && panel != PANEL_BACK) {
118                 ALOGW("Unhandled PLD panel spec: %d\n", panel);
119                 return 0;
120         }
121
122         /* Only deal with 90° rotations for now */
123         if (rotation < 0 || rotation > 7 || (rotation & 1)) {
124                 ALOGW("Unhandled PLD rotation spec: %d\n", rotation);
125                 return 0;
126         }
127
128         return 1;
129 }
130
131
132 static int read_pld_from_properties (int s, int* panel, int* rotation)
133 {
134         int p, r;
135
136         if (sensor_get_prop(s, "panel", &p))
137                 return -1;
138
139         if (sensor_get_prop(s, "rotation", &r))
140                 return -1;
141
142         if (!is_valid_pld(p, r))
143                 return -1;
144
145         *panel = p;
146         *rotation = r;
147
148         ALOGI("S%d PLD from properties: panel=%d, rotation=%d\n", s, p, r);
149
150         return 0;
151 }
152
153
154 static int read_pld_from_sysfs (int s, int dev_num, int* panel, int* rotation)
155 {
156         char sysfs_path[PATH_MAX];
157         int p,r;
158
159         sprintf(sysfs_path, BASE_PATH "../firmware_node/pld/panel", dev_num);
160
161         if (sysfs_read_int(sysfs_path, &p))
162                 return -1;
163
164         sprintf(sysfs_path, BASE_PATH "../firmware_node/pld/rotation", dev_num);
165
166         if (sysfs_read_int(sysfs_path, &r))
167                 return -1;
168
169         if (!is_valid_pld(p, r))
170                 return -1;
171
172         *panel = p;
173         *rotation = r;
174
175         ALOGI("S%d PLD from sysfs: panel=%d, rotation=%d\n", s, p, r);
176
177         return 0;
178 }
179
180
181 static void decode_placement_information (int dev_num, int num_channels, int s)
182 {
183         /*
184          * See if we have optional "physical location of device" ACPI tags.
185          * We're only interested in panel and rotation specifiers. Use the
186          * .panel and .rotation properties in priority, and the actual ACPI
187          * values as a second source.
188          */
189
190         int panel;
191         int rotation;
192
193         if (read_pld_from_properties(s, &panel, &rotation) &&
194                 read_pld_from_sysfs(s, dev_num, &panel, &rotation))
195                         return; /* No PLD data available */
196
197         /* Map that to field ordering and scaling mechanisms */
198         setup_properties_from_pld(s, panel, rotation, num_channels);
199 }
200
201
202 static void populate_descriptors (int s, int sensor_type)
203 {
204         /* Initialize Android-visible descriptor */
205         sensor_desc[s].name             = sensor_get_name(s);
206         sensor_desc[s].vendor           = sensor_get_vendor(s);
207         sensor_desc[s].version          = sensor_get_version(s);
208         sensor_desc[s].handle           = s;
209         sensor_desc[s].type             = sensor_type;
210
211         sensor_desc[s].maxRange         = sensor_get_max_range(s);
212         sensor_desc[s].resolution       = sensor_get_resolution(s);
213         sensor_desc[s].power            = sensor_get_power(s);
214         sensor_desc[s].stringType       = sensor_get_string_type(s);
215
216         /* None of our supported sensors requires a special permission */
217         sensor_desc[s].requiredPermission = "";
218
219         sensor_desc[s].flags = sensor_get_flags(s);
220         sensor_desc[s].minDelay = sensor_get_min_delay(s);
221         sensor_desc[s].maxDelay = sensor_get_max_delay(s);
222
223         ALOGV("Sensor %d (%s) type(%d) minD(%d) maxD(%d) flags(%2.2x)\n",
224                 s, sensor[s].friendly_name, sensor_desc[s].type,
225                 sensor_desc[s].minDelay, sensor_desc[s].maxDelay,
226                 sensor_desc[s].flags);
227
228         /* We currently do not implement batching */
229         sensor_desc[s].fifoReservedEventCount = 0;
230         sensor_desc[s].fifoMaxEventCount = 0;
231 }
232
233
234 static void add_virtual_sensor (int catalog_index)
235 {
236         int s;
237         int sensor_type;
238
239         if (sensor_count == MAX_SENSORS) {
240                 ALOGE("Too many sensors!\n");
241                 return;
242         }
243
244         sensor_type = sensor_catalog[catalog_index].type;
245
246         s = sensor_count;
247
248         sensor[s].is_virtual = 1;
249         sensor[s].catalog_index = catalog_index;
250         sensor[s].type          = sensor_type;
251
252         populate_descriptors(s, sensor_type);
253
254         /* Initialize fields related to sysfs reads offloading */
255         sensor[s].thread_data_fd[0]  = -1;
256         sensor[s].thread_data_fd[1]  = -1;
257         sensor[s].acquisition_thread = -1;
258
259         sensor_count++;
260 }
261
262
263 static void add_sensor (int dev_num, int catalog_index, int use_polling)
264 {
265         int s;
266         int sensor_type;
267         int retval;
268         char sysfs_path[PATH_MAX];
269         const char* prefix;
270         float scale;
271         int c;
272         float opt_scale;
273         const char* ch_name;
274         int num_channels;
275         char suffix[MAX_NAME_SIZE + 8];
276
277         if (sensor_count == MAX_SENSORS) {
278                 ALOGE("Too many sensors!\n");
279                 return;
280         }
281
282         sensor_type = sensor_catalog[catalog_index].type;
283
284         /*
285          * At this point we could check that the expected sysfs attributes are
286          * present ; that would enable having multiple catalog entries with the
287          * same sensor type, accomodating different sets of sysfs attributes.
288          */
289
290         s = sensor_count;
291
292         sensor[s].dev_num               = dev_num;
293         sensor[s].catalog_index = catalog_index;
294         sensor[s].type          = sensor_type;
295
296         num_channels = sensor_catalog[catalog_index].num_channels;
297
298         if (use_polling)
299                 sensor[s].num_channels = 0;
300         else
301                 sensor[s].num_channels = num_channels;
302
303         prefix = sensor_catalog[catalog_index].tag;
304
305         /*
306          * receiving the illumination sensor calibration inputs from
307          * the Android properties and setting it within sysfs
308          */
309         if (sensor_type == SENSOR_TYPE_LIGHT) {
310                 retval = sensor_get_illumincalib(s);
311                 if (retval > 0) {
312                         sprintf(sysfs_path, ILLUMINATION_CALIBPATH, dev_num);
313                         sysfs_write_int(sysfs_path, retval);
314                 }
315         }
316
317         /* Read name attribute, if available */
318         sprintf(sysfs_path, NAME_PATH, dev_num);
319         sysfs_read_str(sysfs_path, sensor[s].internal_name, MAX_NAME_SIZE);
320
321         /* See if we have general offsets and scale values for this sensor */
322
323         sprintf(sysfs_path, SENSOR_OFFSET_PATH, dev_num, prefix);
324         sysfs_read_float(sysfs_path, &sensor[s].offset);
325
326         sprintf(sysfs_path, SENSOR_SCALE_PATH, dev_num, prefix);
327         if (!sensor_get_fl_prop(s, "scale", &scale)) {
328                 /*
329                  * There is a chip preferred scale specified,
330                  * so try to store it in sensor's scale file
331                  */
332                 if (sysfs_write_float(sysfs_path, scale) == -1 && errno == ENOENT) {
333                         ALOGE("Failed to store scale[%f] into %s - file is missing", scale, sysfs_path);
334                         /* Store failed, try to store the scale into channel specific file */
335                         for (c = 0; c < num_channels; c++)
336                         {
337                                 sprintf(sysfs_path, BASE_PATH "%s", dev_num,
338                                         sensor_catalog[catalog_index].channel[c].scale_path);
339                                 if (sysfs_write_float(sysfs_path, scale) == -1)
340                                         ALOGE("Failed to store scale[%f] into %s", scale, sysfs_path);
341                         }
342                 }
343         }
344
345         sprintf(sysfs_path, SENSOR_SCALE_PATH, dev_num, prefix);
346         if (!sysfs_read_float(sysfs_path, &scale)) {
347                 sensor[s].scale = scale;
348                 ALOGI("Scale path:%s scale:%f dev_num:%d\n",
349                                         sysfs_path, scale, dev_num);
350         } else {
351                 sensor[s].scale = 1;
352
353                 /* Read channel specific scale if any*/
354                 for (c = 0; c < num_channels; c++)
355                 {
356                         sprintf(sysfs_path, BASE_PATH "%s", dev_num,
357                            sensor_catalog[catalog_index].channel[c].scale_path);
358
359                         if (!sysfs_read_float(sysfs_path, &scale)) {
360                                 sensor[s].channel[c].scale = scale;
361                                 sensor[s].scale = 0;
362
363                                 ALOGI(  "Scale path:%s "
364                                         "channel scale:%f dev_num:%d\n",
365                                         sysfs_path, scale, dev_num);
366                         }
367                 }
368         }
369
370         /* Set default scaling - if num_channels is zero, we have one channel */
371
372         sensor[s].channel[0].opt_scale = 1;
373
374         for (c = 1; c < num_channels; c++)
375                 sensor[s].channel[c].opt_scale = 1;
376
377         /* Read ACPI _PLD attributes for this sensor, if there are any */
378         decode_placement_information(dev_num, num_channels, s);
379
380         /*
381          * See if we have optional correction scaling factors for each of the
382          * channels of this sensor. These would be expressed using properties
383          * like iio.accel.y.opt_scale = -1. In case of a single channel we also
384          * support things such as iio.temp.opt_scale = -1. Note that this works
385          * for all types of sensors, and whatever transform is selected, on top
386          * of any previous conversions.
387          */
388
389         if (num_channels) {
390                 for (c = 0; c < num_channels; c++) {
391                         ch_name = sensor_catalog[catalog_index].channel[c].name;
392                         sprintf(suffix, "%s.opt_scale", ch_name);
393                         if (!sensor_get_fl_prop(s, suffix, &opt_scale))
394                                 sensor[s].channel[c].opt_scale = opt_scale;
395                 }
396         } else
397                 if (!sensor_get_fl_prop(s, "opt_scale", &opt_scale))
398                         sensor[s].channel[0].opt_scale = opt_scale;
399
400         populate_descriptors(s, sensor_type);
401
402         /* Populate the quirks array */
403         sensor_get_quirks(s);
404
405         if (sensor[s].internal_name[0] == '\0') {
406                 /*
407                  * In case the kernel-mode driver doesn't expose a name for
408                  * the iio device, use (null)-dev%d as the trigger name...
409                  * This can be considered a kernel-mode iio driver bug.
410                  */
411                 ALOGW("Using null trigger on sensor %d (dev %d)\n", s, dev_num);
412                 strcpy(sensor[s].internal_name, "(null)");
413         }
414
415         switch (sensor_type) {
416                 case SENSOR_TYPE_GYROSCOPE:
417                         sensor[s].cal_data = malloc(sizeof(struct gyro_cal_t));
418                         break;
419
420                 case SENSOR_TYPE_MAGNETIC_FIELD:
421                         sensor[s].cal_data = malloc(sizeof(struct compass_cal_t));
422                         break;
423         }
424
425         sensor[s].max_cal_level = sensor_get_cal_steps(s);
426
427         /* Select one of the available sensor sample processing styles */
428         select_transform(s);
429
430         /* Initialize fields related to sysfs reads offloading */
431         sensor[s].thread_data_fd[0]  = -1;
432         sensor[s].thread_data_fd[1]  = -1;
433         sensor[s].acquisition_thread = -1;
434
435         /* Check if we have a special ordering property on this sensor */
436         if (sensor_get_order(s, sensor[s].order))
437                 sensor[s].quirks |= QUIRK_FIELD_ORDERING;
438
439         sensor_count++;
440 }
441
442
443 static void discover_poll_sensors (int dev_num, char map[CATALOG_SIZE])
444 {
445         char base_dir[PATH_MAX];
446         DIR *dir;
447         struct dirent *d;
448         unsigned int i;
449         int c;
450
451         memset(map, 0, CATALOG_SIZE);
452
453         snprintf(base_dir, sizeof(base_dir), BASE_PATH, dev_num);
454
455         dir = opendir(base_dir);
456         if (!dir) {
457                 return;
458         }
459
460         /* Enumerate entries in this iio device's base folder */
461
462         while ((d = readdir(dir))) {
463                 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
464                         continue;
465
466                 /* If the name matches a catalog entry, flag it */
467                 for (i = 0; i < CATALOG_SIZE; i++) {
468                 /* No discovery for virtual sensors */
469                 if (sensor_catalog[i].is_virtual)
470                         continue;
471                 for (c=0; c<sensor_catalog[i].num_channels; c++)
472                         if (!strcmp(d->d_name,sensor_catalog[i].channel[c].raw_path) ||
473                                 !strcmp(d->d_name, sensor_catalog[i].channel[c].input_path)) {
474                                         map[i] = 1;
475                                         break;
476                         }
477                 }
478         }
479
480         closedir(dir);
481 }
482
483
484 static void discover_trig_sensors (int dev_num, char map[CATALOG_SIZE])
485 {
486         char scan_elem_dir[PATH_MAX];
487         DIR *dir;
488         struct dirent *d;
489         unsigned int i;
490
491         memset(map, 0, CATALOG_SIZE);
492
493         /* Enumerate entries in this iio device's scan_elements folder */
494
495         snprintf(scan_elem_dir, sizeof(scan_elem_dir), CHANNEL_PATH, dev_num);
496
497         dir = opendir(scan_elem_dir);
498         if (!dir) {
499                 return;
500         }
501
502         while ((d = readdir(dir))) {
503                 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
504                         continue;
505
506                 /* Compare en entry to known ones and create matching sensors */
507
508                 for (i = 0; i<CATALOG_SIZE; i++) {
509                         /* No discovery for virtual sensors */
510                         if (sensor_catalog[i].is_virtual)
511                                 continue;
512                         if (!strcmp(d->d_name,
513                                         sensor_catalog[i].channel[0].en_path)) {
514                                         map[i] = 1;
515                                         break;
516                         }
517                 }
518         }
519
520         closedir(dir);
521 }
522
523
524 static void orientation_sensor_check (void)
525 {
526         /*
527          * If we have accel + gyro + magn but no rotation vector sensor,
528          * SensorService replaces the HAL provided orientation sensor by the
529          * AOSP version... provided we report one. So initialize a virtual
530          * orientation sensor with zero values, which will get replaced. See:
531          * frameworks/native/services/sensorservice/SensorService.cpp, looking
532          * for SENSOR_TYPE_ROTATION_VECTOR; that code should presumably fall
533          * back to mUserSensorList.add instead of replaceAt, but accommodate it.
534          */
535
536         int i;
537         int has_acc = 0;
538         int has_gyr = 0;
539         int has_mag = 0;
540         int has_rot = 0;
541         int has_ori = 0;
542         int catalog_size = CATALOG_SIZE;
543
544         for (i=0; i<sensor_count; i++)
545                 switch (sensor[i].type) {
546                         case SENSOR_TYPE_ACCELEROMETER:
547                                 has_acc = 1;
548                                 break;
549                         case SENSOR_TYPE_GYROSCOPE:
550                                 has_gyr = 1;
551                                 break;
552                         case SENSOR_TYPE_MAGNETIC_FIELD:
553                                 has_mag = 1;
554                                 break;
555                         case SENSOR_TYPE_ORIENTATION:
556                                 has_ori = 1;
557                                 break;
558                         case SENSOR_TYPE_ROTATION_VECTOR:
559                                 has_rot = 1;
560                                 break;
561                 }
562
563         if (has_acc && has_gyr && has_mag && !has_rot && !has_ori)
564                 for (i=0; i<catalog_size; i++)
565                         if (sensor_catalog[i].type == SENSOR_TYPE_ORIENTATION) {
566                                 ALOGI("Adding placeholder orientation sensor");
567                                 add_sensor(0, i, 1);
568                                 break;
569                         }
570 }
571
572
573 static void propose_new_trigger (int s, char trigger_name[MAX_NAME_SIZE],
574                                  int sensor_name_len)
575 {
576         /*
577          * A new trigger has been enumerated for this sensor. Check if it makes
578          * sense to use it over the currently selected one, and select it if it
579          * is so. The format is something like sensor_name-dev0.
580          */
581
582         const char *suffix = trigger_name + sensor_name_len + 1;
583
584         /* dev is the default, and lowest priority; no need to update */
585         if (!memcmp(suffix, "dev", 3))
586                 return;
587
588         /* If we found any-motion trigger, record it */
589
590         if (!memcmp(suffix, "any-motion-", 11)) {
591                 strcpy(sensor[s].motion_trigger_name, trigger_name);
592                 return;
593         }
594
595         /*
596          * It's neither the default "dev" nor an "any-motion" one. Make sure we
597          * use this though, as we may not have any other indication of the name
598          * of the trigger to use with this sensor.
599          */
600         strcpy(sensor[s].init_trigger_name, trigger_name);
601 }
602
603
604 static void update_sensor_matching_trigger_name (char name[MAX_NAME_SIZE])
605 {
606         /*
607          * Check if we have a sensor matching the specified trigger name,
608          * which should then begin with the sensor name, and end with a number
609          * equal to the iio device number the sensor is associated to. If so,
610          * update the string we're going to write to trigger/current_trigger
611          * when enabling this sensor.
612          */
613
614         int s;
615         int dev_num;
616         int len;
617         char* cursor;
618         int sensor_name_len;
619
620         /*
621          * First determine the iio device number this trigger refers to. We
622          * expect the last few characters (typically one) of the trigger name
623          * to be this number, so perform a few checks.
624          */
625         len = strnlen(name, MAX_NAME_SIZE);
626
627         if (len < 2)
628                 return;
629
630         cursor = name + len - 1;
631
632         if (!isdigit(*cursor))
633                 return;
634
635         while (len && isdigit(*cursor)) {
636                 len--;
637                 cursor--;
638         }
639
640         dev_num = atoi(cursor+1);
641
642         /* See if that matches a sensor */
643         for (s=0; s<sensor_count; s++)
644                 if (sensor[s].dev_num == dev_num) {
645
646                         sensor_name_len = strlen(sensor[s].internal_name);
647
648                         if (!strncmp(name,
649                                      sensor[s].internal_name,
650                                      sensor_name_len))
651                                 /* Switch to new trigger if appropriate */
652                                 propose_new_trigger(s, name, sensor_name_len);
653                 }
654 }
655
656
657 static void setup_trigger_names (void)
658 {
659         char filename[PATH_MAX];
660         char buf[MAX_NAME_SIZE];
661         int len;
662         int s;
663         int trigger;
664         int ret;
665
666         /* By default, use the name-dev convention that most drivers use */
667         for (s=0; s<sensor_count; s++)
668                 snprintf(sensor[s].init_trigger_name,
669                          MAX_NAME_SIZE, "%s-dev%d",
670                          sensor[s].internal_name, sensor[s].dev_num);
671
672         /* Now have a look to /sys/bus/iio/devices/triggerX entries */
673
674         for (trigger=0; trigger<MAX_TRIGGERS; trigger++) {
675
676                 snprintf(filename, sizeof(filename), TRIGGER_FILE_PATH,trigger);
677
678                 ret = sysfs_read_str(filename, buf, sizeof(buf));
679
680                 if (ret < 0)
681                         break;
682
683                 /* Record initial and any-motion triggers names */
684                 update_sensor_matching_trigger_name(buf);
685         }
686
687         /*
688          * Certain drivers expose only motion triggers even though they should
689          * be continous. For these, use the default trigger name as the motion
690          * trigger. The code generating intermediate events is dependent on
691          * motion_trigger_name being set to a non empty string.
692          */
693
694         for (s=0; s<sensor_count; s++)
695                 if ((sensor[s].quirks & QUIRK_TERSE_DRIVER) &&
696                     sensor[s].motion_trigger_name[0] == '\0')
697                         strcpy( sensor[s].motion_trigger_name,
698                                 sensor[s].init_trigger_name);
699
700         for (s=0; s<sensor_count; s++)
701                 if (sensor[s].num_channels) {
702                         ALOGI("Sensor %d (%s) default trigger: %s\n", s,
703                                 sensor[s].friendly_name,
704                                 sensor[s].init_trigger_name);
705                         if (sensor[s].motion_trigger_name[0])
706                                 ALOGI("Sensor %d (%s) motion trigger: %s\n",
707                                 s, sensor[s].friendly_name,
708                                 sensor[s].motion_trigger_name);
709                 }
710 }
711
712
713 static void uncalibrated_gyro_check (void)
714 {
715         unsigned int has_gyr = 0;
716         unsigned int dev_num;
717         int i;
718
719         int cal_idx = 0;
720         int uncal_idx = 0;
721         int catalog_size = CATALOG_SIZE; /* Avoid GCC sign comparison warning */
722
723         if (sensor_count == MAX_SENSORS)
724                 return;
725         /* Checking to see if we have a gyroscope - we can only have uncal if we have the base sensor */
726         for (i=0; i < sensor_count; i++)
727                 if (sensor[i].type == SENSOR_TYPE_GYROSCOPE) {
728                         has_gyr=1;
729                         cal_idx = i;
730                         break;
731                 }
732
733         if (has_gyr) {
734                 uncal_idx = sensor_count;
735                 sensor[uncal_idx].base_count = 1;
736                 sensor[uncal_idx].base[0] = cal_idx;
737
738                 for (i=0; i<catalog_size; i++)
739                         if (sensor_catalog[i].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
740                                 add_virtual_sensor(i);
741                                 break;
742                         }
743         }
744 }
745
746
747 void enumerate_sensors (void)
748 {
749         /*
750          * Discover supported sensors and allocate control structures for them.
751          * Multiple sensors can potentially rely on a single iio device (each
752          * using their own channels). We can't have multiple sensors of the same
753          * type on the same device. In case of detection as both a poll-mode
754          * and trigger-based sensor, use the trigger usage mode.
755          */
756         char poll_sensors[CATALOG_SIZE];
757         char trig_sensors[CATALOG_SIZE];
758         int dev_num;
759         unsigned int i;
760         int trig_found;
761
762         for (dev_num=0; dev_num<MAX_DEVICES; dev_num++) {
763                 trig_found = 0;
764
765                 discover_poll_sensors(dev_num, poll_sensors);
766                 discover_trig_sensors(dev_num, trig_sensors);
767
768                 for (i=0; i<CATALOG_SIZE; i++)
769                         if (trig_sensors[i]) {
770                                 add_sensor(dev_num, i, 0);
771                                 trig_found = 1;
772                         }
773                         else
774                                 if (poll_sensors[i])
775                                         add_sensor(dev_num, i, 1);
776
777                 if (trig_found) {
778                         build_sensor_report_maps(dev_num);
779                 }
780         }
781
782         ALOGI("Discovered %d sensors\n", sensor_count);
783
784         /* Set up default - as well as custom - trigger names */
785         setup_trigger_names();
786
787         /* Make sure Android fall backs to its own orientation sensor */
788         orientation_sensor_check();
789
790         /*
791          * Create the uncalibrated counterpart to the compensated gyroscope.
792          * This is is a new sensor type in Android 4.4.
793          */
794
795           uncalibrated_gyro_check();
796 }
797
798
799 void delete_enumeration_data (void)
800 {
801         int i;
802         for (i = 0; i < sensor_count; i++)
803                 if (sensor[i].cal_data) {
804                         free(sensor[i].cal_data);
805                         sensor[i].cal_data = NULL;
806                         sensor[i].cal_level = 0;
807                 }
808
809         /* Reset sensor count */
810         sensor_count = 0;
811 }
812
813
814 int get_sensors_list (__attribute__((unused)) struct sensors_module_t* module,
815                       struct sensor_t const** list)
816 {
817         *list = sensor_desc;
818         return sensor_count;
819 }
820