OSDN Git Service

Add support for IIO mounting_matrix
authorOctavian Purdila <octavian.purdila@intel.com>
Sun, 19 Apr 2015 23:20:16 +0000 (16:20 -0700)
committerAdriana Reus <adriana.reus@intel.com>
Tue, 21 Apr 2015 12:34:57 +0000 (15:34 +0300)
The IIO mounting_matrix attribute offers information about the way the
sensor was mounted on the PCB. This patch reads this information and
uses it to correct the sample data.

Tracked-On: https://jira01.devtools.intel.com/browse/GMINL-8150
Change-Id: I3f60bfc13db1c1e305aa4456eb409db446c43bda
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
common.h
description.c
description.h
enumeration.c
transform.c

index 42d4acd..09788a2 100644 (file)
--- a/common.h
+++ b/common.h
@@ -28,6 +28,7 @@
 #define DEVICE_AVAIL_FREQ_PATH BASE_PATH "sampling_frequency_available"
 #define ILLUMINATION_CALIBPATH BASE_PATH "in_illuminance_calibscale"
 #define SENSOR_CALIB_BIAS_PATH BASE_PATH "in_%s_calibbias"
+#define MOUNTING_MATRIX_PATH   BASE_PATH "mounting_matrix"
 
 #define PROP_BASE              "ro.iio.%s.%s" /* Note: PROPERTY_KEY_MAX is small */
 
@@ -266,6 +267,12 @@ typedef struct
        unsigned char order[MAX_CHANNELS];
 
        /*
+        * If the QUIRK_MOUNTING_MATRIX bit is set in quirks, the contents of this matrix is used to correct the sample values so that it takes
+        * into account the way the sensor has been mounted on the PCB.
+        */
+       float mounting_matrix[9];
+
+       /*
         * Event counter - will be used to check if we have a significant sample for noisy sensors. We want to make sure we do not send any wrong
         * events before filtering kicks in. We can also use it for statistics.
         */
index 39cc725..d2a5874 100644 (file)
@@ -427,6 +427,41 @@ int sensor_get_order (int s, unsigned char map[MAX_CHANNELS])
        return 1;       /* OK to use modified ordering map */
 }
 
+int sensor_get_mounting_matrix (int s, float mm[9])
+{
+       int dev_num = sensor[s].dev_num, err, i;
+       char mm_path[PATH_MAX], mm_buf[100];
+       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;
+       }
+
+       sprintf(mm_path, MOUNTING_MATRIX_PATH, dev_num);
+
+       err = sysfs_read_str(mm_path, mm_buf, sizeof(mm_buf));
+       if (err < 0)
+               return 0;
+
+       for(i = 0; i < 9; i++) {
+               float f;
+
+               f = strtof(tmp1, &tmp2);
+               if (!f && tmp1 == tmp2)
+                       return 0;
+               mm[i] = f;
+               tmp1 = tmp2 + 1;
+       }
+
+       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;
+}
+
 
 char* sensor_get_string_type (int s)
 {
index 3e0a724..e4f0641 100644 (file)
@@ -18,6 +18,7 @@
 #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 */
 
 #ifdef __LP64__
        typedef uint64_t        flag_t;
@@ -41,6 +42,7 @@ uint32_t      sensor_get_quirks       (int s);
 int            sensor_get_prop         (int s, const char* sel, int* val);
 int            sensor_get_fl_prop      (int s, const char* sel, float* val);
 int            sensor_get_order        (int s,unsigned char map[MAX_CHANNELS]);
+int            sensor_get_mounting_matrix(int s,float mounting_matrix[9]);
 int            sensor_get_cal_steps    (int s);
 char*          sensor_get_string_type  (int s);
 int            sensor_get_st_prop      (int s, const char* sel, char val[MAX_NAME_SIZE]);
index 3b674fe..ebcadb9 100644 (file)
@@ -634,8 +634,11 @@ static int add_sensor (int dev_num, int catalog_index, int mode)
                sensor[s].channel[c].raw_path_present = (access(sysfs_path, R_OK) != -1);
        }
 
-       /* Read ACPI _PLD attributes for this sensor, if there are any */
-       decode_placement_information(dev_num, num_channels, s);
+       if (sensor_get_mounting_matrix(s, sensor[s].mounting_matrix))
+               sensor[s].quirks |= QUIRK_MOUNTING_MATRIX;
+       else
+               /* Read ACPI _PLD attributes for this sensor, if there are any */
+               decode_placement_information(dev_num, num_channels, s);
 
        /*
         * See if we have optional correction scaling factors for each of the
index eaf0faf..fd356fc 100644 (file)
@@ -187,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)
 {
@@ -295,6 +306,8 @@ 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++;