X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fhardware-intel-libsensors.git;a=blobdiff_plain;f=description.c;h=28a3533bf8966adf3ae099b192ef14111607d923;hp=31b55f864643342bbe6fe92be1943ac76acc6825;hb=e35fc5677585eb789efb5c02e2de084fbedcd67d;hpb=a65a6ef5184ce3c36b7b0da63c7a84e2388ebe51 diff --git a/description.c b/description.c index 31b55f8..28a3533 100644 --- a/description.c +++ b/description.c @@ -11,6 +11,7 @@ #include "enumeration.h" #include "description.h" #include "utils.h" +#include "transform.h" #define IIO_SENSOR_HAL_VERSION 1 @@ -92,6 +93,7 @@ int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE]) int i = sensor[s].catalog_index; const char *prefix = sensor_catalog[i].tag; + const char *shorthand = sensor_catalog[i].shorthand; /* First try most specialized form, like ro.iio.anglvel.bmg160.name */ @@ -106,6 +108,16 @@ int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE]) return 0; } + if (shorthand[0] != '\0') { + /* Try with shorthand instead of prefix */ + snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, shorthand, 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 */ snprintf(prop_name, PROP_NAME_MAX, PROP_BASE, prefix, sel); @@ -207,6 +219,60 @@ int sensor_get_version (__attribute__((unused)) int s) return IIO_SENSOR_HAL_VERSION; } +void sensor_update_max_range(int s) +{ + if (sensor[s].max_range) + return; + + if (sensor[s].num_channels && sensor[s].channel[0].type_info.realbits) { + switch (sensor[s].type) { + case SENSOR_TYPE_MAGNETIC_FIELD: + sensor[s].max_range = (1ULL << sensor[s].channel[0].type_info.realbits) * + CONVERT_MICROTESLA_TO_GAUSS(sensor[s].resolution) + + (sensor[s].offset || sensor[s].channel[0].offset); + sensor[s].max_range = CONVERT_GAUSS_TO_MICROTESLA(sensor[s].max_range); + break; + case SENSOR_TYPE_PROXIMITY: + break; + default: + sensor[s].max_range = (1ULL << sensor[s].channel[0].type_info.realbits) * + sensor[s].resolution + (sensor[s].offset || sensor[s].channel[0].offset); + break; + } + } + + if (!sensor[s].max_range) { + /* Try returning a sensible value given the sensor type */ + /* We should cap returned samples accordingly... */ + switch (sensor[s].type) { + case SENSOR_TYPE_ACCELEROMETER: /* m/s^2 */ + sensor[s].max_range = 50; + break; + case SENSOR_TYPE_MAGNETIC_FIELD: /* micro-tesla */ + sensor[s].max_range = 500; + break; + case SENSOR_TYPE_ORIENTATION: /* degrees */ + sensor[s].max_range = 360; + break; + case SENSOR_TYPE_GYROSCOPE: /* radians/s */ + sensor[s].max_range = 10; + break; + case SENSOR_TYPE_LIGHT: /* SI lux units */ + sensor[s].max_range = 50000; + break; + case SENSOR_TYPE_AMBIENT_TEMPERATURE: /* °C */ + case SENSOR_TYPE_TEMPERATURE: /* °C */ + case SENSOR_TYPE_PROXIMITY: /* centimeters */ + case SENSOR_TYPE_PRESSURE: /* hecto-pascal */ + case SENSOR_TYPE_RELATIVE_HUMIDITY: /* percent */ + sensor[s].max_range = 100; + break; + } + } + + if (sensor[s].max_range) + sensor_desc[s].maxRange = sensor[s].max_range; +} float sensor_get_max_range (int s) { @@ -225,39 +291,10 @@ float sensor_get_max_range (int s) !sensor_get_fl_prop(s, "max_range", &sensor[s].max_range)) return sensor[s].max_range; - /* Try returning a sensible value given the sensor type */ - - /* We should cap returned samples accordingly... */ - - switch (sensor[s].type) { - case SENSOR_TYPE_ACCELEROMETER: /* m/s^2 */ - return 50; - - case SENSOR_TYPE_MAGNETIC_FIELD: /* micro-tesla */ - return 500; - - case SENSOR_TYPE_ORIENTATION: /* degrees */ - return 360; - - case SENSOR_TYPE_GYROSCOPE: /* radians/s */ - return 10; - - case SENSOR_TYPE_LIGHT: /* SI lux units */ - return 50000; - - case SENSOR_TYPE_AMBIENT_TEMPERATURE: /* °C */ - case SENSOR_TYPE_TEMPERATURE: /* °C */ - case SENSOR_TYPE_PROXIMITY: /* centimeters */ - case SENSOR_TYPE_PRESSURE: /* hecto-pascal */ - case SENSOR_TYPE_RELATIVE_HUMIDITY: /* percent */ - return 100; - - default: - return 0; - } + return 0; } -static float sensor_get_min_freq (int s) +float sensor_get_min_freq (int s) { /* * Check if a low cap has been specified for this sensor sampling rate. @@ -275,7 +312,7 @@ static float sensor_get_min_freq (int s) } -static float sensor_get_max_freq (int s) +float sensor_get_max_freq (int s) { float max_freq; @@ -308,10 +345,18 @@ float sensor_get_resolution (int s) } if (sensor[s].resolution != 0.0 || - !sensor_get_fl_prop(s, "resolution", &sensor[s].resolution)) - return sensor[s].resolution; + !sensor_get_fl_prop(s, "resolution", &sensor[s].resolution)) { + return sensor[s].resolution; + } - return 0; + sensor[s].resolution = sensor[s].scale; + if (!sensor[s].resolution && sensor[s].num_channels) + sensor[s].resolution = sensor[s].channel[0].scale; + + if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD) + sensor[s].resolution = CONVERT_GAUSS_TO_MICROTESLA(sensor[s].resolution); + + return sensor[s].resolution ? : 1; } @@ -377,6 +422,21 @@ uint32_t sensor_get_quirks (int s) if (strstr(quirks_buf, "spotty")) sensor[s].quirks |= QUIRK_SPOTTY; + if (strstr(quirks_buf, "no-event")) + sensor[s].quirks |= QUIRK_NO_EVENT_MODE; + + if (strstr(quirks_buf, "no-trig")) + sensor[s].quirks |= QUIRK_NO_TRIG_MODE; + + if (strstr(quirks_buf, "no-poll")) + sensor[s].quirks |= QUIRK_NO_POLL_MODE; + + if (strstr(quirks_buf, "hrtimer")) + sensor[s].quirks |= QUIRK_HRTIMER; + + if (strstr(quirks_buf, "secondary")) + sensor[s].quirks |= QUIRK_SECONDARY; + sensor[s].quirks |= QUIRK_ALREADY_DECODED; } @@ -407,11 +467,88 @@ int sensor_get_order (int s, unsigned char map[MAX_CHANNELS]) return 1; /* OK to use modified ordering map */ } +int sensor_get_available_frequencies (int s) +{ + int dev_num = sensor[s].dev_num, err, i; + char avail_sysfs_path[PATH_MAX], freqs_buf[100]; + char *p, *end; + float f; -char* sensor_get_string_type (int s) + sensor[s].avail_freqs_count = 0; + sensor[s].avail_freqs = 0; + + sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num); + + err = sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf)); + if (err < 0) + return 0; + + for (p = freqs_buf, f = strtof(p, &end); p != end; p = end, f = strtof(p, &end)) + sensor[s].avail_freqs_count++; + + if (sensor[s].avail_freqs_count) { + sensor[s].avail_freqs = (float*) calloc(sensor[s].avail_freqs_count, sizeof(float)); + + for (p = freqs_buf, f = strtof(p, &end), i = 0; p != end; p = end, f = strtof(p, &end), i++) + sensor[s].avail_freqs[i] = f; + } + + return 0; +} + +int sensor_get_mounting_matrix (int s, float mm[9]) { + int dev_num = sensor[s].dev_num, err, i; + char mm_path[PATH_MAX], mm_buf[100]; + char *tmp1 = mm_buf, *tmp2; + switch (sensor[s].type) { case SENSOR_TYPE_ACCELEROMETER: + case SENSOR_TYPE_MAGNETIC_FIELD: + case SENSOR_TYPE_GYROSCOPE: + case SENSOR_TYPE_PROXIMITY: + break; + default: + return 0; + } + + sprintf(mm_path, MOUNTING_MATRIX_PATH, dev_num); + + err = sysfs_read_str(mm_path, mm_buf, sizeof(mm_buf)); + if (err < 0) + return 0; + + for(i = 0; i < 9; i++) { + float f; + + f = strtof(tmp1, &tmp2); + if (!f && tmp1 == tmp2) + return 0; + mm[i] = f; + tmp1 = tmp2 + 1; + } + + /* + * For proximity sensors, interpret a negative final z value as a hint that the sensor is back mounted. In that case, mark the sensor as secondary to + * ensure that it gets listed after other sensors of same type that would be front-mounted. Most applications will only ask for the default proximity + * sensor and it makes more sense to point to, say, the IR based proximity sensor rather than SAR based one if we have both, as on SoFIA LTE MRD boards. + */ + if (sensor[s].type == SENSOR_TYPE_PROXIMITY) { + if (mm[8] < 0) { + sensor[s].quirks |= QUIRK_SECONDARY; + } + return 0; + } + + ALOGI("%s: %f %f %f %f %f %f %f %f %f\n", __func__, mm[0], mm[1], mm[2], mm[3], mm[4], mm[5], mm[6], mm[7], mm[8]); + return 1; +} + + +char* sensor_get_string_type (int s) +{ + switch (sensor_desc[s].type) { + case SENSOR_TYPE_ACCELEROMETER: return SENSOR_STRING_TYPE_ACCELEROMETER; case SENSOR_TYPE_MAGNETIC_FIELD: @@ -457,7 +594,7 @@ flag_t sensor_get_flags (int s) { flag_t flags = 0; - switch (sensor[s].type) { + switch (sensor_desc[s].type) { case SENSOR_TYPE_LIGHT: case SENSOR_TYPE_AMBIENT_TEMPERATURE: case SENSOR_TYPE_TEMPERATURE: @@ -483,7 +620,7 @@ flag_t sensor_get_flags (int s) static int get_cdd_freq (int s, int must) { - switch (sensor[s].type) { + switch (sensor_desc[s].type) { case SENSOR_TYPE_ACCELEROMETER: return (must ? 100 : 200); /* must 100 Hz, should 200 Hz, CDD compliant */ @@ -511,13 +648,9 @@ static int get_cdd_freq (int s, int must) */ max_delay_t sensor_get_max_delay (int s) { - char avail_sysfs_path[PATH_MAX]; - int dev_num = sensor[s].dev_num; - char freqs_buf[100]; - char* cursor; - float min_supported_rate = 1000; + int dev_num = sensor[s].dev_num, i; + float min_supported_rate; float rate_cap; - float sr; /* * continuous, on-change: maximum sampling period allowed in microseconds. @@ -544,31 +677,24 @@ max_delay_t sensor_get_max_delay (int s) 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) { - if (sensor[s].mode == MODE_POLL) { - /* 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); - if (sr < min_supported_rate) - min_supported_rate = sr; + switch (sensor[s].mode) { + case MODE_TRIGGER: + /* For interrupt-based devices, obey the list of supported sampling rates */ + if (sensor[s].avail_freqs_count) { + min_supported_rate = 1000; + for (i = 0; i < sensor[s].avail_freqs_count; i++) { + if (sensor[s].avail_freqs[i] < min_supported_rate) + min_supported_rate = sensor[s].avail_freqs[i]; + } + break; + } + /* Fall through ... */ - /* Skip digits */ - while (cursor[0] && !isspace(cursor[0])) - cursor++; - - /* Skip spaces */ - while (cursor[0] && isspace(cursor[0])) - cursor++; - } + default: + /* Report 1 Hz */ + min_supported_rate = 1; + break; } /* Check if a minimum rate was specified for this sensor */ @@ -585,16 +711,24 @@ max_delay_t sensor_get_max_delay (int s) return (max_delay_t) (1000000.0 / min_supported_rate); } +float sensor_get_max_static_freq(int s) +{ + float max_from_prop = sensor_get_max_freq(s); + + /* If we have max specified via a property use it */ + if (max_from_prop != ANDROID_MAX_FREQ) { + return max_from_prop; + } else { + /* The should rate */ + return get_cdd_freq(s, 0); + } +} int32_t sensor_get_min_delay (int s) { - char avail_sysfs_path[PATH_MAX]; - int dev_num = sensor[s].dev_num; - char freqs_buf[100]; - char* cursor; + int dev_num = sensor[s].dev_num, i; float max_supported_rate = 0; float max_from_prop = sensor_get_max_freq(s); - float sr; /* continuous, on change: minimum sampling period allowed in microseconds. * special : 0, unless otherwise noted @@ -624,9 +758,7 @@ int32_t sensor_get_min_delay (int s) } } - sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num); - - if (sysfs_read_str(avail_sysfs_path, freqs_buf, sizeof(freqs_buf)) < 0) { + if (!sensor[s].avail_freqs_count) { if (sensor[s].mode == MODE_POLL) { /* If we have max specified via a property use it */ if (max_from_prop != ANDROID_MAX_FREQ) @@ -636,22 +768,11 @@ int32_t sensor_get_min_delay (int s) 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 <= max_from_prop) - max_supported_rate = sr; - - /* Skip digits */ - while (cursor[0] && !isspace(cursor[0])) - cursor++; - - /* Skip spaces */ - while (cursor[0] && isspace(cursor[0])) - cursor++; + for (i = 0; i < sensor[s].avail_freqs_count; i++) { + if (sensor[s].avail_freqs[i] > max_supported_rate && + sensor[s].avail_freqs[i] <= max_from_prop) { + max_supported_rate = sensor[s].avail_freqs[i]; + } } }