From eedb3f1f9b5d41fe5e201450d6c9ae1e6528387d Mon Sep 17 00:00:00 2001 From: Fei Mao Date: Thu, 17 Sep 2020 19:06:44 +0800 Subject: [PATCH] input: touchscreen: mxt: add callback from drm panel Add callback function from drm panel, so touch driver can be notified when panel is on or off. Change-Id: Icd80ef60db3574b3eed3f9d2b8430923580baf69 Signed-off-by: Fei Mao --- drivers/input/touchscreen/atmel_mxt_ts.c | 98 +++++++++++++++++++++--- 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index d8a90eaf7695..27eaf1d788d6 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -387,6 +387,7 @@ struct mxt_data { u32 panel_minx, panel_miny, panel_maxx, panel_maxy; u32 disp_minx, disp_miny, disp_maxx, disp_maxy; + struct notifier_block notifier; }; struct mxt_vb2_buffer { @@ -732,7 +733,7 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len, } else { if (ret >= 0) ret = -EIO; - dev_err(&client->dev, "%s: i2c send failed (%d)\n", + dev_dbg(&client->dev, "%s: i2c send failed (%d)\n", __func__, ret); } @@ -2993,7 +2994,6 @@ static int mxt_configure_objects(struct mxt_data *data, mxt_debug_init(data); - enable_irq(data->irq); return 0; } @@ -3325,18 +3325,21 @@ static void mxt_stop(struct mxt_data *data) static int mxt_input_open(struct input_dev *dev) { +#if !defined(CONFIG_DRM) struct mxt_data *data = input_get_drvdata(dev); mxt_start(data); - +#endif return 0; } static void mxt_input_close(struct input_dev *dev) { +#if !defined(CONFIG_DRM) struct mxt_data *data = input_get_drvdata(dev); mxt_stop(data); +#endif } static int mxt_parse_device_properties(struct mxt_data *data) @@ -3411,6 +3414,9 @@ static int mxt_check_dedicated_touch(struct device_node *dt, const char *prop, } #ifdef CONFIG_DRM + +static struct drm_panel *active_panel; + static int mxt_check_dt(struct device_node *np) { int i; @@ -3426,8 +3432,10 @@ static int mxt_check_dt(struct device_node *np) node = of_parse_phandle(np, "panel", i); panel = of_drm_find_panel(node); of_node_put(node); - if (!IS_ERR(panel)) + if (!IS_ERR(panel)) { + active_panel = panel; return 0; + } } return PTR_ERR(panel); @@ -3496,6 +3504,55 @@ static const struct dmi_system_id chromebook_T9_suspend_dmi[] = { { } }; +#ifdef CONFIG_DRM + +static int mxt_state_chg_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct mxt_data *mxt = container_of(nb, struct mxt_data, notifier); + struct drm_panel_notifier *evdata = data; + unsigned int blank; + struct input_dev *input_dev; + + if (!evdata) + return 0; + + if (val != DRM_PANEL_EVENT_BLANK || !mxt) + return 0; + + if (evdata->data) { + blank = *(int *) (evdata->data); + input_dev = mxt->input_dev; + switch (blank) { + case DRM_PANEL_BLANK_POWERDOWN: + if (input_dev) + mutex_lock(&input_dev->mutex); + + mxt_stop(mxt); + + if (input_dev) + mutex_unlock(&input_dev->mutex); + break; + + case DRM_PANEL_BLANK_UNBLANK: + if (input_dev) + mutex_lock(&input_dev->mutex); + + mxt_start(mxt); + + if (input_dev) + mutex_unlock(&input_dev->mutex); + break; + default: + break; + } + } + + return NOTIFY_OK; +} + +#endif + static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct mxt_data *data; @@ -3577,12 +3634,8 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) init_completion(&data->reset_completion); init_completion(&data->crc_completion); -#if defined(CONFIG_OF) && defined(CONFIG_DRM) - data->suspend_mode = MXT_SUSPEND_T9_CTRL; -#else data->suspend_mode = dmi_check_system(chromebook_T9_suspend_dmi) ? MXT_SUSPEND_T9_CTRL : MXT_SUSPEND_DEEP_SLEEP; -#endif error = mxt_parse_device_properties(data); if (error) @@ -3622,7 +3675,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) client->name, data); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); - return error; + goto err_disable_regulator; } disable_irq(client->irq); @@ -3642,8 +3695,10 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) gpiod_to_irq(data->irq_gpio); error = mxt_initialize(data); - if (error) - return error; + if (error) { + dev_err(&client->dev, "Failed to initialize device\n"); + goto err_disable_regulator; + } error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); if (error) { @@ -3652,11 +3707,21 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) goto err_free_object; } +#ifdef CONFIG_DRM + data->notifier.notifier_call = mxt_state_chg_callback; + if (active_panel) + drm_panel_notifier_register(active_panel, &data->notifier); +#endif + + data->suspended = true; return 0; err_free_object: mxt_free_input_device(data); mxt_free_object_table(data); + +err_disable_regulator: + mxt_regulator_disable(data); return error; } @@ -3664,7 +3729,14 @@ static int mxt_remove(struct i2c_client *client) { struct mxt_data *data = i2c_get_clientdata(client); +#ifdef CONFIG_DRM + if (active_panel) + drm_panel_notifier_unregister(active_panel, &data->notifier); +#endif + disable_irq(data->irq); + mxt_regulator_disable(data); + sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); mxt_free_input_device(data); mxt_free_object_table(data); @@ -3674,6 +3746,7 @@ static int mxt_remove(struct i2c_client *client) static int __maybe_unused mxt_suspend(struct device *dev) { +#if !defined(CONFIG_DRM) struct i2c_client *client = to_i2c_client(dev); struct mxt_data *data = i2c_get_clientdata(client); struct input_dev *input_dev = data->input_dev; @@ -3689,12 +3762,14 @@ static int __maybe_unused mxt_suspend(struct device *dev) mutex_unlock(&input_dev->mutex); disable_irq(data->irq); +#endif return 0; } static int __maybe_unused mxt_resume(struct device *dev) { +#if !defined(CONFIG_DRM) struct i2c_client *client = to_i2c_client(dev); struct mxt_data *data = i2c_get_clientdata(client); struct input_dev *input_dev = data->input_dev; @@ -3710,6 +3785,7 @@ static int __maybe_unused mxt_resume(struct device *dev) mxt_start(data); mutex_unlock(&input_dev->mutex); +#endif return 0; }