Commit ae97fb58 authored by Jagan Teki's avatar Jagan Teki Committed by Dmitry Torokhov

Input: goodix - add regulators suppot

Goodix CTP controllers require AVDD28, VDDIO regulators for power-on
sequence.

The delay between these regualtor operations as per Power-on Timing
from datasheet[1] is 0 (T1 >= 0 usec).

So, enable and disable these regulators in proper order using normal
regulator functions without any delay in between.

[1] GT5663 Datasheet_English_20151106_Rev.01
Signed-off-by: default avatarJagan Teki <jagan@amarulasolutions.com>
Reviewed-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent ecdf3a96
...@@ -19,6 +19,8 @@ Optional properties: ...@@ -19,6 +19,8 @@ Optional properties:
- irq-gpios : GPIO pin used for IRQ. The driver uses the - irq-gpios : GPIO pin used for IRQ. The driver uses the
interrupt gpio pin as output to reset the device. interrupt gpio pin as output to reset the device.
- reset-gpios : GPIO pin used for reset - reset-gpios : GPIO pin used for reset
- AVDD28-supply : Analog power supply regulator on AVDD28 pin
- VDDIO-supply : GPIO power supply regulator on VDDIO pin
- touchscreen-inverted-x - touchscreen-inverted-x
- touchscreen-inverted-y - touchscreen-inverted-y
- touchscreen-size-x - touchscreen-size-x
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -47,6 +48,8 @@ struct goodix_ts_data { ...@@ -47,6 +48,8 @@ struct goodix_ts_data {
struct touchscreen_properties prop; struct touchscreen_properties prop;
unsigned int max_touch_num; unsigned int max_touch_num;
unsigned int int_trigger_type; unsigned int int_trigger_type;
struct regulator *avdd28;
struct regulator *vddio;
struct gpio_desc *gpiod_int; struct gpio_desc *gpiod_int;
struct gpio_desc *gpiod_rst; struct gpio_desc *gpiod_rst;
u16 id; u16 id;
...@@ -532,6 +535,24 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) ...@@ -532,6 +535,24 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
return -EINVAL; return -EINVAL;
dev = &ts->client->dev; dev = &ts->client->dev;
ts->avdd28 = devm_regulator_get(dev, "AVDD28");
if (IS_ERR(ts->avdd28)) {
error = PTR_ERR(ts->avdd28);
if (error != -EPROBE_DEFER)
dev_err(dev,
"Failed to get AVDD28 regulator: %d\n", error);
return error;
}
ts->vddio = devm_regulator_get(dev, "VDDIO");
if (IS_ERR(ts->vddio)) {
error = PTR_ERR(ts->vddio);
if (error != -EPROBE_DEFER)
dev_err(dev,
"Failed to get VDDIO regulator: %d\n", error);
return error;
}
/* Get the interrupt GPIO pin number */ /* Get the interrupt GPIO pin number */
gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN); gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN);
if (IS_ERR(gpiod)) { if (IS_ERR(gpiod)) {
...@@ -764,6 +785,14 @@ static void goodix_config_cb(const struct firmware *cfg, void *ctx) ...@@ -764,6 +785,14 @@ static void goodix_config_cb(const struct firmware *cfg, void *ctx)
complete_all(&ts->firmware_loading_complete); complete_all(&ts->firmware_loading_complete);
} }
static void goodix_disable_regulators(void *arg)
{
struct goodix_ts_data *ts = arg;
regulator_disable(ts->vddio);
regulator_disable(ts->avdd28);
}
static int goodix_ts_probe(struct i2c_client *client, static int goodix_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -789,6 +818,29 @@ static int goodix_ts_probe(struct i2c_client *client, ...@@ -789,6 +818,29 @@ static int goodix_ts_probe(struct i2c_client *client,
if (error) if (error)
return error; return error;
/* power up the controller */
error = regulator_enable(ts->avdd28);
if (error) {
dev_err(&client->dev,
"Failed to enable AVDD28 regulator: %d\n",
error);
return error;
}
error = regulator_enable(ts->vddio);
if (error) {
dev_err(&client->dev,
"Failed to enable VDDIO regulator: %d\n",
error);
regulator_disable(ts->avdd28);
return error;
}
error = devm_add_action_or_reset(&client->dev,
goodix_disable_regulators, ts);
if (error)
return error;
if (ts->gpiod_int && ts->gpiod_rst) { if (ts->gpiod_int && ts->gpiod_rst) {
/* reset the controller */ /* reset the controller */
error = goodix_reset(ts); error = goodix_reset(ts);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment