From 7b6c078575bc291dd5bf9c3d6ea203e4f45e2e9e Mon Sep 17 00:00:00 2001 From: Adriana Reus Date: Fri, 1 May 2015 12:16:34 +0300 Subject: [PATCH] Add support for using a hrtimer trigger. Add support for creating and using a hrtimer trigger when we do not find any other suitable trigger exposed. This may happen if for example we lack the appropriate interrupt line for a platform. We specify a "hrtimer" quirk to signal we allow creating one for opne particular sensor. WE may not want this by default because there are sensor drivers that do not specifically expose a trigger but work if the traditional "-dev%d" one is setup. Change-Id: I0c8a1f6c55b5258330370dc1ac77f8f6dae598cb Signed-off-by: Adriana Reus --- common.h | 3 +++ control.c | 12 +++++++++++- description.c | 3 +++ description.h | 1 + enumeration.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/common.h b/common.h index 09788a2..a6360ac 100644 --- a/common.h +++ b/common.h @@ -30,6 +30,8 @@ #define SENSOR_CALIB_BIAS_PATH BASE_PATH "in_%s_calibbias" #define MOUNTING_MATRIX_PATH BASE_PATH "mounting_matrix" +#define CONFIGFS_TRIGGER_PATH "/config/iio/triggers/" + #define PROP_BASE "ro.iio.%s.%s" /* Note: PROPERTY_KEY_MAX is small */ #define MAX_TYPE_SPEC_LEN 32 /* Channel type spec len; ex: "le:u10/16>>0" */ @@ -153,6 +155,7 @@ typedef struct char vendor_name[MAX_NAME_SIZE]; /* ex: Intel */ char init_trigger_name[MAX_NAME_SIZE]; /* ex: accel-name-dev1 */ char motion_trigger_name[MAX_NAME_SIZE];/* ex: accel-any-motion-dev1 */ + char hrtimer_trigger_name[MAX_NAME_SIZE]; /*ex: accel-hr-dev1 */ float max_range; float resolution; float power; diff --git a/control.c b/control.c index 189d499..cceb3c0 100644 --- a/control.c +++ b/control.c @@ -746,6 +746,7 @@ 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]; ALOGV("Sampling rate %g requested on sensor %d (%s)\n", requested_rate, s, sensor[s].friendly_name); @@ -877,6 +878,11 @@ 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') { + snprintf (hrtimer_sampling_path, PATH_MAX, "%s%s/%s", CONFIGFS_TRIGGER_PATH, sensor[s].hrtimer_trigger_name, "sampling_frequency"); + sysfs_write_float(hrtimer_sampling_path, arb_sampling_rate); + } + if (trig_sensors_per_dev[dev_num]) enable_buffer(dev_num, 0); @@ -991,7 +997,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) { diff --git a/description.c b/description.c index d2a5874..8685298 100644 --- a/description.c +++ b/description.c @@ -397,6 +397,9 @@ uint32_t sensor_get_quirks (int s) if (strstr(quirks_buf, "no-poll")) sensor[s].quirks |= QUIRK_NO_POLL_MODE; + if (strstr(quirks_buf, "hrtimer")) + sensor[s].quirks |= QUIRK_HRTIMER; + sensor[s].quirks |= QUIRK_ALREADY_DECODED; } diff --git a/description.h b/description.h index e4f0641..80868e9 100644 --- a/description.h +++ b/description.h @@ -19,6 +19,7 @@ #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 */ +#define QUIRK_HRTIMER 0x1000 /* We may use a hrtimer if there is no other trigger */ #ifdef __LP64__ typedef uint64_t flag_t; diff --git a/enumeration.c b/enumeration.c index ebcadb9..e8219cc 100644 --- a/enumeration.c +++ b/enumeration.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "enumeration.h" #include "description.h" @@ -799,6 +800,11 @@ static void propose_new_trigger (int s, char trigger_name[MAX_NAME_SIZE], return; } + /* If we found a hrtimer trigger, record it */ + if (!memcmp(suffix, "hr-dev", 6)) { + strcpy(sensor[s].hrtimer_trigger_name, trigger_name); + return; + } /* * It's neither the default "dev" nor an "any-motion" one. Make sure we use this though, as we may not have any other indication of the name * of the trigger to use with this sensor. @@ -807,7 +813,7 @@ static void propose_new_trigger (int s, char trigger_name[MAX_NAME_SIZE], } -static void update_sensor_matching_trigger_name (char name[MAX_NAME_SIZE]) +static void update_sensor_matching_trigger_name (char name[MAX_NAME_SIZE], int* updated) { /* * Check if we have a sensor matching the specified trigger name, which should then begin with the sensor name, and end with a number @@ -851,9 +857,33 @@ static void update_sensor_matching_trigger_name (char name[MAX_NAME_SIZE]) if (!strncmp(name, sensor[s].internal_name, sensor_name_len)) /* Switch to new trigger if appropriate */ propose_new_trigger(s, name, sensor_name_len); + updated[s] = 1; } } +static int create_hrtimer_trigger(int s) +{ + struct stat dir_status; + char buf[MAX_NAME_SIZE]; + char hrtimer_path[PATH_MAX]; + char hrtimer_name[MAX_NAME_SIZE]; + + snprintf(buf, MAX_NAME_SIZE, "hrtimer-%s-hr-dev%d", sensor[s].internal_name, sensor[s].dev_num); + snprintf(hrtimer_name, MAX_NAME_SIZE, "%s-hr-dev%d", sensor[s].internal_name, sensor[s].dev_num); + snprintf(hrtimer_path, PATH_MAX, "%s%s", CONFIGFS_TRIGGER_PATH, buf); + + /* Get parent dir status */ + if (stat(CONFIGFS_TRIGGER_PATH, &dir_status)) + return -1; + + /* Create hrtimer with the same access rights as it's parent */ + if (mkdir(hrtimer_path, dir_status.st_mode)) + if (errno != EEXIST) + return -1; + + strncpy (sensor[s].hrtimer_trigger_name, hrtimer_name, MAX_NAME_SIZE); + return 0; +} static void setup_trigger_names (void) { @@ -862,6 +892,7 @@ static void setup_trigger_names (void) int s; int trigger; int ret; + int updated[MAX_SENSORS] = {0}; /* By default, use the name-dev convention that most drivers use */ for (s=0; s