Input: zforce - add regulator handling
authorHeiko Stuebner <heiko.stuebner@bq.com>
Mon, 21 Jul 2014 17:02:11 +0000 (10:02 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 21 Jul 2014 17:28:53 +0000 (10:28 -0700)
It's possible that the controller has an individually switchable power supply.
Therefore add support to control a supplying regulator.

As this is not always the case, the regulator is requested as optional.

Signed-off-by: Heiko Stuebner <heiko.stuebner@bq.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Documentation/devicetree/bindings/input/touchscreen/zforce_ts.txt
drivers/input/touchscreen/zforce_ts.c

index 2faf1f1fa39e343c086c991abf84747a4eeb315f..80c37df940a7ecc78d1543be0ff5f6f9092f9477 100644 (file)
@@ -9,6 +9,9 @@ Required properties:
 - x-size: horizontal resolution of touchscreen
 - y-size: vertical resolution of touchscreen
 
+Optional properties:
+- vdd-supply: Regulator controlling the controller supply
+
 Example:
 
        i2c@00000000 {
@@ -18,6 +21,7 @@ Example:
                        compatible = "neonode,zforce";
                        reg = <0x50>;
                        interrupts = <2 0>;
+                       vdd-supply = <&reg_zforce_vdd>;
 
                        gpios = <&gpio5 6 0>, /* INT */
                                <&gpio5 9 0>; /* RST */
index feea85b52fa89c88ee8a213b0eb4ccf8954a2373..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;
        }