summaryrefslogtreecommitdiff
path: root/drivers/media/i2c/ccs
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@linux.intel.com>2020-06-18 14:12:51 +0300
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-12-02 17:52:09 +0300
commitd0fbdcbe75950a4f93edcece34622888c4395133 (patch)
tree62c57542a09bc7f7abd8ead911be2206841686ef /drivers/media/i2c/ccs
parentaab402ea9b4827f6d8d4a7c58d7492124b493e02 (diff)
downloadlinux-d0fbdcbe75950a4f93edcece34622888c4395133.tar.xz
media: ccs: Request for "reset" GPIO
The DT bindings documented "reset-gpios" property but the driver never made use of it. Instead it used a GPIO called "xshutdown", with apprently wrong polarity. Fix this by requesting "reset" GPIO with the right polarity first, and if that fails, then request "xshutdown" GPIO with the old polarity. This way it works for new users as expected while if someone, somewhere, depended on "xshutdown" GPIO, that continues to work as well. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/i2c/ccs')
-rw-r--r--drivers/media/i2c/ccs/ccs-core.c14
-rw-r--r--drivers/media/i2c/ccs/ccs.h1
2 files changed, 13 insertions, 2 deletions
diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c
index bddfee637f33..69e7990c65f3 100644
--- a/drivers/media/i2c/ccs/ccs-core.c
+++ b/drivers/media/i2c/ccs/ccs-core.c
@@ -1295,6 +1295,7 @@ static int ccs_power_on(struct device *dev)
}
usleep_range(1000, 1000);
+ gpiod_set_value(sensor->reset, 0);
gpiod_set_value(sensor->xshutdown, 1);
sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk);
@@ -1381,6 +1382,7 @@ static int ccs_power_on(struct device *dev)
return 0;
out_cci_addr_fail:
+ gpiod_set_value(sensor->reset, 1);
gpiod_set_value(sensor->xshutdown, 0);
clk_disable_unprepare(sensor->ext_clk);
@@ -1407,6 +1409,7 @@ static int ccs_power_off(struct device *dev)
if (sensor->hwcfg->i2c_addr_alt)
ccs_write(sensor, SOFTWARE_RESET, CCS_SOFTWARE_RESET_ON);
+ gpiod_set_value(sensor->reset, 1);
gpiod_set_value(sensor->xshutdown, 0);
clk_disable_unprepare(sensor->ext_clk);
usleep_range(5000, 5000);
@@ -3008,8 +3011,15 @@ static int ccs_probe(struct i2c_client *client)
return -EINVAL;
}
- sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown",
- GPIOD_OUT_LOW);
+ sensor->reset = devm_gpiod_get_optional(&client->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(sensor->reset))
+ return PTR_ERR(sensor->reset);
+ /* Support old users that may have used "xshutdown" property. */
+ if (!sensor->reset)
+ sensor->xshutdown = devm_gpiod_get_optional(&client->dev,
+ "xshutdown",
+ GPIOD_OUT_LOW);
if (IS_ERR(sensor->xshutdown))
return PTR_ERR(sensor->xshutdown);
diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h
index 8933f3d40fa5..bfe39e02f5e9 100644
--- a/drivers/media/i2c/ccs/ccs.h
+++ b/drivers/media/i2c/ccs/ccs.h
@@ -219,6 +219,7 @@ struct ccs_sensor {
struct regulator *vana;
struct clk *ext_clk;
struct gpio_desc *xshutdown;
+ struct gpio_desc *reset;
void *ccs_limits;
u8 nbinning_subtypes;
struct ccs_binning_subtype binning_subtypes[CCS_LIM_BINNING_SUB_TYPE_MAX_N + 1];