#include "calibration.h"
#include "description.h"
#include "filtering.h"
-
+#include <linux/iio/events.h>
/* Currently active sensors count, per device */
static int poll_sensors_per_dev[MAX_DEVICES]; /* poll-mode sensors */
static int trig_sensors_per_dev[MAX_DEVICES]; /* trigger, event based */
ALOGI("Enabling sensor %d (iio device %d: %s)\n", s, dev_num, sensor[s].friendly_name);
switch (sensor[s].type) {
+ case SENSOR_TYPE_ACCELEROMETER:
+ accel_cal_init(s);
+ break;
+
case SENSOR_TYPE_MAGNETIC_FIELD:
- compass_read_data(&sensor[s]);
+ compass_read_data(s);
break;
case SENSOR_TYPE_GYROSCOPE:
- gyro_cal_init(&sensor[s]);
+ gyro_cal_init(s);
break;
}
} else {
/* Sensor disabled, lower report available flag */
sensor[s].report_pending = 0;
- if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
- compass_store_data(&sensor[s]);
+ /* Save calibration data to persistent storage */
+ switch (sensor[s].type) {
+ case SENSOR_TYPE_ACCELEROMETER:
+ accel_cal_store(s);
+ break;
+
+ case SENSOR_TYPE_MAGNETIC_FIELD:
+ compass_store_data(s);
+ break;
- if (sensor[s].type == SENSOR_TYPE_GYROSCOPE)
- gyro_store_data(&sensor[s]);
+ case SENSOR_TYPE_GYROSCOPE:
+ gyro_store_data(s);
+ break;
+ }
}
/* We changed the state of a sensor: adjust device ref counts */
static int get_field_count (int s, size_t *field_size)
{
*field_size = sizeof(float);
+
switch (sensor[s].type) {
case SENSOR_TYPE_ACCELEROMETER: /* m/s^2 */
case SENSOR_TYPE_MAGNETIC_FIELD: /* micro-tesla */
case SENSOR_TYPE_GYROSCOPE: /* radians/s */
return 3;
+ case SENSOR_TYPE_INTERNAL_INTENSITY:
+ case SENSOR_TYPE_INTERNAL_ILLUMINANCE:
case SENSOR_TYPE_LIGHT: /* SI lux units */
case SENSOR_TYPE_AMBIENT_TEMPERATURE: /* °C */
case SENSOR_TYPE_TEMPERATURE: /* °C */
/* Initialize data fields that will be shared by all sensor reports */
data.version = sizeof(sensors_event_t);
data.sensor = s;
- data.type = sensor[s].type;
+ data.type = sensor_desc[s].type;
num_fields = get_field_count(s, &field_size);
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];
+ char trigger_path[PATH_MAX];
ALOGV("Sampling rate %g requested on sensor %d (%s)\n", requested_rate, s, sensor[s].friendly_name);
return -ENOSYS;
}
+ if (sensor[s].hrtimer_trigger_name[0] != '\0') {
+ snprintf(trigger_path, PATH_MAX, "%s%s%d/", IIO_DEVICES, "trigger", sensor[s].trigger_nr);
+ snprintf(hrtimer_sampling_path, PATH_MAX, "%s%s", trigger_path, "sampling_frequency");
+ /* Enforce frequency update when software trigger
+ * frequency and current sampling rate are different */
+ if (sysfs_read_float(hrtimer_sampling_path, &sr) != -1 && sr != cur_sampling_rate)
+ cur_sampling_rate = -1;
+ }
+
/* Check if we have contraints on allowed sampling rates */
sprintf(avail_sysfs_path, DEVICE_AVAIL_FREQ_PATH, dev_num);
sr = strtod(cursor, NULL);
/* If this matches the selected rate, we're happy. Have some tolerance for rounding errors and avoid needless jumps to higher rates */
- if (fabs(arb_sampling_rate - sr) <= 0.001) {
+ if (fabs(arb_sampling_rate - sr) <= 0.01) {
arb_sampling_rate = sr;
break;
}
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')
+ sysfs_write_float(hrtimer_sampling_path, ceilf(arb_sampling_rate));
+
if (trig_sensors_per_dev[dev_num])
enable_buffer(dev_num, 0);
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) {
int s;
for (s=0; s<MAX_SENSORS; s++)
- if (sensor[s].dev_num == dev_num && is_enabled(s) && sensor[s].mode != MODE_POLL)
- set_report_ts(s, ts);
+ if (sensor[s].dev_num == dev_num && is_enabled(s) && sensor[s].mode != MODE_POLL) {
+ if (sensor[s].quirks & QUIRK_SPOTTY)
+ set_report_ts(s, ts);
+ else
+ sensor[s].report_ts = ts;
+ }
}
sensor[s].report_pending = DATA_TRIGGER;
sensor[s].report_initialized = 1;
- ts_offset += sr_offset;
}
/* Tentatively switch to an any-motion trigger if conditions are met */
for (s = 0; s < MAX_SENSORS; s++)
if (sensor[s].dev_num == dev_num &&
is_enabled(s)) {
+ sensor[s].event_id = event.id;
sensor[s].report_ts = ts;
sensor[s].report_pending = 1;
sensor[s].report_initialized = 1;
memcpy(data, &sensor[s].sample, sizeof(sensors_event_t));
data->sensor = s;
- data->type = sensor[s].type;
+ data->type = sensor_desc[s].type; /* sensor_desc[s].type can differ from sensor[s].type ; internal types are remapped */
return 1;
}
data->version = sizeof(sensors_event_t);
data->sensor = s;
- data->type = sensor[s].type;
+ data->type = sensor_desc[s].type; /* sensor_desc[s].type can differ from sensor[s].type ; internal types are remapped */
data->timestamp = sensor[s].report_ts;
if (sensor[s].mode == MODE_EVENT) {
ALOGV("Reporting event\n");
/* Android requires events to return 1.0 */
- data->data[0] = 1.0;
+ int dir = IIO_EVENT_CODE_EXTRACT_DIR(sensor[s].event_id);
+ switch (sensor[s].type) {
+ case SENSOR_TYPE_PROXIMITY:
+ if (dir == IIO_EV_DIR_FALLING)
+ data->data[0] = 0.0;
+ else
+ data->data[0] = 1.0;
+ break;
+ default:
+ data->data[0] = 1.0;
+ break;
+
+ }
data->data[1] = 0.0;
data->data[2] = 0.0;
return 1;