X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=description.c;h=dbba15866d78ed6fe51053ccfcc7b9c388804960;hb=389edefcad440dc0344e6cebe11ddef1f8464b08;hp=2c6fec09095a52037ca3d553d78e8a603dd191fb;hpb=cc5be006f5925b908f44587f29e6aea59199a576;p=android-x86%2Fhardware-intel-libsensors.git diff --git a/description.c b/description.c index 2c6fec0..dbba158 100644 --- a/description.c +++ b/description.c @@ -3,12 +3,14 @@ */ #include +#include #include #include #include #include "common.h" #include "enumeration.h" #include "description.h" +#include "utils.h" #define IIO_SENSOR_HAL_VERSION 1 @@ -70,15 +72,38 @@ * 'panel' and 'rotation' specifiers can be used to express ACPI PLD placement * information ; if found they will be used in priority over the actual ACPI * data. That is intended as a way to verify values during development. + * + * It's possible to use the contents of the iio device name as a way to + * discriminate between sensors. Several sensors of the same type can coexist: + * e.g. ro.iio.temp.bmg160.name = BMG160 Thermometer will be used in priority + * over ro.iio.temp.name = BMC150 Thermometer if the sensor for which we query + * properties values happen to have its iio device name set to bmg160. */ static int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE]) { char prop_name[PROP_NAME_MAX]; char prop_val[PROP_VALUE_MAX]; + char extended_sel[PROP_VALUE_MAX]; + int i = sensor_info[s].catalog_index; const char *prefix = sensor_catalog[i].tag; + /* First try most specialized form, like ro.iio.anglvel.bmg160.name */ + + snprintf(extended_sel, PROP_NAME_MAX, "%s.%s", + sensor_info[s].internal_name, sel); + + snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, prefix, extended_sel); + + if (property_get(prop_name, prop_val, "")) { + strncpy(val, prop_val, MAX_NAME_SIZE-1); + val[MAX_NAME_SIZE-1] = '\0'; + return 0; + } + + /* Fall back to simple form, like ro.iio.anglvel.name */ + sprintf(prop_name, PROP_BASE, prefix, sel); if (property_get(prop_name, prop_val, "")) { @@ -151,9 +176,6 @@ int sensor_get_version (int s) float sensor_get_max_range (int s) { - int catalog_index; - int sensor_type; - if (sensor_info[s].max_range != 0.0 || !sensor_get_fl_prop(s, "max_range", &sensor_info[s].max_range)) return sensor_info[s].max_range; @@ -162,10 +184,7 @@ float sensor_get_max_range (int s) /* We should cap returned samples accordingly... */ - catalog_index = sensor_info[s].catalog_index; - sensor_type = sensor_catalog[catalog_index].type; - - switch (sensor_type) { + switch (sensor_info[s].type) { case SENSOR_TYPE_ACCELEROMETER: /* m/s^2 */ return 50; @@ -193,6 +212,42 @@ float sensor_get_max_range (int s) } } +static float sensor_get_min_freq (int s) +{ + /* + * Check if a low cap has been specified for this sensor sampling rate. + * In some case, even when the driver supports lower rate, we still + * wish to receive a certain number of samples per seconds for various + * reasons (calibration, filtering, no change in power consumption...). + */ + + float min_freq; + + if (!sensor_get_fl_prop(s, "min_freq", &min_freq)) + return min_freq; + + return 0; +} + + +static float sensor_get_max_freq (int s) +{ + float max_freq; + + if (!sensor_get_fl_prop(s, "max_freq", &max_freq)) + return max_freq; + + return 1000; +} + +int sensor_get_cal_steps (int s) +{ + int cal_steps; + if (!sensor_get_prop(s, "cal_steps", &cal_steps)) + return cal_steps; + + return 0; +} float sensor_get_resolution (int s) { @@ -239,6 +294,9 @@ uint32_t sensor_get_quirks (int s) if (strstr(quirks_buf, "init-rate")) sensor_info[s].quirks |= QUIRK_INITIAL_RATE; + if (strstr(quirks_buf, "continuous")) + sensor_info[s].quirks |= QUIRK_FORCE_CONTINUOUS; + if (strstr(quirks_buf, "terse")) sensor_info[s].quirks |= QUIRK_TERSE_DRIVER; @@ -275,15 +333,9 @@ int sensor_get_order (int s, unsigned char map[MAX_CHANNELS]) return 1; /* OK to use modified ordering map */ } -char* sensor_get_string_type(int s) +char* sensor_get_string_type (int s) { - int catalog_index; - int sensor_type; - - catalog_index = sensor_info[s].catalog_index; - sensor_type = sensor_catalog[catalog_index].type; - - switch (sensor_type) { + switch (sensor_info[s].type) { case SENSOR_TYPE_ACCELEROMETER: return SENSOR_STRING_TYPE_ACCELEROMETER; @@ -324,14 +376,9 @@ char* sensor_get_string_type(int s) flag_t sensor_get_flags (int s) { - int catalog_index; - int sensor_type; - flag_t flags = 0x0; - catalog_index = sensor_info[s].catalog_index; - sensor_type = sensor_catalog[catalog_index].type; - switch (sensor_type) { + switch (sensor_info[s].type) { case SENSOR_TYPE_ACCELEROMETER: case SENSOR_TYPE_MAGNETIC_FIELD: case SENSOR_TYPE_ORIENTATION: @@ -360,6 +407,38 @@ flag_t sensor_get_flags (int s) return flags; } +int get_cdd_freq (int s, int must) +{ + switch (sensor_info[s].type) { + case SENSOR_TYPE_ACCELEROMETER: + return (must ? 100 : 200); /* must 100 Hz, should 200 Hz, CDD compliant */ + case SENSOR_TYPE_GYROSCOPE: + case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: + return (must ? 200 : 200); /* must 200 Hz, should 200 Hz, CDD compliant */ + case SENSOR_TYPE_MAGNETIC_FIELD: + return (must ? 10 : 50); /* must 10 Hz, should 50 Hz, CDD compliant */ + case SENSOR_TYPE_LIGHT: + case SENSOR_TYPE_AMBIENT_TEMPERATURE: + case SENSOR_TYPE_TEMPERATURE: + return (must ? 1 : 2); /* must 1 Hz, should 2Hz, not mentioned in CDD */ + default: + return 0; + } +} + +/* This value is defined only for continuous mode and on-change sensors. It is the delay between + * two sensor events corresponding to the lowest frequency that this sensor supports. When lower + * frequencies are requested through batch()/setDelay() the events will be generated at this + * frequency instead. It can be used by the framework or applications to estimate when the batch + * FIFO may be full. + * + * NOTE: 1) period_ns is in nanoseconds where as maxDelay/minDelay are in microseconds. + * continuous, on-change: maximum sampling period allowed in microseconds. + * one-shot, special : 0 + * 2) maxDelay should always fit within a 32 bit signed integer. It is declared as 64 bit + * on 64 bit architectures only for binary compatibility reasons. + * Availability: SENSORS_DEVICE_API_VERSION_1_3 + */ max_delay_t sensor_get_max_delay (int s) { char avail_sysfs_path[PATH_MAX]; @@ -367,38 +446,50 @@ max_delay_t sensor_get_max_delay (int s) char freqs_buf[100]; char* cursor; float min_supported_rate = 1000; + float rate_cap; float sr; - /* continuous: maximum sampling period allowed in microseconds. - * on-change, one-shot, special : 0 + /* continuous, on-change: maximum sampling period allowed in microseconds. + * one-shot, special : 0 */ - - if (sensor_desc[s].flags) + if (REPORTING_MODE(sensor_desc[s].flags) == SENSOR_FLAG_ONE_SHOT_MODE || + REPORTING_MODE(sensor_desc[s].flags) == SENSOR_FLAG_SPECIAL_REPORTING_MODE) return 0; sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num); - if (sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf)) < 0) - return 0; - - cursor = freqs_buf; - while (*cursor && cursor[0]) { + if (sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf)) < 0) { + /* If poll mode sensor */ + if (!sensor_info[s].num_channels) { + /* The must rate */ + min_supported_rate = get_cdd_freq(s, 1); + } + } else { + cursor = freqs_buf; + while (*cursor && cursor[0]) { - /* Decode a single value */ - sr = strtod(cursor, NULL); + /* Decode a single value */ + sr = strtod(cursor, NULL); - if (sr < min_supported_rate) - min_supported_rate = sr; + if (sr < min_supported_rate) + min_supported_rate = sr; - /* Skip digits */ - while (cursor[0] && !isspace(cursor[0])) - cursor++; + /* Skip digits */ + while (cursor[0] && !isspace(cursor[0])) + cursor++; - /* Skip spaces */ - while (cursor[0] && isspace(cursor[0])) - cursor++; + /* Skip spaces */ + while (cursor[0] && isspace(cursor[0])) + cursor++; + } } + /* Check if a minimum rate was specified for this sensor */ + rate_cap = sensor_get_min_freq(s); + + if (min_supported_rate < rate_cap) + min_supported_rate = rate_cap; + /* return 0 for wrong values */ if (min_supported_rate < 0.1) return 0; @@ -406,3 +497,66 @@ max_delay_t sensor_get_max_delay (int s) /* Return microseconds */ return (max_delay_t)(1000000.0 / min_supported_rate); } + +/* this value depends on the reporting mode: + * + * continuous: minimum sample period allowed in microseconds + * on-change : 0 + * one-shot :-1 + * special : 0, unless otherwise noted + */ +int32_t sensor_get_min_delay(int s) +{ + char avail_sysfs_path[PATH_MAX]; + int dev_num = sensor_info[s].dev_num; + char freqs_buf[100]; + char* cursor; + float max_supported_rate = 0; + float sr; + + /* continuous: minimum sampling period allowed in microseconds. + * on-change, special : 0 + * one-shot :-1 + */ + if (REPORTING_MODE(sensor_desc[s].flags) == SENSOR_FLAG_ON_CHANGE_MODE || + REPORTING_MODE(sensor_desc[s].flags) == SENSOR_FLAG_SPECIAL_REPORTING_MODE) + return 0; + + if (REPORTING_MODE(sensor_desc[s].flags) == SENSOR_FLAG_ONE_SHOT_MODE) + return -1; + + sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num); + + if (sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf)) < 0) { + /* If poll mode sensor */ + if (!sensor_info[s].num_channels) { + /* The should rate */ + max_supported_rate = get_cdd_freq(s, 0); + } + } else { + cursor = freqs_buf; + while (*cursor && cursor[0]) { + + /* Decode a single value */ + sr = strtod(cursor, NULL); + + if (sr > max_supported_rate && sr <= sensor_get_max_freq(s)) + max_supported_rate = sr; + + /* Skip digits */ + while (cursor[0] && !isspace(cursor[0])) + cursor++; + + /* Skip spaces */ + while (cursor[0] && isspace(cursor[0])) + cursor++; + } + } + + /* return 0 for wrong values */ + if (max_supported_rate < 0.1) + return 0; + + /* Return microseconds */ + return (int32_t)(1000000.0 / max_supported_rate); +}