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

Commit ac72f8b4 authored by Bingzhe Cai's avatar Bingzhe Cai
Browse files

input: sensors: report accurate timestamp on apds993x driver



Reporting accurate timestamp provides better reference to
sensor application. As input system will ignore sensor event
if its value doesn't change, report accurate timestamp along
with sensor event to allow input system report each sensor
event.

CRs-fixed: 778265
Change-Id: I99aaf1f1a6c275d58c71974d1f75668b3b8c86d0
Signed-off-by: default avatarBingzhe Cai <bingzhec@codeaurora.org>
parent 42162e39
Loading
Loading
Loading
Loading
+47 −18
Original line number Diff line number Diff line
/*
 * apds993x.c - Linux kernel modules for ambient light + proximity sensor
 *
 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 * Copyright (C) 2012 Lee Kai Koon <kai-koon.lee@avagotech.com>
 * Copyright (C) 2012 Avago Technologies
 * Copyright (C) 2013 LGE Inc.
@@ -560,6 +561,36 @@ static int apds993x_set_control(struct i2c_client *client, int control)
	return ret;
}

static void apds993x_report_ps_event(struct input_dev *ps_dev,
			const unsigned int dist)
{
	ktime_t ts;

	ts = ktime_get();

	input_event(ps_dev, EV_SYN, SYN_TIME_SEC,
			ktime_to_timespec(ts).tv_sec);
	input_event(ps_dev, EV_SYN, SYN_TIME_NSEC,
			ktime_to_timespec(ts).tv_nsec);
	input_report_abs(ps_dev, ABS_DISTANCE, dist);
	input_sync(ps_dev);
}

static void apds993x_report_als_event(struct input_dev *als_dev,
			const unsigned int lux)
{
	ktime_t ts;

	ts = ktime_get();

	input_event(als_dev, EV_SYN, SYN_TIME_SEC,
				ktime_to_timespec(ts).tv_sec);
	input_event(als_dev, EV_SYN, SYN_TIME_NSEC,
		ktime_to_timespec(ts).tv_nsec);
	input_report_abs(als_dev, ABS_MISC, lux);
	input_sync(als_dev);
}

/*calibration*/
void apds993x_swap(int *x, int *y)
{
@@ -725,8 +756,7 @@ static void apds993x_change_ps_threshold(struct i2c_client *client)
		data->ps_detection = 1;

		/* FAR-to-NEAR detection */
		input_report_abs(data->input_dev_ps, ABS_DISTANCE, 0);
		input_sync(data->input_dev_ps);
		apds993x_report_ps_event(data->input_dev_ps, 0);

		i2c_smbus_write_word_data(client,
				CMD_WORD|APDS993X_PILTL_REG,
@@ -744,8 +774,7 @@ static void apds993x_change_ps_threshold(struct i2c_client *client)
		data->ps_detection = 0;

		/* NEAR-to-FAR detection */
		input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);
		input_sync(data->input_dev_ps);
		apds993x_report_ps_event(data->input_dev_ps, 1);

		i2c_smbus_write_word_data(client,
				CMD_WORD|APDS993X_PILTL_REG, 0);
@@ -779,6 +808,9 @@ static void apds993x_change_als_threshold(struct i2c_client *client)
	if (luxValue >= 0) {
		luxValue = (luxValue < ALS_MAX_RANGE)
					? luxValue : ALS_MAX_RANGE;
		if (luxValue == data->als_prev_lux)
			lux_is_valid = 0;
		else
			data->als_prev_lux = luxValue;
	} else {
		/* don't report, the lux is invalid value */
@@ -807,8 +839,7 @@ static void apds993x_change_als_threshold(struct i2c_client *client)
		 * from the PS
		 */
		/* NEAR-to-FAR detection */
		input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);
		input_sync(data->input_dev_ps);
		apds993x_report_ps_event(data->input_dev_ps, 1);

		i2c_smbus_write_word_data(client,
				CMD_WORD|APDS993X_PILTL_REG, 0);
@@ -825,11 +856,9 @@ static void apds993x_change_als_threshold(struct i2c_client *client)
		pr_info("%s: FAR\n", __func__);
	}

	if (lux_is_valid) {
	if (lux_is_valid)
		/* report the lux level */
		input_report_abs(data->input_dev_als, ABS_MISC, luxValue);
		input_sync(data->input_dev_als);
	}
		apds993x_report_als_event(data->input_dev_als, luxValue);

	data->als_data = ch0data;

@@ -914,6 +943,9 @@ static void apds993x_als_polling_work_handler(struct work_struct *work)
	if (luxValue >= 0) {
		luxValue = (luxValue < ALS_MAX_RANGE)
					? luxValue : ALS_MAX_RANGE;
		if (luxValue == data->als_prev_lux)
			lux_is_valid = 0;
		else
			data->als_prev_lux = luxValue;
	} else {
		/* don't report, this is invalid lux value */
@@ -942,8 +974,7 @@ static void apds993x_als_polling_work_handler(struct work_struct *work)
		 * from the PS
		 */
		/* NEAR-to-FAR detection */
		input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);
		input_sync(data->input_dev_ps);
		apds993x_report_ps_event(data->input_dev_ps, 1);

		i2c_smbus_write_word_data(client,
				CMD_WORD|APDS993X_PILTL_REG, 0);
@@ -958,11 +989,9 @@ static void apds993x_als_polling_work_handler(struct work_struct *work)
		pr_info("%s: FAR\n", __func__);
	}

	if (lux_is_valid) {
	if (lux_is_valid)
		/* report the lux level */
		input_report_abs(data->input_dev_als, ABS_MISC, luxValue);
		input_sync(data->input_dev_als);
	}
		apds993x_report_als_event(data->input_dev_als, luxValue);

	data->als_data = ch0data;