Add inhibit/uninhibit functions. Signed-off-by: Jingle.wu <jingle.wu@xxxxxxxxxx> --- drivers/input/mouse/elan_i2c_core.c | 86 +++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 5f0d75a45c80..b7100945c9cc 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -329,6 +329,89 @@ static int elan_initialize(struct elan_tp_data *data, bool skip_reset) return error; } +static int elan_reactivate(struct elan_tp_data *data) +{ + struct device *dev = &data->client->dev; + int ret; + + ret = elan_set_power(data, true); + if (ret) + dev_err(dev, "failed to restore power: %d\n", ret); + + ret = data->ops->sleep_control(data->client, false); + if (ret) { + dev_err(dev, + "failed to wake device up: %d\n", ret); + return ret; + } + + return ret; +} + +static void elan_inhibit(struct input_dev *input_dev) +{ + struct elan_tp_data *data = input_get_drvdata(input_dev); + struct i2c_client *client = data->client; + int ret; + + if (data->in_fw_update) + return; + + dev_dbg(&client->dev, "inhibiting\n"); + /* + * We are taking the mutex to make sure sysfs operations are + * complete before we attempt to bring the device into low[er] + * power mode. + */ + ret = mutex_lock_interruptible(&data->sysfs_mutex); + if (ret) + return; + + disable_irq(client->irq); + + ret = elan_set_power(data, false); + if (ret) + enable_irq(client->irq); + + mutex_unlock(&data->sysfs_mutex); + +} + +static void elan_close(struct input_dev *input_dev) +{ + if ((input_dev->users) && (!input_dev->inhibited)) + elan_inhibit(input_dev); + +} + +static int elan_uninhibit(struct input_dev *input_dev) +{ + struct elan_tp_data *data = input_get_drvdata(input_dev); + struct i2c_client *client = data->client; + int ret; + + dev_dbg(&client->dev, "uninhibiting\n"); + ret = mutex_lock_interruptible(&data->sysfs_mutex); + if (ret) + return ret; + + ret = elan_reactivate(data); + if (ret == 0) + enable_irq(client->irq); + + mutex_unlock(&data->sysfs_mutex); + + return ret; +} + +static int elan_open(struct input_dev *input_dev) +{ + if ((input_dev->users) && (input_dev->inhibited)) + return elan_uninhibit(input_dev); + + return 0; +} + static int elan_query_device_info(struct elan_tp_data *data) { int error; @@ -1175,6 +1258,9 @@ static int elan_setup_input_device(struct elan_tp_data *data) 0, ETP_FINGER_WIDTH * min_width, 0, 0); } + input->open = elan_open; + input->close = elan_close; + data->input = input; return 0; base-commit: 38e04b3e4240a6d8fb43129ebad41608db64bc6f -- 2.34.1