X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=enumeration.c;h=e5703e7340678d1cd242b8af9d6230836dac7c3d;hb=53b3fe263b1716d46b0e74234323a159497cb1e1;hp=852f4d41a8bcb040a6b82c809cd0017740ffd2ca;hpb=283c4d88c2df000957cba69aa36725368de5cbf1;p=android-x86%2Fhardware-intel-libsensors.git diff --git a/enumeration.c b/enumeration.c index 852f4d4..e5703e7 100644 --- a/enumeration.c +++ b/enumeration.c @@ -1,10 +1,11 @@ /* - * Copyright (C) 2014 Intel Corporation. + * Copyright (C) 2014-2015 Intel Corporation. */ #include #include #include +#include #include #include #include "enumeration.h" @@ -28,31 +29,388 @@ * from the same iio device as the base one. */ -struct sensor_catalog_entry_t sensor_catalog[] = { - DECLARE_SENSOR3("accel", SENSOR_TYPE_ACCELEROMETER, "x", "y", "z") - DECLARE_SENSOR3("anglvel", SENSOR_TYPE_GYROSCOPE, "x", "y", "z") - DECLARE_SENSOR3("magn", SENSOR_TYPE_MAGNETIC_FIELD, "x", "y", "z") - DECLARE_SENSOR1("intensity", SENSOR_TYPE_LIGHT, "both" ) - DECLARE_SENSOR0("illuminance",SENSOR_TYPE_LIGHT ) - DECLARE_SENSOR3("incli", SENSOR_TYPE_ORIENTATION, "x", "y", "z") - DECLARE_SENSOR4("rot", SENSOR_TYPE_ROTATION_VECTOR, - "quat_x", "quat_y", "quat_z", "quat_w") - DECLARE_SENSOR0("temp", SENSOR_TYPE_AMBIENT_TEMPERATURE ) - DECLARE_SENSOR0("proximity", SENSOR_TYPE_PROXIMITY ) - DECLARE_SENSOR3("anglvel", SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, "x", "y", "z") +sensor_catalog_entry_t sensor_catalog[] = { + { + .tag = "accel", + .type = SENSOR_TYPE_ACCELEROMETER, + .num_channels = 3, + .is_virtual = 0, + .channel = { + { DECLARE_NAMED_CHANNEL("accel", "x") }, + { DECLARE_NAMED_CHANNEL("accel", "y") }, + { DECLARE_NAMED_CHANNEL("accel", "z") }, + }, + }, + { + .tag = "anglvel", + .type = SENSOR_TYPE_GYROSCOPE, + .num_channels = 3, + .is_virtual = 0, + .channel = { + { DECLARE_NAMED_CHANNEL("anglvel", "x") }, + { DECLARE_NAMED_CHANNEL("anglvel", "y") }, + { DECLARE_NAMED_CHANNEL("anglvel", "z") }, + }, + }, + { + .tag = "magn", + .type = SENSOR_TYPE_MAGNETIC_FIELD, + .num_channels = 3, + .is_virtual = 0, + .channel = { + { DECLARE_NAMED_CHANNEL("magn", "x") }, + { DECLARE_NAMED_CHANNEL("magn", "y") }, + { DECLARE_NAMED_CHANNEL("magn", "z") }, + }, + }, + { + .tag = "intensity", + .type = SENSOR_TYPE_LIGHT, + .num_channels = 1, + .is_virtual = 0, + .channel = { + { DECLARE_NAMED_CHANNEL("intensity", "both") }, + }, + }, + { + .tag = "illuminance", + .type = SENSOR_TYPE_LIGHT, + .num_channels = 1, + .is_virtual = 0, + .channel = { + { DECLARE_GENERIC_CHANNEL("illuminance") }, + }, + }, + { + .tag = "incli", + .type = SENSOR_TYPE_ORIENTATION, + .num_channels = 3, + .is_virtual = 0, + .channel = { + { DECLARE_NAMED_CHANNEL("incli", "x") }, + { DECLARE_NAMED_CHANNEL("incli", "y") }, + { DECLARE_NAMED_CHANNEL("incli", "z") }, + }, + }, + { + .tag = "rot", + .type = SENSOR_TYPE_ROTATION_VECTOR, + .num_channels = 4, + .is_virtual = 0, + .channel = { + { DECLARE_NAMED_CHANNEL("rot", "quat_x") }, + { DECLARE_NAMED_CHANNEL("rot", "quat_y") }, + { DECLARE_NAMED_CHANNEL("rot", "quat_z") }, + { DECLARE_NAMED_CHANNEL("rot", "quat_w") }, + }, + }, + { + .tag = "temp", + .type = SENSOR_TYPE_AMBIENT_TEMPERATURE, + .num_channels = 1, + .is_virtual = 0, + .channel = { + { DECLARE_GENERIC_CHANNEL("temp") }, + }, + }, + { + .tag = "proximity", + .type = SENSOR_TYPE_PROXIMITY, + .num_channels = 1, + .is_virtual = 0, + .channel = { + { DECLARE_GENERIC_CHANNEL("proximity") }, + }, + }, + { + .tag = "", + .type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, + .num_channels = 0, + .is_virtual = 1, + .channel = { + { DECLARE_GENERIC_CHANNEL("") }, + }, + + }, + { + .tag = "", + .type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, + .num_channels = 0, + .is_virtual = 1, + .channel = { + { DECLARE_GENERIC_CHANNEL("") }, + }, + }, + { + .tag = "steps", + .type = SENSOR_TYPE_STEP_COUNTER, + .num_channels = 1, + .is_virtual = 0, + .channel = { + { DECLARE_GENERIC_CHANNEL("steps") }, + }, + }, + { + .tag = "steps", + .type = SENSOR_TYPE_STEP_DETECTOR, + .num_channels = 1, + .is_virtual = 0, + .channel = { + { + DECLARE_VOID_CHANNEL("steps") + .num_events = 1, + .event = { + { DECLARE_NAMED_EVENT("steps", "change") }, + }, + }, + }, + }, }; -#define CATALOG_SIZE ARRAY_SIZE(sensor_catalog) +unsigned int catalog_size = ARRAY_SIZE(sensor_catalog); +/* ACPI PLD (physical location of device) definitions, as used with sensors */ + +#define PANEL_FRONT 4 +#define PANEL_BACK 5 /* We equate sensor handles to indices in these tables */ -struct sensor_t sensor_desc[MAX_SENSORS]; /* Android-level descriptors */ -struct sensor_info_t sensor_info[MAX_SENSORS]; /* Internal descriptors */ -int sensor_count; /* Detected sensors */ +struct sensor_t sensor_desc[MAX_SENSORS]; /* Android-level descriptors */ +sensor_info_t sensor[MAX_SENSORS]; /* Internal descriptors */ +int sensor_count; /* Detected sensors */ + + +/* if the sensor has an _en attribute, we need to enable it */ +int get_needs_enable(int dev_num, const char *tag) +{ + char sysfs_path[PATH_MAX]; + int fd; + + sprintf(sysfs_path, SENSOR_ENABLE_PATH, dev_num, tag); + + fd = open(sysfs_path, O_RDWR); + if (fd == -1) + return 0; + + close(fd); + return 1; +} + +static void setup_properties_from_pld (int s, int panel, int rotation, + int num_channels) +{ + /* + * Generate suitable order and opt_scale directives from the PLD panel + * and rotation codes we got. This can later be superseded by the usual + * properties if necessary. Eventually we'll need to replace these + * mechanisms by a less convoluted one, such as a 3x3 placement matrix. + */ + + int x = 1; + int y = 1; + int z = 1; + int xy_swap = 0; + int angle = rotation * 45; + + /* Only deal with 3 axis chips for now */ + if (num_channels < 3) + return; + + if (panel == PANEL_BACK) { + /* Chip placed on the back panel ; negate x and z */ + x = -x; + z = -z; + } + + switch (angle) { + case 90: /* 90° clockwise: negate y then swap x,y */ + xy_swap = 1; + y = -y; + break; + + case 180: /* Upside down: negate x and y */ + x = -x; + y = -y; + break; + + case 270: /* 90° counter clockwise: negate x then swap x,y */ + x = -x; + xy_swap = 1; + break; + } + + if (xy_swap) { + sensor[s].order[0] = 1; + sensor[s].order[1] = 0; + sensor[s].order[2] = 2; + sensor[s].quirks |= QUIRK_FIELD_ORDERING; + } + + sensor[s].channel[0].opt_scale = x; + sensor[s].channel[1].opt_scale = y; + sensor[s].channel[2].opt_scale = z; +} + + +static int is_valid_pld (int panel, int rotation) +{ + if (panel != PANEL_FRONT && panel != PANEL_BACK) { + ALOGW("Unhandled PLD panel spec: %d\n", panel); + return 0; + } + + /* Only deal with 90° rotations for now */ + if (rotation < 0 || rotation > 7 || (rotation & 1)) { + ALOGW("Unhandled PLD rotation spec: %d\n", rotation); + return 0; + } + + return 1; +} + + +static int read_pld_from_properties (int s, int* panel, int* rotation) +{ + int p, r; + + if (sensor_get_prop(s, "panel", &p)) + return -1; + + if (sensor_get_prop(s, "rotation", &r)) + return -1; + + if (!is_valid_pld(p, r)) + return -1; + + *panel = p; + *rotation = r; + + ALOGI("S%d PLD from properties: panel=%d, rotation=%d\n", s, p, r); + + return 0; +} + + +static int read_pld_from_sysfs (int s, int dev_num, int* panel, int* rotation) +{ + char sysfs_path[PATH_MAX]; + int p,r; + + sprintf(sysfs_path, BASE_PATH "../firmware_node/pld/panel", dev_num); + + if (sysfs_read_int(sysfs_path, &p)) + return -1; + + sprintf(sysfs_path, BASE_PATH "../firmware_node/pld/rotation", dev_num); + + if (sysfs_read_int(sysfs_path, &r)) + return -1; + + if (!is_valid_pld(p, r)) + return -1; + + *panel = p; + *rotation = r; + + ALOGI("S%d PLD from sysfs: panel=%d, rotation=%d\n", s, p, r); + + return 0; +} + + +static void decode_placement_information (int dev_num, int num_channels, int s) +{ + /* + * See if we have optional "physical location of device" ACPI tags. + * We're only interested in panel and rotation specifiers. Use the + * .panel and .rotation properties in priority, and the actual ACPI + * values as a second source. + */ + + int panel; + int rotation; + + if (read_pld_from_properties(s, &panel, &rotation) && + read_pld_from_sysfs(s, dev_num, &panel, &rotation)) + return; /* No PLD data available */ + + /* Map that to field ordering and scaling mechanisms */ + setup_properties_from_pld(s, panel, rotation, num_channels); +} + + +static void populate_descriptors (int s, int sensor_type) +{ + int32_t min_delay_us; + max_delay_t max_delay_us; + + /* Initialize Android-visible descriptor */ + sensor_desc[s].name = sensor_get_name(s); + sensor_desc[s].vendor = sensor_get_vendor(s); + sensor_desc[s].version = sensor_get_version(s); + sensor_desc[s].handle = s; + sensor_desc[s].type = sensor_type; + + sensor_desc[s].maxRange = sensor_get_max_range(s); + sensor_desc[s].resolution = sensor_get_resolution(s); + sensor_desc[s].power = sensor_get_power(s); + sensor_desc[s].stringType = sensor_get_string_type(s); + + /* None of our supported sensors requires a special permission */ + sensor_desc[s].requiredPermission = ""; + + sensor_desc[s].flags = sensor_get_flags(s); + sensor_desc[s].minDelay = sensor_get_min_delay(s); + sensor_desc[s].maxDelay = sensor_get_max_delay(s); + + ALOGV("Sensor %d (%s) type(%d) minD(%d) maxD(%d) flags(%2.2x)\n", + s, sensor[s].friendly_name, sensor_desc[s].type, + sensor_desc[s].minDelay, sensor_desc[s].maxDelay, + sensor_desc[s].flags); + + /* We currently do not implement batching */ + sensor_desc[s].fifoReservedEventCount = 0; + sensor_desc[s].fifoMaxEventCount = 0; + + min_delay_us = sensor_desc[s].minDelay; + max_delay_us = sensor_desc[s].maxDelay; + + sensor[s].min_supported_rate = max_delay_us ? 1000000.0 / max_delay_us : 1; + sensor[s].max_supported_rate = min_delay_us && min_delay_us != -1 ? 1000000.0 / min_delay_us : 0; +} -static void add_sensor (int dev_num, int catalog_index, int use_polling) +static void add_virtual_sensor (int catalog_index) +{ + int s; + int sensor_type; + + if (sensor_count == MAX_SENSORS) { + ALOGE("Too many sensors!\n"); + return; + } + + sensor_type = sensor_catalog[catalog_index].type; + + s = sensor_count; + + sensor[s].is_virtual = 1; + sensor[s].catalog_index = catalog_index; + sensor[s].type = sensor_type; + + populate_descriptors(s, sensor_type); + + /* Initialize fields related to sysfs reads offloading */ + sensor[s].thread_data_fd[0] = -1; + sensor[s].thread_data_fd[1] = -1; + sensor[s].acquisition_thread = -1; + + sensor_count++; +} + + +static void add_sensor (int dev_num, int catalog_index, int mode) { int s; int sensor_type; @@ -65,6 +423,7 @@ static void add_sensor (int dev_num, int catalog_index, int use_polling) const char* ch_name; int num_channels; char suffix[MAX_NAME_SIZE + 8]; + int calib_bias; if (sensor_count == MAX_SENSORS) { ALOGE("Too many sensors!\n"); @@ -81,14 +440,17 @@ static void add_sensor (int dev_num, int catalog_index, int use_polling) s = sensor_count; - sensor_info[s].dev_num = dev_num; - sensor_info[s].catalog_index = catalog_index; + sensor[s].dev_num = dev_num; + sensor[s].catalog_index = catalog_index; + sensor[s].type = sensor_type; + sensor[s].mode = mode; + + num_channels = sensor_catalog[catalog_index].num_channels; - if (use_polling) - sensor_info[s].num_channels = 0; + if (mode == MODE_POLL) + sensor[s].num_channels = 0; else - sensor_info[s].num_channels = - sensor_catalog[catalog_index].num_channels; + sensor[s].num_channels = num_channels; prefix = sensor_catalog[catalog_index].tag; @@ -96,7 +458,7 @@ static void add_sensor (int dev_num, int catalog_index, int use_polling) * receiving the illumination sensor calibration inputs from * the Android properties and setting it within sysfs */ - if (sensor_catalog[catalog_index].type == SENSOR_TYPE_LIGHT) { + if (sensor_type == SENSOR_TYPE_LIGHT) { retval = sensor_get_illumincalib(s); if (retval > 0) { sprintf(sysfs_path, ILLUMINATION_CALIBPATH, dev_num); @@ -104,40 +466,102 @@ static void add_sensor (int dev_num, int catalog_index, int use_polling) } } + /* + * See if we have optional calibration biases for each of the channels of this sensor. These would be expressed using properties like + * iio.accel.y.calib_bias = -1, or possibly something like iio.temp.calib_bias if the sensor has a single channel. This value gets stored in the + * relevant calibbias sysfs file if that file can be located and then used internally by the iio sensor driver. + */ + + if (num_channels) { + for (c = 0; c < num_channels; c++) { + ch_name = sensor_catalog[catalog_index].channel[c].name; + sprintf(suffix, "%s.calib_bias", ch_name); + if (!sensor_get_prop(s, suffix, &calib_bias) && calib_bias) { + sprintf(suffix, "%s_%s", prefix, sensor_catalog[catalog_index].channel[c].name); + sprintf(sysfs_path, SENSOR_CALIB_BIAS_PATH, dev_num, suffix); + sysfs_write_int(sysfs_path, calib_bias); + } + } + } else + if (!sensor_get_prop(s, "calib_bias", &calib_bias) && calib_bias) { + sprintf(sysfs_path, SENSOR_CALIB_BIAS_PATH, dev_num, prefix); + sysfs_write_int(sysfs_path, calib_bias); + } + /* Read name attribute, if available */ sprintf(sysfs_path, NAME_PATH, dev_num); - sysfs_read_str(sysfs_path, sensor_info[s].internal_name, MAX_NAME_SIZE); + sysfs_read_str(sysfs_path, sensor[s].internal_name, MAX_NAME_SIZE); /* See if we have general offsets and scale values for this sensor */ sprintf(sysfs_path, SENSOR_OFFSET_PATH, dev_num, prefix); - sysfs_read_float(sysfs_path, &sensor_info[s].offset); + sysfs_read_float(sysfs_path, &sensor[s].offset); + + sprintf(sysfs_path, SENSOR_SCALE_PATH, dev_num, prefix); + if (!sensor_get_fl_prop(s, "scale", &scale)) { + /* + * There is a chip preferred scale specified, + * so try to store it in sensor's scale file + */ + if (sysfs_write_float(sysfs_path, scale) == -1 && errno == ENOENT) { + ALOGE("Failed to store scale[%g] into %s - file is missing", scale, sysfs_path); + /* Store failed, try to store the scale into channel specific file */ + for (c = 0; c < num_channels; c++) + { + sprintf(sysfs_path, BASE_PATH "%s", dev_num, + sensor_catalog[catalog_index].channel[c].scale_path); + if (sysfs_write_float(sysfs_path, scale) == -1) + ALOGE("Failed to store scale[%g] into %s", scale, sysfs_path); + } + } + } sprintf(sysfs_path, SENSOR_SCALE_PATH, dev_num, prefix); if (!sysfs_read_float(sysfs_path, &scale)) { - sensor_info[s].scale = scale; - ALOGI("Scale path:%s scale:%f dev_num:%d\n", + sensor[s].scale = scale; + ALOGV("Scale path:%s scale:%g dev_num:%d\n", sysfs_path, scale, dev_num); } else { - sensor_info[s].scale = 1; + sensor[s].scale = 1; /* Read channel specific scale if any*/ - for (c = 0; c < sensor_catalog[catalog_index].num_channels; c++) + for (c = 0; c < num_channels; c++) { sprintf(sysfs_path, BASE_PATH "%s", dev_num, sensor_catalog[catalog_index].channel[c].scale_path); if (!sysfs_read_float(sysfs_path, &scale)) { - sensor_info[s].channel[c].scale = scale; - sensor_info[s].scale = 0; + sensor[s].channel[c].scale = scale; + sensor[s].scale = 0; - ALOGI( "Scale path:%s " - "channel scale:%f dev_num:%d\n", + ALOGV( "Scale path:%s " + "channel scale:%g dev_num:%d\n", sysfs_path, scale, dev_num); } } } + /* Set default scaling - if num_channels is zero, we have one channel */ + + sensor[s].channel[0].opt_scale = 1; + + for (c = 1; c < num_channels; c++) + sensor[s].channel[c].opt_scale = 1; + + for (c = 0; c < num_channels; c++) { + /* Check the presence of the channel's input_path */ + sprintf(sysfs_path, BASE_PATH "%s", dev_num, + sensor_catalog[catalog_index].channel[c].input_path); + sensor[s].channel[c].input_path_present = (access(sysfs_path, R_OK) != -1); + /* Check the presence of the channel's raw_path */ + sprintf(sysfs_path, BASE_PATH "%s", dev_num, + sensor_catalog[catalog_index].channel[c].raw_path); + sensor[s].channel[c].raw_path_present = (access(sysfs_path, R_OK) != -1); + } + + /* Read ACPI _PLD attributes for this sensor, if there are any */ + decode_placement_information(dev_num, num_channels, s); + /* * See if we have optional correction scaling factors for each of the * channels of this sensor. These would be expressed using properties @@ -146,188 +570,92 @@ static void add_sensor (int dev_num, int catalog_index, int use_polling) * for all types of sensors, and whatever transform is selected, on top * of any previous conversions. */ - num_channels = sensor_catalog[catalog_index].num_channels; if (num_channels) { for (c = 0; c < num_channels; c++) { - opt_scale = 1; - ch_name = sensor_catalog[catalog_index].channel[c].name; sprintf(suffix, "%s.opt_scale", ch_name); - sensor_get_fl_prop(s, suffix, &opt_scale); - - sensor_info[s].channel[c].opt_scale = opt_scale; + if (!sensor_get_fl_prop(s, suffix, &opt_scale)) + sensor[s].channel[c].opt_scale = opt_scale; } - } else { - opt_scale = 1; - sensor_get_fl_prop(s, "opt_scale", &opt_scale); - sensor_info[s].channel[0].opt_scale = opt_scale; - } + } else + if (!sensor_get_fl_prop(s, "opt_scale", &opt_scale)) + sensor[s].channel[0].opt_scale = opt_scale; - /* Initialize Android-visible descriptor */ - sensor_desc[s].name = sensor_get_name(s); - sensor_desc[s].vendor = sensor_get_vendor(s); - sensor_desc[s].version = sensor_get_version(s); - sensor_desc[s].handle = s; - sensor_desc[s].type = sensor_type; - sensor_desc[s].maxRange = sensor_get_max_range(s); - sensor_desc[s].resolution = sensor_get_resolution(s); - sensor_desc[s].power = sensor_get_power(s); - sensor_desc[s].stringType = sensor_get_string_type(s); + populate_descriptors(s, sensor_type); - /* None of our supported sensors requires a special permission. - * If this will be the case we should implement a sensor_get_perm - */ - sensor_desc[s].requiredPermission = ""; - sensor_desc[s].flags = sensor_get_flags(s); + /* Populate the quirks array */ + sensor_get_quirks(s); - if (sensor_info[s].internal_name[0] == '\0') { + if (sensor[s].internal_name[0] == '\0') { /* * In case the kernel-mode driver doesn't expose a name for * the iio device, use (null)-dev%d as the trigger name... * This can be considered a kernel-mode iio driver bug. */ ALOGW("Using null trigger on sensor %d (dev %d)\n", s, dev_num); - strcpy(sensor_info[s].internal_name, "(null)"); + strcpy(sensor[s].internal_name, "(null)"); } - if (sensor_catalog[catalog_index].type == SENSOR_TYPE_GYROSCOPE || - sensor_catalog[catalog_index].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) { - struct gyro_cal* calibration_data = calloc(1, sizeof(struct gyro_cal)); - sensor_info[s].cal_data = calibration_data; - } + switch (sensor_type) { + case SENSOR_TYPE_ACCELEROMETER: + /* Only engage accelerometer bias compensation if really needed */ + if (sensor_get_quirks(s) & QUIRK_BIASED) + sensor[s].cal_data = calloc(1, sizeof(accel_cal_t)); + break; + + case SENSOR_TYPE_GYROSCOPE: + sensor[s].cal_data = malloc(sizeof(gyro_cal_t)); + break; - if (sensor_catalog[catalog_index].type == SENSOR_TYPE_MAGNETIC_FIELD) { - struct compass_cal* calibration_data = calloc(1, sizeof(struct compass_cal)); - sensor_info[s].cal_data = calibration_data; + case SENSOR_TYPE_MAGNETIC_FIELD: + sensor[s].cal_data = malloc(sizeof(compass_cal_t)); + break; } + sensor[s].max_cal_level = sensor_get_cal_steps(s); + /* Select one of the available sensor sample processing styles */ select_transform(s); /* Initialize fields related to sysfs reads offloading */ - sensor_info[s].thread_data_fd[0] = -1; - sensor_info[s].thread_data_fd[1] = -1; - sensor_info[s].acquisition_thread = -1; + sensor[s].thread_data_fd[0] = -1; + sensor[s].thread_data_fd[1] = -1; + sensor[s].acquisition_thread = -1; /* Check if we have a special ordering property on this sensor */ - if (sensor_get_order(s, sensor_info[s].order)) - sensor_info[s].quirks |= QUIRK_FIELD_ORDERING; - - sensor_count++; -} - - -static void discover_poll_sensors (int dev_num, char map[CATALOG_SIZE]) -{ - char base_dir[PATH_MAX]; - DIR *dir; - struct dirent *d; - unsigned int i; - int c; - - memset(map, 0, CATALOG_SIZE); - - snprintf(base_dir, sizeof(base_dir), BASE_PATH, dev_num); - - dir = opendir(base_dir); - if (!dir) { - return; - } - - /* Enumerate entries in this iio device's base folder */ - - while ((d = readdir(dir))) { - if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) - continue; - - /* If the name matches a catalog entry, flag it */ - for (i = 0; id_name,sensor_catalog[i].channel[c].raw_path) || - !strcmp(d->d_name, sensor_catalog[i].channel[c].input_path)) { - map[i] = 1; - break; - } - } - } - - closedir(dir); -} - - -static void discover_trig_sensors (int dev_num, char map[CATALOG_SIZE]) -{ - char scan_elem_dir[PATH_MAX]; - DIR *dir; - struct dirent *d; - unsigned int i; - - memset(map, 0, CATALOG_SIZE); - - /* Enumerate entries in this iio device's scan_elements folder */ - - snprintf(scan_elem_dir, sizeof(scan_elem_dir), CHANNEL_PATH, dev_num); - - dir = opendir(scan_elem_dir); - if (!dir) { - return; - } + if (sensor_get_order(s, sensor[s].order)) + sensor[s].quirks |= QUIRK_FIELD_ORDERING; - while ((d = readdir(dir))) { - if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) - continue; + sensor[s].needs_enable = get_needs_enable(dev_num, sensor_catalog[catalog_index].tag); - /* Compare en entry to known ones and create matching sensors */ - - for (i = 0; id_name, - sensor_catalog[i].channel[0].en_path)) { - map[i] = 1; - break; - } - } - } - - closedir(dir); + sensor_count++; } - -static void orientation_sensor_check(void) +static void virtual_sensors_check (void) { - /* - * If we have accel + gyro + magn but no rotation vector sensor, - * SensorService replaces the HAL provided orientation sensor by the - * AOSP version... provided we report one. So initialize a virtual - * orientation sensor with zero values, which will get replaced. See: - * frameworks/native/services/sensorservice/SensorService.cpp, looking - * for SENSOR_TYPE_ROTATION_VECTOR; that code should presumably fall - * back to mUserSensorList.add instead of replaceAt, but accommodate it. - */ - int i; int has_acc = 0; int has_gyr = 0; int has_mag = 0; int has_rot = 0; int has_ori = 0; - int catalog_size = CATALOG_SIZE; + int gyro_cal_idx = 0; + int magn_cal_idx = 0; + unsigned int j; for (i=0; i