Handle regulators used on this chip family, namely AVDD and VDD. These definitions are taken from the GPLv2 licensed vendor driver. Signed-off-by: Felix Kaechele <felix@xxxxxxxxxxx> Link: https://github.com/HimaxSoftware/HX83112_Android_Driver --- drivers/input/touchscreen/himax_hx83112b.c | 48 ++++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c index 4f6609dcdef3..0a797789e548 100644 --- a/drivers/input/touchscreen/himax_hx83112b.c +++ b/drivers/input/touchscreen/himax_hx83112b.c @@ -19,10 +19,12 @@ #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #define HIMAX_ID_83112B 0x83112b #define HIMAX_MAX_POINTS 10 +#define HIMAX_MAX_SUPPLIES 2 #define HIMAX_REG_CFG_SET_ADDR 0x00 #define HIMAX_REG_CFG_INIT_READ 0x0c @@ -50,6 +52,7 @@ struct himax_event { static_assert(sizeof(struct himax_event) == 56); struct himax_ts_data { + struct regulator_bulk_data supplies[HIMAX_MAX_SUPPLIES]; struct gpio_desc *gpiod_rst; struct input_dev *input_dev; struct i2c_client *client; @@ -63,6 +66,11 @@ static const struct regmap_config himax_regmap_config = { .val_format_endian = REGMAP_ENDIAN_LITTLE, }; +static const char *const himax_supply_names[] = { + "avdd", + "vdd", +}; + static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst) { int error; @@ -267,7 +275,7 @@ static irqreturn_t himax_irq_handler(int irq, void *dev_id) static int himax_probe(struct i2c_client *client) { - int error; + int error, i; struct device *dev = &client->dev; struct himax_ts_data *ts; @@ -290,11 +298,31 @@ static int himax_probe(struct i2c_client *client) return error; } + int num_supplies = ARRAY_SIZE(himax_supply_names); + + for (i = 0; i < num_supplies; i++) + ts->supplies[i].supply = himax_supply_names[i]; + + error = devm_regulator_bulk_get(dev, + num_supplies, + ts->supplies); + if (error) { + dev_err(dev, "Failed to get supplies: %d\n", error); + return error; + } + + error = regulator_bulk_enable(num_supplies, + ts->supplies); + if (error) { + dev_err(dev, "Failed to enable supplies: %d\n", error); + goto error_out; + } + ts->gpiod_rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); error = PTR_ERR_OR_ZERO(ts->gpiod_rst); if (error) { dev_err(dev, "Failed to get reset GPIO: %d\n", error); - return error; + goto error_out; } himax_reset(ts); @@ -305,15 +333,26 @@ static int himax_probe(struct i2c_client *client) error = himax_input_register(ts); if (error) - return error; + goto error_out; error = devm_request_threaded_irq(dev, client->irq, NULL, himax_irq_handler, IRQF_ONESHOT, client->name, ts); if (error) - return error; + goto error_out; return 0; + +error_out: + regulator_bulk_disable(num_supplies, ts->supplies); + return error; +} + +static void himax_remove(struct i2c_client *client) +{ + struct himax_ts_data *ts = i2c_get_clientdata(client); + + regulator_bulk_disable(ARRAY_SIZE(himax_supply_names), ts->supplies); } static int himax_suspend(struct device *dev) @@ -350,6 +389,7 @@ MODULE_DEVICE_TABLE(of, himax_of_match); static struct i2c_driver himax_ts_driver = { .probe = himax_probe, + .remove = himax_remove, .id_table = himax_ts_id, .driver = { .name = "Himax-hx83112b-TS", -- 2.44.0