#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 */
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.
*/
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)
{
#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;
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]);
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
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)
{
/* 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++;