OSDN Git Service

iio_sensors: Add Light sensor sysfs interface and transformation
[android-x86/hardware-intel-libsensors.git] / enumeration.c
index fc68760..d72b023 100644 (file)
@@ -8,6 +8,9 @@
 #include "enumeration.h"
 #include "description.h"
 #include "utils.h"
+#include "transform.h"
+#include "description.h"
+#include "control.h"
 
 /*
  * This table maps syfs entries in scan_elements directories to sensor types,
@@ -19,12 +22,12 @@ struct sensor_catalog_entry_t sensor_catalog[] = {
        DECLARE_SENSOR3("accel",      SENSOR_TYPE_ACCELEROMETER,  "x", "y", "z")
        DECLARE_SENSOR3("anglvel",    SENSOR_TYPE_GYROSCOPE,      "x", "y", "z")
        DECLARE_SENSOR3("magn",       SENSOR_TYPE_MAGNETIC_FIELD, "x", "y", "z")
+       DECLARE_SENSOR1("intensity",  SENSOR_TYPE_LIGHT,          "both"       )
        DECLARE_SENSOR0("illuminance",SENSOR_TYPE_LIGHT                        )
        DECLARE_SENSOR3("incli",      SENSOR_TYPE_ORIENTATION,    "x", "y", "z")
        DECLARE_SENSOR4("rot",        SENSOR_TYPE_ROTATION_VECTOR,
                                         "quat_x", "quat_y", "quat_z", "quat_w")
-       DECLARE_SENSOR0("temp",       SENSOR_TYPE_TEMPERATURE                  )
-       DECLARE_SENSOR0("timestamp",  SENSOR_TYPE_DEVICE_PRIVATE_BASE          )
+       DECLARE_SENSOR0("temp",       SENSOR_TYPE_AMBIENT_TEMPERATURE          )
 };
 
 #define CATALOG_SIZE   ARRAY_SIZE(sensor_catalog)
@@ -41,9 +44,15 @@ static void add_sensor (int dev_num, int catalog_index, int use_polling)
 {
        int s;
        int sensor_type;
+       int retval;
        char sysfs_path[PATH_MAX];
        const char* prefix;
         float scale;
+       int c;
+       float opt_scale;
+       const char* ch_name;
+       int num_channels;
+       char suffix[MAX_NAME_SIZE + 8];
 
        if (sensor_count == MAX_SENSORS) {
                ALOGE("Too many sensors!\n");
@@ -71,18 +80,75 @@ static void add_sensor (int dev_num, int catalog_index, int use_polling)
 
        prefix = sensor_catalog[catalog_index].tag;
 
+       /*
+        * receiving the illumination sensor calibration inputs from
+        * the Android properties and setting it within sysfs
+        */
+       if (sensor_catalog[catalog_index].type == SENSOR_TYPE_LIGHT) {
+               retval = sensor_get_illumincalib(s);
+               sprintf(sysfs_path, ILLUMINATION_CALIBPATH, dev_num);
+               sysfs_write_int(sysfs_path, retval);
+       }
+
        /* Read name attribute, if available */
        sprintf(sysfs_path, NAME_PATH, dev_num);
        sysfs_read_str(sysfs_path, sensor_info[s].internal_name, MAX_NAME_SIZE);
 
        /* See if we have general offsets and scale values for this sensor */
 
-       sprintf(sysfs_path, COMMON_OFFSET_PATH, dev_num, prefix);
+       sprintf(sysfs_path, SENSOR_OFFSET_PATH, dev_num, prefix);
        sysfs_read_float(sysfs_path, &sensor_info[s].offset);
 
-       sprintf(sysfs_path, COMMON_SCALE_PATH, dev_num, prefix);
-       if (!sysfs_read_float(sysfs_path, &scale))
+       sprintf(sysfs_path, SENSOR_SCALE_PATH, dev_num, prefix);
+       if (!sysfs_read_float(sysfs_path, &scale)) {
                 sensor_info[s].scale = scale;
+               ALOGI("Scale path:%s scale:%f dev_num:%d\n",
+                                        sysfs_path, scale, dev_num);
+       } else {
+                sensor_info[s].scale = 1;
+
+                /* Read channel specific scale if any*/
+                for (c = 0; c < sensor_catalog[catalog_index].num_channels; c++)
+                {
+                        sprintf(sysfs_path, BASE_PATH "%s", dev_num,
+                           sensor_catalog[catalog_index].channel[c].scale_path);
+
+                        if (!sysfs_read_float(sysfs_path, &scale)) {
+                                sensor_info[s].channel[c].scale = scale;
+                               sensor_info[s].scale = 0;
+
+                               ALOGI(  "Scale path:%s "
+                                       "channel scale:%f dev_num:%d\n",
+                                        sysfs_path, scale, dev_num);
+                        }
+                }
+        }
+
+        /*
+         * See if we have optional correction scaling factors for each of the
+         * channels of this sensor. These would be expressed using properties
+         * like iio.accel.y.scale = -1. In case of a single channel we also
+         * support things such as iio.temp.scale = -1. Note that this works
+         * for all types of sensors, and whatever transform is selected, on top
+         * of any previous conversions.
+         */
+        num_channels = sensor_catalog[catalog_index].num_channels;
+
+        if (num_channels) {
+               for (c = 0; c < num_channels; c++) {
+                       opt_scale = 1;
+
+                       ch_name = sensor_catalog[catalog_index].channel[c].name;
+                       sprintf(suffix, "%s.scale", ch_name);
+                       sensor_get_fl_prop(s, suffix, &opt_scale);
+
+                       sensor_info[s].channel[c].opt_scale = opt_scale;
+               }
+        } else {
+               opt_scale = 1;
+               sensor_get_fl_prop(s, "scale", &opt_scale);
+               sensor_info[s].channel[0].opt_scale = opt_scale;
+        }
 
        /* Initialize Android-visible descriptor */
        sensor_desc[s].name             = sensor_get_name(s);
@@ -104,6 +170,9 @@ static void add_sensor (int dev_num, int catalog_index, int use_polling)
                strcpy(sensor_info[s].internal_name, "(null)");
        }
 
+       /* Select one of the available sensor sample processing styles */
+       select_transform(s);
+
        sensor_count++;
 }
 
@@ -187,6 +256,55 @@ static void discover_trig_sensors (int dev_num, char map[CATALOG_SIZE])
 }
 
 
+static void orientation_sensor_check(void)
+{
+       /*
+        * If we have accel + gyro + magn but no rotation vector sensor,
+        * SensorService replaces the HAL provided orientation sensor by the
+        * AOSP version... provided we report one. So initialize a virtual
+        * orientation sensor with zero values, which will get replaced. See:
+        * frameworks/native/services/sensorservice/SensorService.cpp, looking
+        * for SENSOR_TYPE_ROTATION_VECTOR; that code should presumably fall
+        * back to mUserSensorList.add instead of replaceAt, but accommodate it.
+        */
+
+       int i;
+       int has_acc = 0;
+       int has_gyr = 0;
+       int has_mag = 0;
+       int has_rot = 0;
+       int has_ori = 0;
+       int catalog_size = CATALOG_SIZE;
+
+       for (i=0; i<sensor_count; i++)
+               switch (sensor_catalog[sensor_info[i].catalog_index].type) {
+                       case SENSOR_TYPE_ACCELEROMETER:
+                               has_acc = 1;
+                               break;
+                       case SENSOR_TYPE_GYROSCOPE:
+                               has_gyr = 1;
+                               break;
+                       case SENSOR_TYPE_MAGNETIC_FIELD:
+                               has_mag = 1;
+                               break;
+                       case SENSOR_TYPE_ORIENTATION:
+                               has_ori = 1;
+                               break;
+                       case SENSOR_TYPE_ROTATION_VECTOR:
+                               has_rot = 1;
+                               break;
+               }
+
+       if (has_acc && has_gyr && has_mag && !has_rot && !has_ori)
+               for (i=0; i<catalog_size; i++)
+                       if (sensor_catalog[i].type == SENSOR_TYPE_ORIENTATION) {
+                               ALOGI("Adding placeholder orientation sensor");
+                               add_sensor(0, i, 1);
+                               break;
+                       }
+}
+
+
 void enumerate_sensors (void)
 {
        /*
@@ -200,20 +318,31 @@ void enumerate_sensors (void)
        char trig_sensors[CATALOG_SIZE];
        int dev_num;
        unsigned int i;
+       int trig_found;
 
        for (dev_num=0; dev_num<MAX_DEVICES; dev_num++) {
+               trig_found = 0;
+
                discover_poll_sensors(dev_num, poll_sensors);
                discover_trig_sensors(dev_num, trig_sensors);
 
                for (i=0; i<CATALOG_SIZE; i++)
-                       if (trig_sensors[i])
+                       if (trig_sensors[i]) {
                                add_sensor(dev_num, i, 0);
+                               trig_found = 1;
+                       }
                        else
                                if (poll_sensors[i])
                                        add_sensor(dev_num, i, 1);
+
+               if (trig_found)
+                       build_sensor_report_maps(dev_num);
        }
 
        ALOGI("Discovered %d sensors\n", sensor_count);
+
+       /* Make sure Android fall backs to its own orientation sensor */
+       orientation_sensor_check();
 }