diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 2c233c54a5fe..7ef74c82d8d3 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); } @@ -2995,7 +2996,6 @@ static int mxt_configure_objects(struct mxt_data *data, mxt_debug_init(data); - enable_irq(data->irq); return 0; } @@ -3327,18 +3327,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) @@ -3413,6 +3416,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; @@ -3428,8 +3434,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); @@ -3498,6 +3506,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; @@ -3579,12 +3636,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) @@ -3624,7 +3677,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); @@ -3644,8 +3697,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) { @@ -3654,11 +3709,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; } @@ -3666,7 +3731,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); @@ -3676,6 +3748,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; @@ -3691,12 +3764,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; @@ -3712,6 +3787,7 @@ static int __maybe_unused mxt_resume(struct device *dev) mxt_start(data); mutex_unlock(&input_dev->mutex); +#endif return 0; }