OSDN Git Service

GMINL-10383: Allow for prioritization of sensors
authorPatrick Porlan <patrick.porlan@intel.com>
Thu, 18 Jun 2015 16:05:18 +0000 (18:05 +0200)
committerPatrick Porlan <patrick.porlan@intel.com>
Tue, 23 Jun 2015 14:25:00 +0000 (16:25 +0200)
This adds support for a 'secondary' quirk that ensures that
such sensors are listed after normal ones. One possible usage
is to list SAR proximity sensors after ALS ones.

i.e. setprop ro.iio.prox.sx9500.quirks "secondary"

The quirk is also implied by the presence of a negative
value in the last slot of the orientation matrix in the
Device Tree, for proximity sensors

Change-Id: I4d0b83b3220abfe7155b193e15356bb4e9ce8b1f
Signed-off-by: Patrick Porlan <patrick.porlan@intel.com>
description.c
description.h
enumeration.c

index 302121f..a4dd2df 100644 (file)
@@ -400,6 +400,9 @@ uint32_t sensor_get_quirks (int s)
                if (strstr(quirks_buf, "hrtimer"))
                        sensor[s].quirks |= QUIRK_HRTIMER;
 
+               if (strstr(quirks_buf, "secondary"))
+                       sensor[s].quirks |= QUIRK_SECONDARY;
+
                sensor[s].quirks |= QUIRK_ALREADY_DECODED;
        }
 
@@ -437,12 +440,13 @@ int sensor_get_mounting_matrix (int s, float mm[9])
        char *tmp1 = mm_buf, *tmp2;
 
        switch (sensor[s].type) {
-       case SENSOR_TYPE_ACCELEROMETER:
-       case SENSOR_TYPE_MAGNETIC_FIELD:
-       case SENSOR_TYPE_GYROSCOPE:
-               break;
-       default:
-               return 0;
+               case SENSOR_TYPE_ACCELEROMETER:
+               case SENSOR_TYPE_MAGNETIC_FIELD:
+               case SENSOR_TYPE_GYROSCOPE:
+               case SENSOR_TYPE_PROXIMITY:
+                       break;
+               default:
+                       return 0;
        }
 
        sprintf(mm_path, MOUNTING_MATRIX_PATH, dev_num);
@@ -461,6 +465,18 @@ int sensor_get_mounting_matrix (int s, float mm[9])
                tmp1 = tmp2 + 1;
        }
 
+       /*
+        * 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
+        * 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
+        * 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.
+        */
+        if (sensor[s].type == SENSOR_TYPE_PROXIMITY) {
+               if (mm[8] < 0) {
+                       sensor[s].quirks |= QUIRK_SECONDARY;
+               }
+               return 0;
+       }
+
        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]);
        return 1;
 }
index 80868e9..72f3bba 100644 (file)
@@ -7,19 +7,20 @@
 
 #include "common.h"
 
-#define QUIRK_ALREADY_DECODED  0x01  /* Sensor quirks have been read         */
-#define QUIRK_INITIAL_RATE     0x02  /* Force initial sensor sampling rate   */
-#define QUIRK_FIELD_ORDERING   0x04  /* Do field remapping for this sensor   */
-#define QUIRK_TERSE_DRIVER     0x08  /* Force duplicate events generation    */
-#define QUIRK_NOISY            0x10  /* High noise level on readings         */
-#define QUIRK_FORCE_CONTINUOUS 0x20  /* Force usage of continuous trigger    */
-#define QUIRK_BIASED           0x40  /* Biased sensor, requires compensation */
-#define QUIRK_SPOTTY           0x80  /* Driver may lose events               */
-#define QUIRK_NO_EVENT_MODE    0x100 /* Disable event mode                   */
-#define QUIRK_NO_TRIG_MODE     0x200 /* Disable trigger mode                 */
-#define QUIRK_NO_POLL_MODE     0x400 /* Disable poll mode                    */
-#define QUIRK_MOUNTING_MATRIX  0x800  /* Mounting information present */
-#define QUIRK_HRTIMER          0x1000  /* We may use a hrtimer if there is no other trigger */
+#define QUIRK_ALREADY_DECODED  0x01    /* Sensor quirks have been read                         */
+#define QUIRK_INITIAL_RATE     0x02    /* Force initial sensor sampling rate                   */
+#define QUIRK_FIELD_ORDERING   0x04    /* Do field remapping for this sensor                   */
+#define QUIRK_TERSE_DRIVER     0x08    /* Force duplicate events generation                    */
+#define QUIRK_NOISY            0x10    /* High noise level on readings                         */
+#define QUIRK_FORCE_CONTINUOUS 0x20    /* Force usage of continuous trigger                    */
+#define QUIRK_BIASED           0x40    /* Biased sensor, requires compensation                 */
+#define QUIRK_SPOTTY           0x80    /* Driver may lose events                               */
+#define QUIRK_NO_EVENT_MODE    0x100   /* Disable event mode                                   */
+#define QUIRK_NO_TRIG_MODE     0x200   /* Disable trigger mode                                 */
+#define QUIRK_NO_POLL_MODE     0x400   /* Disable poll mode                                    */
+#define QUIRK_MOUNTING_MATRIX  0x800   /* Mounting information present                         */
+#define QUIRK_HRTIMER          0x1000  /* We may use a hrtimer if there is no other trigger    */
+#define QUIRK_SECONDARY                0x2000  /* List after other sensors of the same type            */
 
 #ifdef __LP64__
        typedef uint64_t        flag_t;
index c8fa34a..041196d 100644 (file)
@@ -975,6 +975,53 @@ static void post_process_sensor_list (char poll_map[catalog_size], char trig_map
 }
 
 
+static void swap_sensors (int s1, int s2)
+{
+       struct sensor_t temp_sensor_desc;
+       sensor_info_t   temp_sensor;
+
+       /* S1 -> temp */
+       memcpy(&temp_sensor, &sensor[s1], sizeof(sensor_info_t));
+       memcpy(&temp_sensor_desc, &sensor_desc[s1], sizeof(struct sensor_t));
+
+       /* S2 -> S1 */
+       memcpy(&sensor[s1], &sensor[s2], sizeof(sensor_info_t));
+       memcpy(&sensor_desc[s1], &sensor_desc[s2], sizeof(struct sensor_t));
+
+       /* temp -> S2 */
+       memcpy(&sensor[s2], &temp_sensor, sizeof(sensor_info_t));
+       memcpy(&sensor_desc[s2], &temp_sensor_desc,  sizeof(struct sensor_t));
+
+       /* Fix-up sensor id mapping, which is stale */
+       sensor_desc[s1].handle  = s1;
+       sensor_desc[s2].handle  = s2;
+
+       /* Fix up name and vendor buffer pointers, which are potentially stale pointers */
+       sensor_desc[s1].name            = sensor_get_name(s1);
+       sensor_desc[s1].vendor          = sensor_get_vendor(s1);
+       sensor_desc[s2].name            = sensor_get_name(s2);
+       sensor_desc[s2].vendor          = sensor_get_vendor(s2);
+}
+
+
+static void reorder_sensors (void)
+{
+       /* Some sensors may be marked as secondary - these need to be listed after other sensors of the same type */
+       int s1, s2;
+
+       for (s1=0; s1<sensor_count-1; s1++)
+               if (sensor[s1].quirks & QUIRK_SECONDARY) {
+                       /* Search for subsequent sensors of same type */
+                       for (s2 = s1+1; s2<sensor_count; s2++)
+                               if (sensor[s2].type == sensor[s1].type && !(sensor[s2].quirks & QUIRK_SECONDARY)) {
+                                       ALOGI("Sensor S%d has higher priority than S%d, swapping\n", s2, s1);
+                                       swap_sensors(s1, s2);
+                                       break;
+                               }
+               }
+}
+
+
 void enumerate_sensors (void)
 {
        /*
@@ -988,6 +1035,7 @@ void enumerate_sensors (void)
        int dev_num;
        unsigned int i;
        int trig_found;
+       int s;
 
        for (dev_num=0; dev_num<MAX_DEVICES; dev_num++) {
                trig_found = 0;
@@ -1019,12 +1067,21 @@ void enumerate_sensors (void)
                        build_sensor_report_maps(dev_num);
        }
 
+       /* Make sure secondary sensors appear after primary ones */
+       reorder_sensors();
+
        ALOGI("Discovered %d sensors\n", sensor_count);
 
        /* Set up default - as well as custom - trigger names */
        setup_trigger_names();
 
+       ALOGI("Discovered %d sensors\n", sensor_count);
+
        virtual_sensors_check();
+
+       for (s=0; s<sensor_count; s++) {
+               ALOGI("S%d: %s\n", s, sensor[s].friendly_name);
+       }
 }