80a5d900d688bcc95df4a706c6297864150d4c47
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.19 / 950-0167-media-ov5647-Add-support-for-PWDN-GPIO.patch
1 From f41fdda9ca98e675d7467cc352c678bbcdca2df1 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Wed, 31 Oct 2018 14:56:33 +0000
4 Subject: [PATCH] media: ov5647: Add support for PWDN GPIO.
5
6 Add support for an optional GPIO connected to PWDN on the sensor.
7
8 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
9 ---
10 drivers/media/i2c/ov5647.c | 28 ++++++++++++++++++++++++++++
11 1 file changed, 28 insertions(+)
12
13 --- a/drivers/media/i2c/ov5647.c
14 +++ b/drivers/media/i2c/ov5647.c
15 @@ -21,6 +21,7 @@
16
17 #include <linux/clk.h>
18 #include <linux/delay.h>
19 +#include <linux/gpio/consumer.h>
20 #include <linux/i2c.h>
21 #include <linux/init.h>
22 #include <linux/io.h>
23 @@ -35,6 +36,13 @@
24
25 #define SENSOR_NAME "ov5647"
26
27 +/*
28 + * From the datasheet, "20ms after PWDN goes low or 20ms after RESETB goes
29 + * high if reset is inserted after PWDN goes high, host can access sensor's
30 + * SCCB to initialize sensor."
31 + */
32 +#define PWDN_ACTIVE_DELAY_MS 20
33 +
34 #define MIPI_CTRL00_CLOCK_LANE_GATE BIT(5)
35 #define MIPI_CTRL00_BUS_IDLE BIT(2)
36 #define MIPI_CTRL00_CLOCK_LANE_DISABLE BIT(0)
37 @@ -86,6 +94,7 @@ struct ov5647 {
38 unsigned int height;
39 int power_count;
40 struct clk *xclk;
41 + struct gpio_desc *pwdn;
42 };
43
44 static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
45 @@ -355,6 +364,11 @@ static int ov5647_sensor_power(struct v4
46 if (on && !ov5647->power_count) {
47 dev_dbg(&client->dev, "OV5647 power on\n");
48
49 + if (ov5647->pwdn) {
50 + gpiod_set_value(ov5647->pwdn, 0);
51 + msleep(PWDN_ACTIVE_DELAY_MS);
52 + }
53 +
54 ret = clk_prepare_enable(ov5647->xclk);
55 if (ret < 0) {
56 dev_err(&client->dev, "clk prepare enable failed\n");
57 @@ -392,6 +406,8 @@ static int ov5647_sensor_power(struct v4
58 dev_dbg(&client->dev, "soft stby failed\n");
59
60 clk_disable_unprepare(ov5647->xclk);
61 +
62 + gpiod_set_value(ov5647->pwdn, 1);
63 }
64
65 /* Update the power count. */
66 @@ -604,6 +620,10 @@ static int ov5647_probe(struct i2c_clien
67 return -EINVAL;
68 }
69
70 + /* Request the power down GPIO asserted */
71 + sensor->pwdn = devm_gpiod_get_optional(&client->dev, "pwdn",
72 + GPIOD_OUT_HIGH);
73 +
74 mutex_init(&sensor->lock);
75
76 sd = &sensor->sd;
77 @@ -617,7 +637,15 @@ static int ov5647_probe(struct i2c_clien
78 if (ret < 0)
79 goto mutex_remove;
80
81 + if (sensor->pwdn) {
82 + gpiod_set_value(sensor->pwdn, 0);
83 + msleep(PWDN_ACTIVE_DELAY_MS);
84 + }
85 +
86 ret = ov5647_detect(sd);
87 +
88 + gpiod_set_value(sensor->pwdn, 1);
89 +
90 if (ret < 0)
91 goto error;
92