OSDN Git Service

hrtimer sampling frequency must be integral number
[android-x86/hardware-intel-libsensors.git] / control.c
index b8fdeab..bb67530 100644 (file)
--- a/control.c
+++ b/control.c
@@ -21,7 +21,7 @@
 #include "calibration.h"
 #include "description.h"
 #include "filtering.h"
-
+#include <linux/iio/events.h>
 /* Currently active sensors count, per device */
 static int poll_sensors_per_dev[MAX_DEVICES];          /* poll-mode sensors                            */
 static int trig_sensors_per_dev[MAX_DEVICES];          /* trigger, event based                         */
@@ -373,12 +373,16 @@ int adjust_counters (int s, int enabled, int from_virtual)
                ALOGI("Enabling sensor %d (iio device %d: %s)\n", s, dev_num, sensor[s].friendly_name);
 
                switch (sensor[s].type) {
+                       case SENSOR_TYPE_ACCELEROMETER:
+                               accel_cal_init(s);
+                               break;
+
                        case SENSOR_TYPE_MAGNETIC_FIELD:
-                               compass_read_data(&sensor[s]);
+                               compass_read_data(s);
                                break;
 
                        case SENSOR_TYPE_GYROSCOPE:
-                               gyro_cal_init(&sensor[s]);
+                               gyro_cal_init(s);
                                break;
                }
        } else {
@@ -387,11 +391,20 @@ int adjust_counters (int s, int enabled, int from_virtual)
                /* Sensor disabled, lower report available flag */
                sensor[s].report_pending = 0;
 
-               if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
-                       compass_store_data(&sensor[s]);
+               /* Save calibration data to persistent storage */
+               switch (sensor[s].type) {
+                       case SENSOR_TYPE_ACCELEROMETER:
+                               accel_cal_store(s);
+                               break;
+
+                       case SENSOR_TYPE_MAGNETIC_FIELD:
+                               compass_store_data(s);
+                               break;
 
-               if (sensor[s].type == SENSOR_TYPE_GYROSCOPE)
-                       gyro_store_data(&sensor[s]);
+                       case SENSOR_TYPE_GYROSCOPE:
+                               gyro_store_data(s);
+                               break;
+               }
        }
 
        /* We changed the state of a sensor: adjust device ref counts */
@@ -426,6 +439,7 @@ int adjust_counters (int s, int enabled, int from_virtual)
 static int get_field_count (int s, size_t *field_size)
 {
        *field_size = sizeof(float);
+
        switch (sensor[s].type) {
                case SENSOR_TYPE_ACCELEROMETER:         /* m/s^2        */
                case SENSOR_TYPE_MAGNETIC_FIELD:        /* micro-tesla  */
@@ -434,6 +448,8 @@ static int get_field_count (int s, size_t *field_size)
                case SENSOR_TYPE_GYROSCOPE:             /* radians/s    */
                        return 3;
 
+               case SENSOR_TYPE_INTERNAL_INTENSITY:
+               case SENSOR_TYPE_INTERNAL_ILLUMINANCE:
                case SENSOR_TYPE_LIGHT:                 /* SI lux units */
                case SENSOR_TYPE_AMBIENT_TEMPERATURE:   /* °C          */
                case SENSOR_TYPE_TEMPERATURE:           /* °C          */
@@ -520,7 +536,7 @@ static void* acquisition_routine (void* param)
        /* Initialize data fields that will be shared by all sensor reports */
        data.version    = sizeof(sensors_event_t);
        data.sensor     = s;
-       data.type       = sensor[s].type;
+       data.type       = sensor_desc[s].type;
 
        num_fields = get_field_count(s, &field_size);
 
@@ -730,6 +746,8 @@ static int sensor_set_rate (int s, float requested_rate)
        float group_max_sampling_rate;
        float cur_sampling_rate; /* Currently used sampling rate              */
        float arb_sampling_rate; /* Granted sampling rate after arbitration   */
+       char hrtimer_sampling_path[PATH_MAX];
+       char trigger_path[PATH_MAX];
 
        ALOGV("Sampling rate %g requested on sensor %d (%s)\n", requested_rate, s, sensor[s].friendly_name);
 
@@ -789,6 +807,15 @@ static int sensor_set_rate (int s, float requested_rate)
                return -ENOSYS;
        }
 
+       if (sensor[s].hrtimer_trigger_name[0] != '\0') {
+               snprintf(trigger_path, PATH_MAX, "%s%s%d/", IIO_DEVICES, "trigger", sensor[s].trigger_nr);
+               snprintf(hrtimer_sampling_path, PATH_MAX, "%s%s", trigger_path, "sampling_frequency");
+               /* Enforce frequency update when software trigger
+                * frequency and current sampling rate are different */
+               if (sysfs_read_float(hrtimer_sampling_path, &sr) != -1 && sr != cur_sampling_rate)
+                       cur_sampling_rate = -1;
+       }
+
        /* Check if we have contraints on allowed sampling rates */
 
        sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num);
@@ -805,7 +832,7 @@ static int sensor_set_rate (int s, float requested_rate)
                        sr = strtod(cursor, NULL);
 
                        /* If this matches the selected rate, we're happy.  Have some tolerance for rounding errors and avoid needless jumps to higher rates */
-                       if (fabs(arb_sampling_rate - sr) <= 0.001) {
+                       if (fabs(arb_sampling_rate - sr) <= 0.01) {
                                arb_sampling_rate = sr;
                                break;
                        }
@@ -861,6 +888,9 @@ static int sensor_set_rate (int s, float requested_rate)
 
        ALOGI("Sensor %d (%s) sampling rate set to %g\n", s, sensor[s].friendly_name, arb_sampling_rate);
 
+       if (sensor[s].hrtimer_trigger_name[0] != '\0')
+               sysfs_write_float(hrtimer_sampling_path, ceilf(arb_sampling_rate));
+
        if (trig_sensors_per_dev[dev_num])
                enable_buffer(dev_num, 0);
 
@@ -975,7 +1005,11 @@ int sensor_activate (int s, int enabled, int from_virtual)
                if (trig_sensors_per_dev[dev_num]) {
 
                        /* Start sampling */
-                       setup_trigger(s, sensor[s].init_trigger_name);
+                       if (sensor[s].hrtimer_trigger_name[0] != '\0')
+                               setup_trigger(s, sensor[s].hrtimer_trigger_name);
+                       else
+                               setup_trigger(s, sensor[s].init_trigger_name);
+
                        enable_buffer(dev_num, 1);
                }
        } else if (sensor[s].mode == MODE_POLL) {
@@ -1158,8 +1192,12 @@ static void stamp_reports (int dev_num, int64_t ts)
        int s;
 
        for (s=0; s<MAX_SENSORS; s++)
-               if (sensor[s].dev_num == dev_num && is_enabled(s) && sensor[s].mode != MODE_POLL)
-                       set_report_ts(s, ts);
+               if (sensor[s].dev_num == dev_num && is_enabled(s) && sensor[s].mode != MODE_POLL) {
+                       if (sensor[s].quirks & QUIRK_SPOTTY)
+                               set_report_ts(s, ts);
+                       else
+                               sensor[s].report_ts = ts;
+               }
 }
 
 
@@ -1217,7 +1255,6 @@ static int integrate_device_report_from_dev(int dev_num, int fd)
                        sensor[s].report_pending = DATA_TRIGGER;
                        sensor[s].report_initialized = 1;
 
-                       ts_offset += sr_offset;
                }
 
        /* Tentatively switch to an any-motion trigger if conditions are met */
@@ -1287,6 +1324,7 @@ static int integrate_device_report_from_event(int dev_num, int fd)
        for (s = 0; s < MAX_SENSORS; s++)
                if (sensor[s].dev_num == dev_num &&
                    is_enabled(s)) {
+                       sensor[s].event_id = event.id;
                        sensor[s].report_ts = ts;
                        sensor[s].report_pending = 1;
                        sensor[s].report_initialized = 1;
@@ -1323,7 +1361,7 @@ static int propagate_vsensor_report (int s, sensors_event_t *data)
        memcpy(data, &sensor[s].sample, sizeof(sensors_event_t));
 
        data->sensor    = s;
-       data->type      = sensor[s].type;
+       data->type      = sensor_desc[s].type; /* sensor_desc[s].type can differ from sensor[s].type ; internal types are remapped */
        return 1;
 }
 
@@ -1359,13 +1397,25 @@ static int propagate_sensor_report (int s, sensors_event_t *data)
 
        data->version   = sizeof(sensors_event_t);
        data->sensor    = s;
-       data->type      = sensor[s].type;
+       data->type      = sensor_desc[s].type;  /* sensor_desc[s].type can differ from sensor[s].type ; internal types are remapped */
        data->timestamp = sensor[s].report_ts;
 
        if (sensor[s].mode == MODE_EVENT) {
                ALOGV("Reporting event\n");
                /* Android requires events to return 1.0 */
-               data->data[0] = 1.0;
+               int dir = IIO_EVENT_CODE_EXTRACT_DIR(sensor[s].event_id);
+               switch (sensor[s].type) {
+                       case SENSOR_TYPE_PROXIMITY:
+                               if (dir == IIO_EV_DIR_FALLING)
+                                       data->data[0] = 0.0;
+                               else
+                                       data->data[0] = 1.0;
+                               break;
+                       default:
+                               data->data[0] = 1.0;
+                               break;
+
+               }
                data->data[1] = 0.0;
                data->data[2] = 0.0;
                return 1;