X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fhardware-intel-libsensors.git;a=blobdiff_plain;f=transform.c;h=1b688d3385fe4c4ee518304f4305eecee76c20ec;hp=9911bee7d4faf202f2a10ac9aba4d12b3173bf0f;hb=refs%2Fheads%2Foreo-x86;hpb=50085d7944f4bb7d40787ba8bd31a18396778544 diff --git a/transform.c b/transform.c index 9911bee..1b688d3 100644 --- a/transform.c +++ b/transform.c @@ -1,6 +1,18 @@ /* - * Copyright (C) 2014 Intel Corporation. - */ +// Copyright (c) 2015 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ #include #include @@ -13,7 +25,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 */ @@ -41,8 +53,6 @@ #define CONVERT_M_Y (-CONVERT_M) #define CONVERT_M_Z (CONVERT_M) -#define CONVERT_GAUSS_TO_MICROTESLA(x) ((x) * 100) - /* Conversion of orientation data to degree units */ #define CONVERT_O (1.0 / 64) #define CONVERT_O_A (CONVERT_O) @@ -57,6 +67,8 @@ #define BIT(x) (1 << (x)) +#define PROXIMITY_THRESHOLD 1 + inline unsigned int set_bit_range (int start, int end) { int i; @@ -185,6 +197,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 +316,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 +346,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 +365,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 +414,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 +462,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 +539,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 +550,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 +557,18 @@ 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) + if (!ret) { + if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD) + return CONVERT_GAUSS_TO_MICROTESLA (val * correction); 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 +581,46 @@ 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; + 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; +}