diff options
Diffstat (limited to 'drivers/input/touchscreen/atmel_mxt_ts.c')
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index b6f75367a284..383a848eb601 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -24,6 +24,7 @@ #include <linux/of.h> #include <linux/property.h> #include <linux/slab.h> +#include <linux/regulator/consumer.h> #include <linux/gpio/consumer.h> #include <asm/unaligned.h> #include <media/v4l2-device.h> @@ -309,6 +310,7 @@ struct mxt_data { u8 multitouch; struct t7_config t7_cfg; struct mxt_dbg dbg; + struct regulator_bulk_data regulators[2]; struct gpio_desc *reset_gpio; bool use_retrigen_workaround; @@ -606,7 +608,6 @@ recheck: static int mxt_send_bootloader_cmd(struct mxt_data *data, bool unlock) { - int ret; u8 buf[2]; if (unlock) { @@ -617,11 +618,7 @@ static int mxt_send_bootloader_cmd(struct mxt_data *data, bool unlock) buf[1] = 0x01; } - ret = mxt_bootloader_write(data, buf, 2); - if (ret) - return ret; - - return 0; + return mxt_bootloader_write(data, buf, sizeof(buf)); } static int __mxt_read_reg(struct i2c_client *client, @@ -3134,8 +3131,24 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) if (error) return error; + /* + * VDDA is the analog voltage supply 2.57..3.47 V + * VDD is the digital voltage supply 1.71..3.47 V + */ + data->regulators[0].supply = "vdda"; + data->regulators[1].supply = "vdd"; + error = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(data->regulators), + data->regulators); + if (error) { + if (error != -EPROBE_DEFER) + dev_err(&client->dev, "Failed to get regulators %d\n", + error); + return error; + } + + /* Request the RESET line as asserted so we go into reset */ data->reset_gpio = devm_gpiod_get_optional(&client->dev, - "reset", GPIOD_OUT_LOW); + "reset", GPIOD_OUT_HIGH); if (IS_ERR(data->reset_gpio)) { error = PTR_ERR(data->reset_gpio); dev_err(&client->dev, "Failed to get reset gpio: %d\n", error); @@ -3152,15 +3165,29 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) disable_irq(client->irq); + error = regulator_bulk_enable(ARRAY_SIZE(data->regulators), + data->regulators); + if (error) { + dev_err(&client->dev, "failed to enable regulators: %d\n", + error); + return error; + } + /* + * The device takes 40ms to come up after power-on according + * to the mXT224 datasheet, page 13. + */ + msleep(MXT_BACKUP_TIME); + if (data->reset_gpio) { + /* Wait a while and then de-assert the RESET GPIO line */ msleep(MXT_RESET_GPIO_TIME); - gpiod_set_value(data->reset_gpio, 1); + gpiod_set_value(data->reset_gpio, 0); msleep(MXT_RESET_INVALID_CHG); } error = mxt_initialize(data); if (error) - return error; + goto err_disable_regulators; error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); if (error) { @@ -3174,6 +3201,9 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) err_free_object: mxt_free_input_device(data); mxt_free_object_table(data); +err_disable_regulators: + regulator_bulk_disable(ARRAY_SIZE(data->regulators), + data->regulators); return error; } @@ -3185,6 +3215,8 @@ static int mxt_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); mxt_free_input_device(data); mxt_free_object_table(data); + regulator_bulk_disable(ARRAY_SIZE(data->regulators), + data->regulators); return 0; } @@ -3200,7 +3232,7 @@ static int __maybe_unused mxt_suspend(struct device *dev) mutex_lock(&input_dev->mutex); - if (input_dev->users) + if (input_device_enabled(input_dev)) mxt_stop(data); mutex_unlock(&input_dev->mutex); @@ -3223,7 +3255,7 @@ static int __maybe_unused mxt_resume(struct device *dev) mutex_lock(&input_dev->mutex); - if (input_dev->users) + if (input_device_enabled(input_dev)) mxt_start(data); mutex_unlock(&input_dev->mutex); |