From 1d58cb9fa9034f87a9df63b8024a94028478ebf6 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Mon, 9 Sep 2024 16:49:41 +0200
Subject: [PATCH 326/463] media: imx258: Add reset gpio

IMX258 features a reset input that needs to be controlled when powering
up the chip.

Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
 drivers/media/i2c/imx258.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 5adcfc98a11f4..5c92d1c2ecb28 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -678,6 +678,7 @@ struct imx258 {
 	struct mutex mutex;
 
 	struct clk *clk;
+	struct gpio_desc *reset_gpio;
 	struct regulator_bulk_data supplies[IMX258_NUM_SUPPLIES];
 };
 
@@ -1113,12 +1114,20 @@ static int imx258_power_on(struct device *dev)
 		return ret;
 	}
 
+	mdelay(20);
+
 	ret = clk_prepare_enable(imx258->clk);
 	if (ret) {
 		dev_err(dev, "failed to enable clock\n");
 		regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);
 	}
 
+	usleep_range(1000, 2000);
+
+	gpiod_set_value_cansleep(imx258->reset_gpio, 0);
+
+	usleep_range(400, 500);
+
 	return ret;
 }
 
@@ -1128,6 +1137,7 @@ static int imx258_power_off(struct device *dev)
 	struct imx258 *imx258 = to_imx258(sd);
 
 	clk_disable_unprepare(imx258->clk);
+	gpiod_set_value_cansleep(imx258->reset_gpio, 1);
 	regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);
 
 	return 0;
@@ -1426,6 +1436,11 @@ static int imx258_probe(struct i2c_client *client)
 		return dev_err_probe(&client->dev, ret,
 				     "failed to get regulators\n");
 
+	imx258->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+						     GPIOD_OUT_HIGH);
+	if (IS_ERR(imx258->reset_gpio))
+		return PTR_ERR(imx258->reset_gpio);
+
 	imx258->clk = devm_clk_get_optional(&client->dev, NULL);
 	if (IS_ERR(imx258->clk))
 		return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),
-- 
2.46.0

