[media] mt9v032: Add reset and standby gpios
authorMarkus Pargmann <mpa@pengutronix.de>
Mon, 14 Dec 2015 14:41:51 +0000 (12:41 -0200)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Mon, 25 Jan 2016 17:15:34 +0000 (15:15 -0200)
Add optional reset and standby gpios. The reset gpio is used to reset
the chip in power_on().

The standby gpio is not used currently. It is just unset, so the chip is
not in standby.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Documentation/devicetree/bindings/media/i2c/mt9v032.txt
drivers/media/i2c/mt9v032.c

index 202565313e825fe897e03a05849fa54765efe2fe..100f0ae432691c36ff54609c86a8cc984b9a5b7d 100644 (file)
@@ -20,6 +20,8 @@ Optional Properties:
 
 - link-frequencies: List of allowed link frequencies in Hz. Each frequency is
        expressed as a 64-bit big-endian integer.
+- reset-gpios: GPIO handle which is connected to the reset pin of the chip.
+- standby-gpios: GPIO handle which is connected to the standby pin of the chip.
 
 For further reading on port node refer to
 Documentation/devicetree/bindings/media/video-interfaces.txt.
index 2e1d116a64e7b43eb1f6e886f842d9ef296664c9..501b37039449730411ad1673da7f4458d15ce373 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
 #include <linux/mutex.h>
@@ -251,6 +252,8 @@ struct mt9v032 {
 
        struct regmap *regmap;
        struct clk *clk;
+       struct gpio_desc *reset_gpio;
+       struct gpio_desc *standby_gpio;
 
        struct mt9v032_platform_data *pdata;
        const struct mt9v032_model_info *model;
@@ -312,16 +315,31 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
        struct regmap *map = mt9v032->regmap;
        int ret;
 
+       if (mt9v032->reset_gpio)
+               gpiod_set_value_cansleep(mt9v032->reset_gpio, 1);
+
        ret = clk_set_rate(mt9v032->clk, mt9v032->sysclk);
        if (ret < 0)
                return ret;
 
+       /* System clock has to be enabled before releasing the reset */
        ret = clk_prepare_enable(mt9v032->clk);
        if (ret)
                return ret;
 
        udelay(1);
 
+       if (mt9v032->reset_gpio) {
+               gpiod_set_value_cansleep(mt9v032->reset_gpio, 0);
+
+               /* After releasing reset we need to wait 10 clock cycles
+                * before accessing the sensor over I2C. As the minimum SYSCLK
+                * frequency is 13MHz, waiting 1µs will be enough in the worst
+                * case.
+                */
+               udelay(1);
+       }
+
        /* Reset the chip and stop data read out */
        ret = regmap_write(map, MT9V032_RESET, 1);
        if (ret < 0)
@@ -954,6 +972,16 @@ static int mt9v032_probe(struct i2c_client *client,
        if (IS_ERR(mt9v032->clk))
                return PTR_ERR(mt9v032->clk);
 
+       mt9v032->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+                                                     GPIOD_OUT_HIGH);
+       if (IS_ERR(mt9v032->reset_gpio))
+               return PTR_ERR(mt9v032->reset_gpio);
+
+       mt9v032->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby",
+                                                       GPIOD_OUT_LOW);
+       if (IS_ERR(mt9v032->standby_gpio))
+               return PTR_ERR(mt9v032->standby_gpio);
+
        mutex_init(&mt9v032->power_lock);
        mt9v032->pdata = pdata;
        mt9v032->model = (const void *)did->driver_data;