Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac87aa0d authored by Oliver Wang's avatar Oliver Wang
Browse files

input: sensors: change sensor batching interface



The new Android sensor HAL requires more interfaces to communicate with
sensors driver. Change batching interface to meet the requirements. Sensor
drivers can use the interfaces to provide more features.

Change-Id: I7f3cbdcaa6f5473b038d1cdc07eb34685c1fca23
Signed-off-by: default avatarOliver Wang <mengmeng@codeaurora.org>
parent f533df78
Loading
Loading
Loading
Loading
+60 −15
Original line number Diff line number Diff line
@@ -283,6 +283,7 @@ struct lis3dh_acc_data {
	unsigned int delay_ms;
	unsigned int batch_mode;
	unsigned int fifo_timeout_ms;
	unsigned int flush_count;
	int irq1;
	int irq2;

@@ -301,16 +302,17 @@ static struct sensors_classdev lis3dh_acc_cdev = {
	.resolution = "0.01",
	.sensor_power = "0.01",
	.min_delay = 10000,
	.max_delay = 6400,
	.delay_msec = 200,
	.fifo_reserved_event_count = 0,
	.fifo_max_event_count = 0,
	.enabled = 0,
	.batch_enable = 0,
	.batch_mode = BATCH_MODE_NORMAL,
	.batch_timeout_ms = 0,
	.max_latency = 0,
	.flags = 0,
	.sensors_enable = NULL,
	.sensors_batch = NULL,
	.sensors_poll_delay = NULL,
	.sensors_set_latency = NULL,
	.sensors_flush = NULL,
};

struct sensor_regulator {
@@ -1620,6 +1622,54 @@ static int remove_sysfs_interfaces(struct device *dev)
	return 0;
}

static int lis3dh_acc_flush(struct sensors_classdev *sensors_cdev)
{
	struct lis3dh_acc_data *acc = container_of(sensors_cdev,
			struct lis3dh_acc_data, cdev);
	s64 timestamp;
	int err;
	int fifo_cnt;
	int i;
	u32 time_h, time_l, time_ms;
	int xyz[3] = {0};

	timestamp = lis3dh_acc_get_time_ns();
	time_ms = lis3dh_acc_odr_to_interval(acc,
			(acc->resume_state[RES_CTRL_REG1] >> 4));
	fifo_cnt = lis3dh_acc_get_fifo_lvl(acc);
	dev_dbg(&acc->client->dev, "TS: base=%lld, interval=%d fifo_cnt=%d\n",
			timestamp, time_ms, fifo_cnt);
	timestamp = timestamp -
		((s64)time_ms * LIS3DH_TIME_MS_TO_NS * fifo_cnt);

	for (i = 0; i < fifo_cnt; i++) {
		err = lis3dh_acc_get_acceleration_data(acc, xyz);
		if (err < 0) {
			dev_err(&acc->client->dev,
					"get_acceleration_data failed\n");
			goto exit;
		} else {
			timestamp = timestamp +
				(time_ms * LIS3DH_TIME_MS_TO_NS);
			time_h = (u32)(((u64)timestamp >> 32) & 0xFFFFFFFF);
			time_l = (u32)(timestamp & 0xFFFFFFFF);

			input_report_abs(acc->input_dev, ABS_RX,
					time_h);
			input_report_abs(acc->input_dev, ABS_RY,
					time_l);
			lis3dh_acc_report_values(acc, xyz);
		}
	}

	input_event(acc->input_dev, EV_SYN, SYN_CONFIG, acc->flush_count++);
	input_sync(acc->input_dev);

	return 0;
exit:
	return err;
}

static int lis3dh_acc_poll_delay_set(struct sensors_classdev *sensors_cdev,
	unsigned int delay_msec)
{
@@ -1683,12 +1733,8 @@ static int lis3dh_acc_enable_set(struct sensors_classdev *sensors_cdev,
	}
	return err;
}

static int lis3dh_batch_set(struct sensors_classdev *cdev,
					unsigned int enable,
					unsigned int mode,
					unsigned int period_ms,
					unsigned int timeout_ms)
static int lis3dh_latency_set(struct sensors_classdev *cdev,
					unsigned int max_latency)
{
	struct lis3dh_acc_data *acc = container_of(cdev,
		struct lis3dh_acc_data, cdev);
@@ -1700,10 +1746,8 @@ static int lis3dh_batch_set(struct sensors_classdev *cdev,
			"Cannot set batch mode, interrupt is not enabled!\n");
		return -EPERM;
	}
	acc->use_batch = enable ? true : false;
	acc->delay_ms = period_ms;
	acc->batch_mode = mode;
	acc->fifo_timeout_ms = timeout_ms;
	acc->use_batch = max_latency ? true : false;
	acc->fifo_timeout_ms = max_latency;
	return 0;
}

@@ -2128,7 +2172,8 @@ static int lis3dh_acc_probe(struct i2c_client *client,
	acc->cdev.sensors_poll_delay = lis3dh_acc_poll_delay_set;
	/* batch is possiable only when interrupt is enabled */
	if (gpio_is_valid(acc->pdata->gpio_int1) && acc->pdata->enable_int) {
		acc->cdev.sensors_batch = lis3dh_batch_set;
		acc->cdev.sensors_set_latency = lis3dh_latency_set;
		acc->cdev.sensors_flush = lis3dh_acc_flush;
		acc->cdev.fifo_reserved_event_count = LIS3DH_FIFO_SIZE;
		acc->cdev.fifo_max_event_count = LIS3DH_FIFO_SIZE;
	}
+41 −30
Original line number Diff line number Diff line
@@ -127,6 +127,20 @@ static ssize_t sensors_type_show(struct device *dev,
	return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->type);
}

static ssize_t sensors_max_delay_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->max_delay);
}

static ssize_t sensors_flags_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE, "%d\n", sensors_cdev->flags);
}

static ssize_t sensors_max_range_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
@@ -261,55 +275,49 @@ static ssize_t sensors_test_show(struct device *dev,
			ret ? "fail" : "pass");
}

static ssize_t sensors_batch_store(struct device *dev,
static ssize_t sensors_max_latency_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
	unsigned int enable, mode, period_ms, timeout_ms;
	unsigned long latency;
	int ret = -EINVAL;

	ret = sscanf(buf, "enable=%u, mode=%u, period_ms=%u, timeout_ms=%u",
		&enable, &mode, &period_ms, &timeout_ms);
	ret = kstrtoul(buf, 10, &latency);
	if (ret)
		return ret;

	if (ret != 4)
		return -EINVAL;
	if (enable && (timeout_ms == 0)) {
		dev_err(dev,
			"Cannot set timeout to zero while enable batch mode\n");
	if (latency > sensors_cdev->max_delay) {
		dev_err(dev, "max_latency(%lu) is greater than max_delay(%u)\n",
				latency, sensors_cdev->max_delay);
		return -EINVAL;
	}
	if (enable && ((period_ms * 1000) < sensors_cdev->min_delay)) {
		dev_err(dev,
			"batch: invalid value of delay, delay(ms)=%u\n",
				period_ms);

	if (sensors_cdev->sensors_set_latency == NULL) {
		dev_err(dev, "Invalid sensor calss set latency handle\n");
		return -EINVAL;
	}
	if (sensors_cdev->sensors_batch == NULL) {
		dev_err(dev, "Invalid sensor class batch handle\n");

	/* Disable batching for this sensor */
	if (latency < sensors_cdev->delay_msec) {
		dev_err(dev, "max_latency is less than delay_msec\n");
		return -EINVAL;
	}
	ret = sensors_cdev->sensors_batch(sensors_cdev,
			enable, mode, period_ms, timeout_ms);

	ret = sensors_cdev->sensors_set_latency(sensors_cdev, latency);
	if (ret)
		return ret;

	sensors_cdev->batch_enable = enable;
	sensors_cdev->batch_mode = mode;
	sensors_cdev->delay_msec = period_ms;
	sensors_cdev->batch_timeout_ms = timeout_ms;
	sensors_cdev->max_latency = latency;

	return size;
}

static ssize_t sensors_batch_show(struct device *dev,
static ssize_t sensors_max_latency_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct sensors_classdev *sensors_cdev = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE,
		"enable=%u, mode=%u, period_ms=%u, timeout_ms=%u\n",
			sensors_cdev->batch_enable,
			sensors_cdev->batch_mode,
			sensors_cdev->delay_msec,
			sensors_cdev->batch_timeout_ms);
		"%u\n", sensors_cdev->max_latency);
}

static ssize_t sensors_flush_store(struct device *dev,
@@ -455,13 +463,16 @@ static struct device_attribute sensors_class_attrs[] = {
	__ATTR(min_delay, 0444, sensors_min_delay_show, NULL),
	__ATTR(fifo_reserved_event_count, 0444, sensors_fifo_event_show, NULL),
	__ATTR(fifo_max_event_count, 0444, sensors_fifo_max_show, NULL),
	__ATTR(max_delay, 0444, sensors_max_delay_show, NULL),
	__ATTR(flags, 0444, sensors_flags_show, NULL),
	__ATTR(enable, 0664, sensors_enable_show, sensors_enable_store),
	__ATTR(enable_wakeup, 0664, sensors_enable_wakeup_show,
			sensors_enable_wakeup_store),
	__ATTR(poll_delay, 0664, sensors_delay_show, sensors_delay_store),
	__ATTR(self_test, 0440, sensors_test_show, NULL),
	__ATTR(batch, 0660, sensors_batch_show, sensors_batch_store),
	__ATTR(max_latency, 0660, sensors_max_latency_show,
			sensors_max_latency_store),
	__ATTR(flush, 0660, sensors_flush_show, sensors_flush_store),
	__ATTR(enable_wakeup, 0660, sensors_enable_wakeup_show,
			sensors_enable_wakeup_store),
	__ATTR(calibrate, 0664, sensors_calibrate_show,
			sensors_calibrate_store),
	__ATTR_NULL,
+15 −11
Original line number Diff line number Diff line
@@ -106,12 +106,18 @@ struct cal_result_t {
 *				in the batch mode FIFO.
 * @fifo_max_event_count:	The maximum number of events of this sensor
 *				that could be batched.
 * @max_delay:		The slowest rate the sensor supports in millisecond.
 * @flags:		Should be '1' if the sensor is a wake up sensor.
 *			set it to '0' otherwise.
 * @enabled:		Store the sensor driver enable status.
 * @delay_msec:		Store the sensor driver delay value. The data unit is
 *			millisecond.
 * @wakeup:		Indicate if the wake up interrupt has been enabled
 * @wakeup:		Indicate if the wake up interrupt has been enabled.
 * @max_latency:	Max report latency in millisecond
 * @sensors_enable:	The handle for enable and disable sensor.
 * @sensors_poll_delay:	The handle for set the sensor polling delay time.
 * @sensors_set_latency:Set the max report latency of the sensor.
 * @sensors_flush:	Flush sensor events in FIFO and report it to user space.
 * @params		The sensor calibrate string format params up to userspace.
 * @cal_result		The sensor calibrate parameters, cal_result is a struct for sensor.
 */
@@ -129,12 +135,13 @@ struct sensors_classdev {
	int			min_delay;
	int			fifo_reserved_event_count;
	int			fifo_max_event_count;
	int32_t			max_delay;
	uint32_t		flags;

	unsigned int		enabled;
	unsigned int		batch_enable;
	unsigned int		batch_mode;
	unsigned int		delay_msec;
	unsigned int		batch_timeout_ms;
	unsigned int		wakeup;
	unsigned int		max_latency;
	char			*params;
	struct cal_result_t	cal_result;
	/* enable and disable the sensor handle*/
@@ -143,14 +150,11 @@ struct sensors_classdev {
	int	(*sensors_poll_delay)(struct sensors_classdev *sensors_cdev,
					unsigned int delay_msec);
	int	(*sensors_self_test)(struct sensors_classdev *sensors_cdev);
	int	(*sensors_batch)(struct sensors_classdev *sensor_cdev,
					unsigned int enable,
					unsigned int mode,
					unsigned int period_ms,
					unsigned int timeout_ms);
	int	(*sensors_flush)(struct sensors_classdev *sensors_cdev);
	int	(*sensors_enable_wakeup)(struct sensors_classdev *sensors_cdev,
	int	(*sensors_set_latency)(struct sensors_classdev *sensor_cdev,
					unsigned int max_latency);
	int	(*sensors_enable_wakeup)(struct sensors_classdev *sensor_cdev,
					unsigned int enable);
	int	(*sensors_flush)(struct sensors_classdev *sensors_cdev);
	int	(*sensors_calibrate)(struct sensors_classdev *sensor_cdev,
					int axis, int apply_now);
	int	(*sensors_write_cal_params)(struct sensors_classdev