OSDN Git Service

Enable Gauss-2-uT conversion for interrupt mode magneto
[android-x86/hardware-intel-libsensors.git] / transform.c
index 9911bee..7aee50d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Intel Corporation.
+ * Copyright (C) 2014-2015 Intel Corporation.
  */
 
 #include <stdlib.h>
@@ -13,7 +13,7 @@
 #include "transform.h"
 #include "utils.h"
 #include "filtering.h"
-
+#include "enumeration.h"
 
 #define        GYRO_MIN_SAMPLES 5 /* Drop first few gyro samples after enable */
 
@@ -57,6 +57,8 @@
 
 #define BIT(x) (1 << (x))
 
+#define PROXIMITY_THRESHOLD 1
+
 inline unsigned int set_bit_range (int start, int end)
 {
        int i;
@@ -185,6 +187,17 @@ static void reorder_fields (float* data, unsigned char map[MAX_CHANNELS])
                data[i] = temp[i];
 }
 
+static void mount_correction (float* data, float mm[9])
+{
+       int i;
+       float temp[3];
+
+       for (i=0; i<3; i++)
+               temp[i] = data[0] * mm[i * 3] + data[1] * mm[i * 3 + 1] + data[2] * mm[i * 3 + 2];
+
+       for (i=0; i<3; i++)
+               data[i] = temp[i];
+}
 
 static void clamp_gyro_readings_to_zero (int s, sensors_event_t* data)
 {
@@ -293,20 +306,23 @@ static int finalize_sample_default (int s, sensors_event_t* data)
        /* Swap fields if we have a custom channel ordering on this sensor */
        if (sensor[s].quirks & QUIRK_FIELD_ORDERING)
                reorder_fields(data->data, sensor[s].order);
+       if (sensor[s].quirks & QUIRK_MOUNTING_MATRIX)
+               mount_correction(data->data, sensor[s].mounting_matrix);
 
        sensor[s].event_count++;
+
        switch (sensor[s].type) {
                case SENSOR_TYPE_ACCELEROMETER:
                        /* Always consider the accelerometer accurate */
                        data->acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
-                       if (sensor[s].quirks & QUIRK_NOISY)
-                               denoise(s, data);
+                       if (sensor[s].quirks & QUIRK_BIASED)
+                               calibrate_accel(s, data);
+                       denoise(s, data);
                        break;
 
                case SENSOR_TYPE_MAGNETIC_FIELD:
-                       calibrate_compass (data, &sensor[s]);
-                       if (sensor[s].quirks & QUIRK_NOISY)
-                               denoise(s, data);
+                       calibrate_compass (s, data);
+                       denoise(s, data);
                        break;
 
                case SENSOR_TYPE_GYROSCOPE:
@@ -320,13 +336,13 @@ static int finalize_sample_default (int s, sensors_event_t* data)
                         */
                        if (sensor[s].selected_trigger !=
                                sensor[s].motion_trigger_name)
-                                       calibrate_gyro(data, &sensor[s]);
+                                       calibrate_gyro(s, data);
 
                        /*
                         * For noisy sensors drop a few samples to make sure we have at least GYRO_MIN_SAMPLES events in the
                         * filtering queue. This improves mean and std dev.
                         */
-                       if (sensor[s].quirks & QUIRK_NOISY) {
+                       if (sensor[s].filter_type) {
                                if (sensor[s].selected_trigger !=
                                    sensor[s].motion_trigger_name &&
                                    sensor[s].event_count < GYRO_MIN_SAMPLES)
@@ -339,21 +355,37 @@ static int finalize_sample_default (int s, sensors_event_t* data)
                        clamp_gyro_readings_to_zero(s, data);
                        break;
 
+               case SENSOR_TYPE_PROXIMITY:
+                       /*
+                        * See iio spec for in_proximity* - depending on the device
+                        * this value is either in meters either unit-less and cannot
+                        * be translated to SI units. Where the translation is not possible
+                        * lower values indicate something is close and higher ones indicate distance.
+                        */
+                       if (data->data[0] > PROXIMITY_THRESHOLD)
+                               data->data[0] = PROXIMITY_THRESHOLD;
+
+                       /* ... fall through ... */
                case SENSOR_TYPE_LIGHT:
                case SENSOR_TYPE_AMBIENT_TEMPERATURE:
                case SENSOR_TYPE_TEMPERATURE:
+               case SENSOR_TYPE_INTERNAL_ILLUMINANCE:
+               case SENSOR_TYPE_INTERNAL_INTENSITY:
                        /* Only keep two decimals for these readings */
                        data->data[0] = 0.01 * ((int) (data->data[0] * 100));
 
-                       /* ... fall through ... */
-
-               case SENSOR_TYPE_PROXIMITY:
                        /* These are on change sensors ; drop the sample if it has the same value as the previously reported one. */
-                       if (data->data[0] == sensor[s].prev_val)
+                       if (data->data[0] == sensor[s].prev_val.data)
                                return 0;
 
-                       sensor[s].prev_val = data->data[0];
+                       sensor[s].prev_val.data = data->data[0];
                        break;
+               case SENSOR_TYPE_STEP_COUNTER:
+                       if (data->u64.step_counter == sensor[s].prev_val.data64)
+                               return 0;
+                       sensor[s].prev_val.data64 = data->u64.data[0];
+                       break;
+
        }
 
        /* If there are active virtual sensors depending on this one - process the event */
@@ -372,10 +404,14 @@ static float transform_sample_default (int s, int c, unsigned char* sample_data)
        float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale;
 
        /* In case correction has been requested using properties, apply it */
-       scale *= sensor[s].channel[c].opt_scale;
+       float correction = sensor[s].channel[c].opt_scale;
+
+       /* Correlated with "acquire_immediate_value" method */
+       if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
+                return CONVERT_GAUSS_TO_MICROTESLA((sensor[s].offset + s64) * scale) * correction;
 
        /* Apply default scaling rules */
-       return (sensor[s].offset + s64) * scale;
+       return (sensor[s].offset + s64) * scale * correction;
 }
 
 
@@ -416,7 +452,7 @@ static float transform_sample_ISH (int s, int c, unsigned char* sample_data)
        /* In case correction has been requested using properties, apply it */
        correction = sensor[s].channel[c].opt_scale;
 
-       switch (sensor[s].type) {
+       switch (sensor_desc[s].type) {
                case SENSOR_TYPE_ACCELEROMETER:
                        switch (c) {
                                case 0:
@@ -493,7 +529,7 @@ void select_transform (int s)
 }
 
 
-float acquire_immediate_value (int s, int c)
+float acquire_immediate_float_value (int s, int c)
 {
        char sysfs_path[PATH_MAX];
        float val;
@@ -504,7 +540,6 @@ float acquire_immediate_value (int s, int c)
        const char* input_path = sensor_catalog[i].channel[c].input_path;
        float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale;
        float offset = sensor[s].offset;
-       int sensor_type = sensor_catalog[i].type;
        float correction;
 
        /* In case correction has been requested using properties, apply it */
@@ -512,15 +547,15 @@ float acquire_immediate_value (int s, int c)
 
        /* Acquire a sample value for sensor s / channel c through sysfs */
 
-       if (input_path[0]) {
+       if (sensor[s].channel[c].input_path_present) {
                sprintf(sysfs_path, BASE_PATH "%s", dev_num, input_path);
                ret = sysfs_read_float(sysfs_path, &val);
 
                if (!ret)
                        return val * correction;
-       };
+       }
 
-       if (!raw_path[0])
+       if (!sensor[s].channel[c].raw_path_present)
                return 0;
 
        sprintf(sysfs_path, BASE_PATH "%s", dev_num, raw_path);
@@ -533,8 +568,47 @@ float acquire_immediate_value (int s, int c)
         * There is no transform ops defined yet for raw sysfs values.
          * Use this function to perform transformation as well.
         */
-       if (sensor_type == SENSOR_TYPE_MAGNETIC_FIELD)
+       if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
                 return CONVERT_GAUSS_TO_MICROTESLA ((val + offset) * scale) * correction;
 
        return (val + offset) * scale * correction;
 }
+
+uint64_t acquire_immediate_uint64_value (int s, int c)
+{
+       char sysfs_path[PATH_MAX];
+       uint64_t val;
+       int ret;
+       int dev_num = sensor[s].dev_num;
+       int i = sensor[s].catalog_index;
+       const char* raw_path = sensor_catalog[i].channel[c].raw_path;
+       const char* input_path = sensor_catalog[i].channel[c].input_path;
+       float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale;
+       float offset = sensor[s].offset;
+       int sensor_type = sensor_catalog[i].type;
+       float correction;
+
+       /* In case correction has been requested using properties, apply it */
+       correction = sensor[s].channel[c].opt_scale;
+
+       /* Acquire a sample value for sensor s / channel c through sysfs */
+
+       if (sensor[s].channel[c].input_path_present) {
+               sprintf(sysfs_path, BASE_PATH "%s", dev_num, input_path);
+               ret = sysfs_read_uint64(sysfs_path, &val);
+
+               if (!ret)
+                       return val * correction;
+       };
+
+       if (!sensor[s].channel[c].raw_path_present)
+               return 0;
+
+       sprintf(sysfs_path, BASE_PATH "%s", dev_num, raw_path);
+       ret = sysfs_read_uint64(sysfs_path, &val);
+
+       if (ret == -1)
+               return 0;
+
+       return (val + offset) * scale * correction;
+}