Input: zforce - add regulator handling
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / zforce_ts.c
index 01d30cedde460f7f54f49ac72ad744b080fcfcb6..8ba48f5eff7bfefebde28d38ea69e71e640e086a 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/sysfs.h>
 #include <linux/input/mt.h>
 #include <linux/platform_data/zforce_ts.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 
@@ -117,6 +119,8 @@ struct zforce_ts {
        const struct zforce_ts_platdata *pdata;
        char                    phys[32];
 
+       struct regulator        *reg_vdd;
+
        bool                    suspending;
        bool                    suspended;
        bool                    boot_complete;
@@ -690,6 +694,11 @@ static void zforce_reset(void *data)
        struct zforce_ts *ts = data;
 
        gpio_set_value(ts->pdata->gpio_rst, 0);
+
+       udelay(10);
+
+       if (!IS_ERR(ts->reg_vdd))
+               regulator_disable(ts->reg_vdd);
 }
 
 static struct zforce_ts_platdata *zforce_parse_dt(struct device *dev)
@@ -765,10 +774,32 @@ static int zforce_probe(struct i2c_client *client,
                return ret;
        }
 
+       ts->reg_vdd = devm_regulator_get_optional(&client->dev, "vdd");
+       if (IS_ERR(ts->reg_vdd)) {
+               ret = PTR_ERR(ts->reg_vdd);
+               if (ret == -EPROBE_DEFER)
+                       return ret;
+       } else {
+               ret = regulator_enable(ts->reg_vdd);
+               if (ret)
+                       return ret;
+
+               /*
+                * according to datasheet add 100us grace time after regular
+                * regulator enable delay.
+                */
+               udelay(100);
+       }
+
        ret = devm_add_action(&client->dev, zforce_reset, ts);
        if (ret) {
                dev_err(&client->dev, "failed to register reset action, %d\n",
                        ret);
+
+               /* hereafter the regulator will be disabled by the action */
+               if (!IS_ERR(ts->reg_vdd))
+                       regulator_disable(ts->reg_vdd);
+
                return ret;
        }
 
@@ -880,7 +911,7 @@ static struct i2c_device_id zforce_idtable[] = {
 MODULE_DEVICE_TABLE(i2c, zforce_idtable);
 
 #ifdef CONFIG_OF
-static struct of_device_id zforce_dt_idtable[] = {
+static const struct of_device_id zforce_dt_idtable[] = {
        { .compatible = "neonode,zforce" },
        {},
 };