OSDN Git Service

Allow for a slight difference when parsing available frequencies
[android-x86/hardware-intel-libsensors.git] / control.c
index 12d118b..14f5570 100644 (file)
--- a/control.c
+++ b/control.c
@@ -7,6 +7,7 @@
 #include <fcntl.h>
 #include <pthread.h>
 #include <time.h>
+#include <math.h>
 #include <sys/epoll.h>
 #include <sys/socket.h>
 #include <utils/Log.h>
@@ -41,44 +42,46 @@ static pthread_mutex_t    thread_release_mutex      [MAX_SENSORS];
  * - a iio device number if the fd is a iio character device fd
  * - THREAD_REPORT_TAG_BASE + sensor handle if the fd is the receiving end of a
  *   pipe used by a sysfs data acquisition thread
- *  */
+ */
 #define THREAD_REPORT_TAG_BASE 0x00010000
 
 #define ENABLE_BUFFER_RETRIES 10
 #define ENABLE_BUFFER_RETRY_DELAY_MS 10
 
-inline int is_enabled(int s)
+
+inline int is_enabled (int s)
 {
-       return (sensor[s].directly_enabled || sensor[s].ref_count);
+       return sensor[s].directly_enabled || sensor[s].ref_count;
 }
 
-static int check_state_change(int s, int enabled, int from_virtual)
+
+static int check_state_change (int s, int enabled, int from_virtual)
 {
-       if(enabled) {
+       if (enabled) {
                if (sensor[s].directly_enabled)
-                       return 0;
+                                       /*
+                                        * We're being enabled but already were
+                                        * directly activated: no change.
+                                        */
+                                       return 0;
 
-               /* If we were enabled by Android no sample drops */
                if (!from_virtual)
+                       /* We're being directly enabled */
                        sensor[s].directly_enabled = 1;
 
-               /*
-               * If we got here it means we were not previously directly enabled - we may
-               * or may not be now, whatever the case if we already had references we
-               * were already in use
-               */
                if (sensor[s].ref_count)
+                       /* We were already indirectly enabled */
                        return 0;
 
-               return 1;
-
+               return 1; /* Do continue enabling this sensor */
        }
-       /* Spurious disable call */
+
        if (!is_enabled(s))
+               /* We are being disabled but already were: no change */
                return 0;
 
-       /* We're requesting disable for a virtual sensor but the base is still active */
        if (from_virtual && sensor[s].directly_enabled)
+               /* We're indirectly disabled but the base is still active */
                return 0;
 
        /* If it's disable, and it's from Android, and we still have ref counts */
@@ -90,8 +93,10 @@ static int check_state_change(int s, int enabled, int from_virtual)
        /*If perhaps we are from virtual but we're disabling it*/
        sensor[s].directly_enabled = 0;
 
-       return 1;
+       return 1; /* Do continue disabling this sensor */
 }
+
+
 static int enable_buffer(int dev_num, int enabled)
 {
        char sysfs_path[PATH_MAX];
@@ -385,7 +390,6 @@ int adjust_counters (int s, int enabled, int from_virtual)
 {
        /*
         * Adjust counters based on sensor enable action. Return values are:
-        * -1 if there's an inconsistency: abort action in this case
         *  0 if the operation was completed and we're all set
         *  1 if we toggled the state of the sensor and there's work left
         */
@@ -393,6 +397,7 @@ int adjust_counters (int s, int enabled, int from_virtual)
        int dev_num = sensor[s].dev_num;
 
        if (!check_state_change(s, enabled, from_virtual))
+               /* The state of the sensor remains the same: we're done */
                return 0;
 
        if (enabled) {
@@ -418,12 +423,12 @@ int adjust_counters (int s, int enabled, int from_virtual)
                if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
                        compass_store_data(&sensor[s]);
 
-               if(sensor[s].type == SENSOR_TYPE_GYROSCOPE)
+               if (sensor[s].type == SENSOR_TYPE_GYROSCOPE)
                        gyro_store_data(&sensor[s]);
        }
 
-       /* We changed the state of a sensor - adjust per iio device counters */
-       /* If this is a regular event-driven sensor */
+       /* We changed the state of a sensor: adjust device ref counts */
+
        if (sensor[s].num_channels) {
 
                        if (enabled)
@@ -432,7 +437,7 @@ int adjust_counters (int s, int enabled, int from_virtual)
                                trig_sensors_per_dev[dev_num]--;
 
                        return 1;
-               }
+       }
 
        if (enabled) {
                active_poll_sensors++;
@@ -465,7 +470,7 @@ static int get_field_count (int s)
                        return 1;
 
                case SENSOR_TYPE_ROTATION_VECTOR:
-                       return  4;
+                       return 4;
 
                default:
                        ALOGE("Unknown sensor type!\n");
@@ -498,11 +503,11 @@ static void* acquisition_routine (void* param)
                return NULL;
        }
 
-       ALOGI("Entering data acquisition thread S%d (%s): rate(%f), ts(%lld)\n", s,
-               sensor[s].friendly_name, sensor[s].sampling_rate, sensor[s].report_ts);
+       ALOGI("Entering data acquisition thread S%d (%s), rate:%g\n",
+             s, sensor[s].friendly_name, sensor[s].sampling_rate);
 
        if (sensor[s].sampling_rate <= 0) {
-               ALOGE("Non-positive rate in acquisition routine for sensor %d: %f\n",
+               ALOGE("Invalid rate in acquisition routine for sensor %d: %g\n",
                        s, sensor[s].sampling_rate);
                return NULL;
        }
@@ -542,8 +547,8 @@ static void* acquisition_routine (void* param)
                                        &data.timestamp, sample_size);
 
                        if (ret != sample_size)
-                               ALOGE("S%d acquisition thread: tried to write %d, ret: %d\n",
-                                       s, sample_size, ret);
+                               ALOGE("S%d write failure: wrote %d, got %d\n",
+                                     s, sample_size, ret);
                }
 
                /* Check and honor termination requests */
@@ -553,7 +558,7 @@ static void* acquisition_routine (void* param)
                /* Recalculate period asumming sensor[s].sampling_rate
                 * can be changed dynamically during the thread run */
                if (sensor[s].sampling_rate <= 0) {
-                       ALOGE("Non-positive rate in acquisition routine for sensor %d: %f\n",
+                       ALOGE("Unexpected sampling rate for sensor %d: %g\n",
                                s, sensor[s].sampling_rate);
                        goto exit;
                }
@@ -643,7 +648,8 @@ static void stop_acquisition_thread (int s)
        pthread_mutex_destroy(&thread_release_mutex[s]);
 }
 
-static void sensor_activate_virtual(int s, int enabled, int from_virtual)
+
+static void sensor_activate_virtual (int s, int enabled, int from_virtual)
 {
        int i, base;
 
@@ -655,7 +661,7 @@ static void sensor_activate_virtual(int s, int enabled, int from_virtual)
        if (enabled) {
                /* Enable all the base sensors for this virtual one */
                for (i = 0; i < sensor[s].base_count; i++) {
-                       base = sensor[s].base_idx[i];
+                       base = sensor[s].base[i];
                        sensor_activate(base, enabled, 1);
                        sensor[base].ref_count++;
                }
@@ -666,7 +672,7 @@ static void sensor_activate_virtual(int s, int enabled, int from_virtual)
        sensor[s].report_pending = 0;
 
        for (i = 0; i < sensor[s].base_count; i++) {
-               base = sensor[s].base_idx[i];
+               base = sensor[s].base[i];
                sensor_activate(base, enabled, 1);
                sensor[base].ref_count--;
        }
@@ -692,6 +698,7 @@ static int is_fast_accelerometer (int s)
        return 1;
 }
 
+
 static void tentative_switch_trigger (int s)
 {
        /*
@@ -710,15 +717,14 @@ static void tentative_switch_trigger (int s)
                setup_trigger(s, sensor[s].init_trigger_name);
 }
 
-static int setup_delay_sysfs(int s, float new_sampling_rate)
+
+static int setup_delay_sysfs (int s, float requested_rate)
 {
        /* Set the rate at which a specific sensor should report events */
-
        /* See Android sensors.h for indication on sensor trigger modes */
 
        char sysfs_path[PATH_MAX];
        char avail_sysfs_path[PATH_MAX];
-       float cur_sampling_rate; /* Currently used sampling rate              */
        int dev_num             =       sensor[s].dev_num;
        int i                   =       sensor[s].catalog_index;
        const char *prefix      =       sensor_catalog[i].tag;
@@ -726,27 +732,42 @@ static int setup_delay_sysfs(int s, float new_sampling_rate)
        int per_device_sampling_rate;
        int32_t min_delay_us = sensor_desc[s].minDelay;
        max_delay_t max_delay_us = sensor_desc[s].maxDelay;
-       float min_supported_rate = max_delay_us ? (1000000.0 / max_delay_us) : 1;
+       float min_supported_rate = max_delay_us ? 1000000.0/max_delay_us : 1;
        float max_supported_rate =
-               (min_delay_us && min_delay_us != -1) ? (1000000.0 / min_delay_us) : 0;
+               min_delay_us && min_delay_us != -1 ? 1000000.0/min_delay_us : 0;
        char freqs_buf[100];
        char* cursor;
        int n;
        float sr;
+       float cur_sampling_rate; /* Currently used sampling rate              */
+       float arb_sampling_rate; /* Granted sampling rate after arbitration   */
 
-       if (new_sampling_rate < min_supported_rate)
-               new_sampling_rate = min_supported_rate;
+       ALOGV("Sampling rate %g requested on sensor %d (%s)\n", requested_rate,
+             s, sensor[s].friendly_name);
 
-       if (max_supported_rate &&
-               new_sampling_rate > max_supported_rate) {
-               new_sampling_rate = max_supported_rate;
+       sensor[s].requested_rate = requested_rate;
+
+       arb_sampling_rate = requested_rate;
+
+       if (arb_sampling_rate < min_supported_rate) {
+               ALOGV("Sampling rate %g too low for %s, using %g instead\n",
+                      arb_sampling_rate, sensor[s].friendly_name,
+                      min_supported_rate);
+
+               arb_sampling_rate = min_supported_rate;
        }
 
-       sensor[s].sampling_rate = new_sampling_rate;
+       if (max_supported_rate && arb_sampling_rate > max_supported_rate) {
+               ALOGV("Sampling rate %g too high for %s, using %g instead\n",
+               arb_sampling_rate, sensor[s].friendly_name, max_supported_rate);
+               arb_sampling_rate = max_supported_rate;
+       }
+
+       sensor[s].sampling_rate = arb_sampling_rate;
 
        /* If we're dealing with a poll-mode sensor */
        if (!sensor[s].num_channels) {
-               /* Interrupt current sleep so the new sampling gets used */
+               /* Wake up thread so the new sampling rate gets used */
                pthread_cond_signal(&thread_release_cond[s]);
                return 0;
        }
@@ -778,8 +799,8 @@ static int setup_delay_sysfs(int s, float new_sampling_rate)
                        if (n != s && sensor[n].dev_num == dev_num &&
                            sensor[n].num_channels &&
                            is_enabled(s) &&
-                           sensor[n].sampling_rate > new_sampling_rate)
-                               new_sampling_rate= sensor[n].sampling_rate;
+                           sensor[n].sampling_rate > arb_sampling_rate)
+                               arb_sampling_rate = sensor[n].sampling_rate;
 
        /* Check if we have contraints on allowed sampling rates */
 
@@ -796,9 +817,15 @@ static int setup_delay_sysfs(int s, float new_sampling_rate)
                        /* Decode a single value */
                        sr = strtod(cursor, NULL);
 
-                       /* If this matches the selected rate, we're happy */
-                       if (new_sampling_rate == sr)
+                       /*
+                        * If this matches the selected rate, we're happy.
+                        * Have some tolerance to counter rounding errors and
+                        * avoid needless jumps to higher rates.
+                        */
+                       if (fabs(arb_sampling_rate - sr) <= 0.001) {
+                               arb_sampling_rate = sr;
                                break;
+                       }
 
                        /*
                         * If we reached a higher value than the desired rate,
@@ -807,8 +834,8 @@ static int setup_delay_sysfs(int s, float new_sampling_rate)
                         * assumption that rates are sorted by increasing value
                         * in the allowed frequencies string.
                         */
-                       if (sr > new_sampling_rate) {
-                               new_sampling_rate = sr;
+                       if (sr > arb_sampling_rate) {
+                               arb_sampling_rate = sr;
                                break;
                        }
 
@@ -823,20 +850,21 @@ static int setup_delay_sysfs(int s, float new_sampling_rate)
        }
 
        if (max_supported_rate &&
-               new_sampling_rate > max_supported_rate) {
-               new_sampling_rate = max_supported_rate;
+               arb_sampling_rate > max_supported_rate) {
+               arb_sampling_rate = max_supported_rate;
        }
 
        /* If the desired rate is already active we're all set */
-       if (new_sampling_rate == cur_sampling_rate)
+       if (arb_sampling_rate == cur_sampling_rate)
                return 0;
 
-       ALOGI("Sensor %d sampling rate set to %g\n", s, new_sampling_rate);
+       ALOGI("Sensor %d (%s) sampling rate set to %g\n",
+             s, sensor[s].friendly_name, arb_sampling_rate);
 
        if (trig_sensors_per_dev[dev_num])
                enable_buffer(dev_num, 0);
 
-       sysfs_write_float(sysfs_path, new_sampling_rate);
+       sysfs_write_float(sysfs_path, arb_sampling_rate);
 
        /* Check if it makes sense to use an alternate trigger */
        tentative_switch_trigger(s);
@@ -846,6 +874,8 @@ static int setup_delay_sysfs(int s, float new_sampling_rate)
 
        return 0;
 }
+
+
 /*
  * We go through all the virtual sensors of the base - and the base itself
  * in order to recompute the maximum requested delay of the group and setup the base
@@ -863,7 +893,7 @@ static int arbitrate_bases (int s)
         for (i = 0; i < sensor_count; i++) {
                        for (vidx = 0; vidx < sensor[i].base_count; vidx++)
                        /* If we have a virtual sensor depending on this one - handle it */
-                               if (sensor[i].base_idx[vidx] == s &&
+                               if (sensor[i].base[vidx] == s &&
                                        sensor[i].directly_enabled &&
                                        sensor[i].requested_rate > arbitrated_rate)
                                                arbitrated_rate = sensor[i].requested_rate;
@@ -872,10 +902,11 @@ static int arbitrate_bases (int s)
        return setup_delay_sysfs(s, arbitrated_rate);
 }
 
+
 /*
  * Re-assesment for delays. We need to re-asses delays for all related groups
  * of sensors everytime a sensor enables / disables / changes frequency.
-*/
+ */
 int arbitrate_delays (int s)
 {
        int i;
@@ -885,11 +916,13 @@ int arbitrate_delays (int s)
        }
        /* Is virtual sensor - go through bases */
        for (i = 0; i < sensor[s].base_count; i++)
-               arbitrate_bases(sensor[s].base_idx[i]);
+               arbitrate_bases(sensor[s].base[i]);
 
        return 0;
 }
-int sensor_activate(int s, int enabled, int from_virtual)
+
+
+int sensor_activate (int s, int enabled, int from_virtual)
 {
        char device_name[PATH_MAX];
        struct epoll_event ev = {0};
@@ -906,6 +939,7 @@ int sensor_activate(int s, int enabled, int from_virtual)
 
        /* Prepare the report timestamp field for the first event, see set_report_ts method */
        sensor[s].report_ts = 0;
+
        ret = adjust_counters(s, enabled, from_virtual);
 
        /* If the operation was neutral in terms of state, we're done */
@@ -1075,7 +1109,9 @@ static void enable_motion_trigger (int dev_num)
        enable_buffer(dev_num, 1);
 }
 
-/* CTS acceptable thresholds:
+
+/*
+ *  CTS acceptable thresholds:
  *     EventGapVerification.java: (th <= 1.8)
  *     FrequencyVerification.java: (0.9)*(expected freq) => (th <= 1.1111)
  */
@@ -1227,6 +1263,7 @@ static int integrate_device_report (int dev_num)
        return 0;
 }
 
+
 static int propagate_vsensor_report (int s, struct sensors_event_t  *data)
 {
        /* There's a new report stored in sensor.sample for this sensor; transmit it */
@@ -1238,6 +1275,7 @@ static int propagate_vsensor_report (int s, struct sensors_event_t  *data)
        return 1;
 }
 
+
 static int propagate_sensor_report (int s, struct sensors_event_t  *data)
 {
        /* There's a sensor report pending for this sensor ; transmit it */
@@ -1409,7 +1447,7 @@ static int get_poll_wait_timeout (void)
 }
 
 
-int sensor_poll(struct sensors_event_t* data, int count)
+int sensor_poll (struct sensors_event_t* data, int count)
 {
        int s;
        int i;
@@ -1499,26 +1537,28 @@ await_event:
        goto return_available_sensor_reports;
 }
 
-int sensor_set_delay(int s, int64_t ns)
+
+int sensor_set_delay (int s, int64_t ns)
 {
-       float new_sampling_rate; /* Granted sampling rate after arbitration   */
+       float requested_sampling_rate;
 
        if (ns <= 0) {
-               ALOGE("Rejecting non-positive delay request on sensor %d,required delay: %lld\n", s, ns);
+               ALOGE("Invalid delay requested on sensor %d: %lld\n", s, ns);
                return -EINVAL;
        }
 
-       new_sampling_rate = 1000000000LL/ns;
+       requested_sampling_rate = 1000000000.0/ns;
 
-       ALOGV("Entering set delay S%d (%s): old rate(%f), new rate(%f)\n",
+       ALOGV("Entering set delay S%d (%s): current rate: %f, requested: %f\n",
                s, sensor[s].friendly_name, sensor[s].sampling_rate,
-               new_sampling_rate);
+               requested_sampling_rate);
 
-       sensor[s].requested_rate = new_sampling_rate;
+       sensor[s].requested_rate = requested_sampling_rate;
 
        return arbitrate_delays(s);
 }
 
+
 int sensor_flush (int s)
 {
        /* If one shot or not enabled return -EINVAL */
@@ -1529,6 +1569,7 @@ int sensor_flush (int s)
        return 0;
 }
 
+
 int allocate_control_data (void)
 {
        int i;