DECLARE_SENSOR0("temp", SENSOR_TYPE_AMBIENT_TEMPERATURE )
DECLARE_SENSOR0("proximity", SENSOR_TYPE_PROXIMITY )
DECLARE_VIRTUAL(SENSOR_TYPE_GYROSCOPE_UNCALIBRATED )
+ DECLARE_VIRTUAL(SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED )
};
#define CATALOG_SIZE ARRAY_SIZE(sensor_catalog)
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);
/* 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;
}
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");
s = sensor_count;
- sensor[s].dev_num = dev_num;
+ sensor[s].dev_num = dev_num;
sensor[s].catalog_index = catalog_index;
sensor[s].type = sensor_type;
+ sensor[s].is_polling = use_polling;
num_channels = sensor_catalog[catalog_index].num_channels;
}
}
+ /*
+ * 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[s].internal_name, MAX_NAME_SIZE);
/* If the name matches a catalog entry, flag it */
for (i = 0; i < CATALOG_SIZE; i++) {
- /* No discovery for virtual sensors */
- if (sensor_catalog[i].is_virtual)
- continue;
- for (c=0; c<sensor_catalog[i].num_channels; c++)
- if (!strcmp(d->d_name,sensor_catalog[i].channel[c].raw_path) ||
- !strcmp(d->d_name, sensor_catalog[i].channel[c].input_path)) {
+
+ /* No discovery for virtual sensors */
+ if (sensor_catalog[i].is_virtual)
+ continue;
+
+ for (c=0; c<sensor_catalog[i].num_channels; c++)
+ if (!strcmp(d->d_name,sensor_catalog[i].channel[c].raw_path) || !strcmp(d->d_name, sensor_catalog[i].channel[c].input_path)) {
map[i] = 1;
break;
}
/* Compare en entry to known ones and create matching sensors */
for (i = 0; i<CATALOG_SIZE; i++) {
+
/* No discovery for virtual sensors */
if (sensor_catalog[i].is_virtual)
continue;
- if (!strcmp(d->d_name,
- sensor_catalog[i].channel[0].en_path)) {
+
+ if (!strcmp(d->d_name, sensor_catalog[i].channel[0].en_path)) {
map[i] = 1;
break;
}
}
-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_rot = 0;
int has_ori = 0;
int catalog_size = CATALOG_SIZE;
+ int gyro_cal_idx = 0;
+ int magn_cal_idx = 0;
for (i=0; i<sensor_count; i++)
switch (sensor[i].type) {
break;
case SENSOR_TYPE_GYROSCOPE:
has_gyr = 1;
+ gyro_cal_idx = i;
break;
case SENSOR_TYPE_MAGNETIC_FIELD:
has_mag = 1;
+ magn_cal_idx = i;
break;
case SENSOR_TYPE_ORIENTATION:
has_ori = 1;
break;
}
- if (has_acc && has_gyr && has_mag && !has_rot && !has_ori)
- for (i=0; i<catalog_size; i++)
- if (sensor_catalog[i].type == SENSOR_TYPE_ORIENTATION) {
- ALOGI("Adding placeholder orientation sensor");
- add_sensor(0, i, 1);
+ for (i=0; i<catalog_size; i++)
+ switch (sensor_catalog[i].type) {
+ /*
+ * 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.
+ */
+
+ case SENSOR_TYPE_ORIENTATION:
+ if (has_acc && has_gyr && has_mag && !has_rot && !has_ori)
+ add_sensor(0, i, 1);
break;
- }
+ case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+ if (has_gyr) {
+ sensor[sensor_count].base_count = 1;
+ sensor[sensor_count].base[0] = gyro_cal_idx;
+ add_virtual_sensor(i);
+ }
+ break;
+ case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+ if (has_mag) {
+ sensor[sensor_count].base_count = 1;
+ sensor[sensor_count].base[0] = magn_cal_idx;
+ add_virtual_sensor(i);
+ }
+ break;
+ default:
+ break;
+ }
}
int sensor_name_len)
{
/*
- * A new trigger has been enumerated for this sensor. Check if it makes
- * sense to use it over the currently selected one, and select it if it
- * is so. The format is something like sensor_name-dev0.
+ * A new trigger has been enumerated for this sensor. Check if it makes sense to use it over the currently selected one,
+ * and select it if it is so. The format is something like sensor_name-dev0.
*/
const char *suffix = trigger_name + sensor_name_len + 1;
}
/*
- * 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
+ * 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.
*/
strcpy(sensor[s].init_trigger_name, trigger_name);
static void update_sensor_matching_trigger_name (char name[MAX_NAME_SIZE])
{
/*
- * Check if we have a sensor matching the specified trigger name,
- * which should then begin with the sensor name, and end with a number
- * equal to the iio device number the sensor is associated to. If so,
- * update the string we're going to write to trigger/current_trigger
+ * Check if we have a sensor matching the specified trigger name, which should then begin with the sensor name, and end with a number
+ * equal to the iio device number the sensor is associated to. If so, update the string we're going to write to trigger/current_trigger
* when enabling this sensor.
*/
int sensor_name_len;
/*
- * First determine the iio device number this trigger refers to. We
- * expect the last few characters (typically one) of the trigger name
+ * First determine the iio device number this trigger refers to. We expect the last few characters (typically one) of the trigger name
* to be this number, so perform a few checks.
*/
len = strnlen(name, MAX_NAME_SIZE);
sensor_name_len = strlen(sensor[s].internal_name);
- if (!strncmp(name,
- sensor[s].internal_name,
- sensor_name_len))
+ if (!strncmp(name, sensor[s].internal_name, sensor_name_len))
/* Switch to new trigger if appropriate */
propose_new_trigger(s, name, sensor_name_len);
}
/* By default, use the name-dev convention that most drivers use */
for (s=0; s<sensor_count; s++)
- snprintf(sensor[s].init_trigger_name,
- MAX_NAME_SIZE, "%s-dev%d",
- sensor[s].internal_name, sensor[s].dev_num);
+ snprintf(sensor[s].init_trigger_name, MAX_NAME_SIZE, "%s-dev%d", sensor[s].internal_name, sensor[s].dev_num);
/* Now have a look to /sys/bus/iio/devices/triggerX entries */
}
/*
- * Certain drivers expose only motion triggers even though they should
- * be continous. For these, use the default trigger name as the motion
- * trigger. The code generating intermediate events is dependent on
- * motion_trigger_name being set to a non empty string.
+ * Certain drivers expose only motion triggers even though they should be continous. For these, use the default trigger name as the motion
+ * trigger. The code generating intermediate events is dependent on motion_trigger_name being set to a non empty string.
*/
for (s=0; s<sensor_count; s++)
- if ((sensor[s].quirks & QUIRK_TERSE_DRIVER) &&
- sensor[s].motion_trigger_name[0] == '\0')
- strcpy( sensor[s].motion_trigger_name,
- sensor[s].init_trigger_name);
+ if ((sensor[s].quirks & QUIRK_TERSE_DRIVER) && sensor[s].motion_trigger_name[0] == '\0')
+ strcpy(sensor[s].motion_trigger_name, sensor[s].init_trigger_name);
for (s=0; s<sensor_count; s++)
- if (sensor[s].num_channels) {
- ALOGI("Sensor %d (%s) default trigger: %s\n", s,
- sensor[s].friendly_name,
- sensor[s].init_trigger_name);
+ if (!sensor[s].is_polling) {
+ ALOGI("Sensor %d (%s) default trigger: %s\n", s, sensor[s].friendly_name, sensor[s].init_trigger_name);
if (sensor[s].motion_trigger_name[0])
- ALOGI("Sensor %d (%s) motion trigger: %s\n",
- s, sensor[s].friendly_name,
- sensor[s].motion_trigger_name);
- }
-}
-
-
-static void uncalibrated_gyro_check (void)
-{
- unsigned int has_gyr = 0;
- unsigned int dev_num;
- int i;
-
- int cal_idx = 0;
- int uncal_idx = 0;
- int catalog_size = CATALOG_SIZE; /* Avoid GCC sign comparison warning */
-
- if (sensor_count == MAX_SENSORS)
- return;
- /* Checking to see if we have a gyroscope - we can only have uncal if we have the base sensor */
- for (i=0; i < sensor_count; i++)
- if (sensor[i].type == SENSOR_TYPE_GYROSCOPE) {
- has_gyr=1;
- cal_idx = i;
- break;
+ ALOGI("Sensor %d (%s) motion trigger: %s\n", s, sensor[s].friendly_name, sensor[s].motion_trigger_name);
}
-
- if (has_gyr) {
- uncal_idx = sensor_count;
- sensor[uncal_idx].base_count = 1;
- sensor[uncal_idx].base[0] = cal_idx;
-
- for (i=0; i<catalog_size; i++)
- if (sensor_catalog[i].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
- add_virtual_sensor(i);
- break;
- }
- }
}
-
void enumerate_sensors (void)
{
/*
- * Discover supported sensors and allocate control structures for them.
- * Multiple sensors can potentially rely on a single iio device (each
- * using their own channels). We can't have multiple sensors of the same
- * type on the same device. In case of detection as both a poll-mode
+ * Discover supported sensors and allocate control structures for them. Multiple sensors can potentially rely on a single iio device (each
+ * using their own channels). We can't have multiple sensors of the same type on the same device. In case of detection as both a poll-mode
* and trigger-based sensor, use the trigger usage mode.
*/
char poll_sensors[CATALOG_SIZE];
if (poll_sensors[i])
add_sensor(dev_num, i, 1);
- if (trig_found) {
+ if (trig_found)
build_sensor_report_maps(dev_num);
- }
}
ALOGI("Discovered %d sensors\n", sensor_count);
/* Set up default - as well as custom - trigger names */
setup_trigger_names();
- /* Make sure Android fall backs to its own orientation sensor */
- orientation_sensor_check();
-
- /*
- * Create the uncalibrated counterpart to the compensated gyroscope.
- * This is is a new sensor type in Android 4.4.
- */
-
- uncalibrated_gyro_check();
+ virtual_sensors_check();
}