From b3f40bb2fbcb4cca9cf1ca3adc09f4ae87524e1d Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Sun, 22 May 2022 14:31:08 +0200
Subject: [PATCH 357/389] media: i2c: ov8858: Port BSP driver to 5.18 and
 improve DT bindings

- drop power-gpios
- use optional gpio instead of error checks everywhere
- assume positive meaning for gpios with inversion handled in DT
- don't touch default pinctrl setup
- simplify powerup

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

diff --git a/drivers/media/i2c/ov8858.c b/drivers/media/i2c/ov8858.c
index 11f01e30bc1d..69ec1efef2f8 100644
--- a/drivers/media/i2c/ov8858.c
+++ b/drivers/media/i2c/ov8858.c
@@ -21,7 +21,7 @@
 #include <linux/slab.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/version.h>
-#include <linux/rk-camera-module.h>
+#include "rk-camera-module.h"
 
 #include <media/v4l2-async.h>
 #include <media/media-entity.h>
@@ -34,8 +34,6 @@
 #include <media/v4l2-mediabus.h>
 #include <media/v4l2-subdev.h>
 
-#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x03)
-
 #ifndef V4L2_CID_DIGITAL_GAIN
 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
 #endif
@@ -158,7 +156,6 @@ struct ov8858_mode {
 struct ov8858 {
 	struct i2c_client	*client;
 	struct clk		*xvclk;
-	struct gpio_desc	*power_gpio;
 	struct gpio_desc	*reset_gpio;
 	struct gpio_desc	*pwdn_gpio;
 	struct regulator_bulk_data supplies[OV8858_NUM_SUPPLIES];
@@ -1488,7 +1485,7 @@ ov8858_find_best_fit(struct ov8858 *ov8858,
 }
 
 static int ov8858_set_fmt(struct v4l2_subdev *sd,
-			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_state *state,
 			  struct v4l2_subdev_format *fmt)
 {
 	struct ov8858 *ov8858 = to_ov8858(sd);
@@ -1504,7 +1501,7 @@ static int ov8858_set_fmt(struct v4l2_subdev *sd,
 	fmt->format.field = V4L2_FIELD_NONE;
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
-		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+		*v4l2_subdev_get_try_format(sd, state, fmt->pad) = fmt->format;
 #else
 		mutex_unlock(&ov8858->mutex);
 		return -ENOTTY;
@@ -1526,7 +1523,7 @@ static int ov8858_set_fmt(struct v4l2_subdev *sd,
 }
 
 static int ov8858_get_fmt(struct v4l2_subdev *sd,
-			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_state *state,
 			  struct v4l2_subdev_format *fmt)
 {
 	struct ov8858 *ov8858 = to_ov8858(sd);
@@ -1535,7 +1532,7 @@ static int ov8858_get_fmt(struct v4l2_subdev *sd,
 	mutex_lock(&ov8858->mutex);
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
-		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+		fmt->format = *v4l2_subdev_get_try_format(sd, state, fmt->pad);
 #else
 		mutex_unlock(&ov8858->mutex);
 		return -ENOTTY;
@@ -1552,7 +1549,7 @@ static int ov8858_get_fmt(struct v4l2_subdev *sd,
 }
 
 static int ov8858_enum_mbus_code(struct v4l2_subdev *sd,
-				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_state *state,
 				 struct v4l2_subdev_mbus_code_enum *code)
 {
 	if (code->index != 0)
@@ -1563,7 +1560,7 @@ static int ov8858_enum_mbus_code(struct v4l2_subdev *sd,
 }
 
 static int ov8858_enum_frame_sizes(struct v4l2_subdev *sd,
-				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_state *state,
 				   struct v4l2_subdev_frame_size_enum *fse)
 {
 	struct ov8858 *ov8858 = to_ov8858(sd);
@@ -2137,11 +2134,6 @@ static int __ov8858_power_on(struct ov8858 *ov8858)
 	u32 delay_us;
 	struct device *dev = &ov8858->client->dev;
 
-	if (!IS_ERR(ov8858->power_gpio))
-		gpiod_set_value_cansleep(ov8858->power_gpio, 1);
-
-	usleep_range(1000, 2000);
-
 	if (!IS_ERR_OR_NULL(ov8858->pins_default)) {
 		ret = pinctrl_select_state(ov8858->pinctrl,
 					   ov8858->pins_default);
@@ -2154,31 +2146,28 @@ static int __ov8858_power_on(struct ov8858 *ov8858)
 		dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
 	if (clk_get_rate(ov8858->xvclk) != OV8858_XVCLK_FREQ)
 		dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
+
 	ret = clk_prepare_enable(ov8858->xvclk);
 	if (ret < 0) {
 		dev_err(dev, "Failed to enable xvclk\n");
 		return ret;
 	}
 
-	if (!IS_ERR(ov8858->reset_gpio))
-		gpiod_set_value_cansleep(ov8858->reset_gpio, 0);
-
 	ret = regulator_bulk_enable(OV8858_NUM_SUPPLIES, ov8858->supplies);
 	if (ret < 0) {
 		dev_err(dev, "Failed to enable regulators\n");
 		goto disable_clk;
 	}
 
-	if (!IS_ERR(ov8858->reset_gpio))
-		gpiod_set_value_cansleep(ov8858->reset_gpio, 1);
+	mdelay(20);
 
-	usleep_range(1000, 2000);
-	if (!IS_ERR(ov8858->pwdn_gpio))
-		gpiod_set_value_cansleep(ov8858->pwdn_gpio, 1);
+	gpiod_set_value_cansleep(ov8858->reset_gpio, 0);
+	gpiod_set_value_cansleep(ov8858->pwdn_gpio, 0);
 
 	/* 8192 cycles prior to first SCCB transaction */
-	delay_us = ov8858_cal_delay(8192);
-	usleep_range(delay_us, delay_us * 2);
+	//delay_us = ov8858_cal_delay(8192);
+	//usleep_range(delay_us, delay_us * 2);
+	mdelay(10);
 
 	return 0;
 
@@ -2193,11 +2182,10 @@ static void __ov8858_power_off(struct ov8858 *ov8858)
 	int ret;
 	struct device *dev = &ov8858->client->dev;
 
-	if (!IS_ERR(ov8858->pwdn_gpio))
-		gpiod_set_value_cansleep(ov8858->pwdn_gpio, 0);
+	gpiod_set_value_cansleep(ov8858->pwdn_gpio, 1);
 	clk_disable_unprepare(ov8858->xvclk);
-	if (!IS_ERR(ov8858->reset_gpio))
-		gpiod_set_value_cansleep(ov8858->reset_gpio, 0);
+	gpiod_set_value_cansleep(ov8858->reset_gpio, 1);
+
 	if (!IS_ERR_OR_NULL(ov8858->pins_sleep)) {
 		ret = pinctrl_select_state(ov8858->pinctrl,
 					   ov8858->pins_sleep);
@@ -2205,9 +2193,6 @@ static void __ov8858_power_off(struct ov8858 *ov8858)
 			dev_dbg(dev, "could not set pins\n");
 	}
 
-	//if (!IS_ERR(ov8858->power_gpio))
-		//gpiod_set_value_cansleep(ov8858->power_gpio, 0);
-
 	regulator_bulk_disable(OV8858_NUM_SUPPLIES, ov8858->supplies);
 }
 
@@ -2236,7 +2221,7 @@ static int ov8858_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 {
 	struct ov8858 *ov8858 = to_ov8858(sd);
 	struct v4l2_mbus_framefmt *try_fmt =
-				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+				v4l2_subdev_get_try_format(sd, fh->state, 0);
 	const struct ov8858_mode *def_mode = &supported_modes[0];
 
 	mutex_lock(&ov8858->mutex);
@@ -2254,7 +2239,7 @@ static int ov8858_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 #endif
 
 static int ov8858_enum_frame_interval(struct v4l2_subdev *sd,
-				      struct v4l2_subdev_pad_config *cfg,
+				      struct v4l2_subdev_state *state,
 				      struct v4l2_subdev_frame_interval_enum *fie)
 {
 	struct ov8858 *ov8858 = to_ov8858(sd);
@@ -2726,18 +2711,19 @@ static int ov8858_check_sensor_id(struct ov8858 *ov8858,
 	int ret;
 
 	ret = ov8858_read_reg(client, OV8858_REG_CHIP_ID,
-			       OV8858_REG_VALUE_24BIT, &id);
+			      OV8858_REG_VALUE_24BIT, &id);
 	if (id != CHIP_ID) {
 		dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
 		return ret;
 	}
 
 	ret = ov8858_read_reg(client, OV8858_CHIP_REVISION_REG,
-			       OV8858_REG_VALUE_08BIT, &id);
+			      OV8858_REG_VALUE_08BIT, &id);
 	if (ret) {
 		dev_err(dev, "Read chip revision register error\n");
 		return ret;
 	}
+
 	dev_info(dev, "Detected OV%06x sensor, REVISION 0x%x\n", CHIP_ID, id);
 
 	if (id == OV8858_R2A) {
@@ -2781,6 +2767,7 @@ static int ov8858_parse_of(struct ov8858 *ov8858)
 		dev_err(dev, "Failed to get endpoint\n");
 		return -EINVAL;
 	}
+
 	fwnode = of_fwnode_handle(endpoint);
 	rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
 	if (rval <= 0) {
@@ -2821,16 +2808,12 @@ static int ov8858_probe(struct i2c_client *client,
 	char facing[2];
 	int ret;
 
-	dev_info(dev, "driver version: %02x.%02x.%02x",
-		DRIVER_VERSION >> 16,
-		(DRIVER_VERSION & 0xff00) >> 8,
-		DRIVER_VERSION & 0x00ff);
-
 	ov8858 = devm_kzalloc(dev, sizeof(*ov8858), GFP_KERNEL);
 	if (!ov8858)
 		return -ENOMEM;
 
 	ov8858->client = client;
+
 	ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
 				   &ov8858->module_index);
 	ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
@@ -2839,40 +2822,37 @@ static int ov8858_probe(struct i2c_client *client,
 				       &ov8858->module_name);
 	ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
 				       &ov8858->len_name);
-	if (ret) {
-		dev_err(dev,
+	if (ret)
+		return dev_err_probe(dev, -EINVAL,
 			"could not get module information!\n");
-		return -EINVAL;
-	}
 
 	ov8858->xvclk = devm_clk_get(dev, "xvclk");
-	if (IS_ERR(ov8858->xvclk)) {
-		dev_err(dev, "Failed to get xvclk\n");
-		return -EINVAL;
-	}
+	if (IS_ERR(ov8858->xvclk))
+		return dev_err_probe(dev, PTR_ERR(ov8858->xvclk),
+				     "Failed to get xvclk\n");
 
-	ov8858->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);
-	if (IS_ERR(ov8858->power_gpio))
-		dev_warn(dev, "Failed to get power-gpios, maybe no use\n");
-
-	ov8858->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	ov8858->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+						     GPIOD_OUT_HIGH);
 	if (IS_ERR(ov8858->reset_gpio))
-		dev_warn(dev, "Failed to get reset-gpios, maybe no use\n");
+		return dev_err_probe(dev, PTR_ERR(ov8858->reset_gpio),
+				     "Failed to get reset gpio\n");
 
-	ov8858->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+	ov8858->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
+						    GPIOD_OUT_HIGH);
 	if (IS_ERR(ov8858->pwdn_gpio))
-		dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n");
+		return dev_err_probe(dev, PTR_ERR(ov8858->pwdn_gpio),
+				     "Failed to get powerdown gpio\n");
 
 	ret = ov8858_configure_regulators(ov8858);
-	if (ret) {
-		dev_err(dev, "Failed to get power regulators\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to get power regulators\n");
 
 	ret = ov8858_parse_of(ov8858);
 	if (ret != 0)
 		return -EINVAL;
 
+	/*
 	ov8858->pinctrl = devm_pinctrl_get(dev);
 	if (!IS_ERR(ov8858->pinctrl)) {
 		ov8858->pins_default =
@@ -2887,6 +2867,7 @@ static int ov8858_probe(struct i2c_client *client,
 		if (IS_ERR(ov8858->pins_sleep))
 			dev_err(dev, "could not get sleep pinstate\n");
 	}
+         */
 
 	mutex_init(&ov8858->mutex);
 
@@ -2910,10 +2891,10 @@ static int ov8858_probe(struct i2c_client *client,
 	sd->internal_ops = &ov8858_internal_ops;
 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 #endif
-#if defined(CONFIG_MEDIA_CONTROLLER)
+#ifdef CONFIG_MEDIA_CONTROLLER
 	ov8858->pad.flags = MEDIA_PAD_FL_SOURCE;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &ov8858->pad, 0);
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &ov8858->pad);
 	if (ret < 0)
 		goto err_power_off;
 #endif
@@ -2927,7 +2908,7 @@ static int ov8858_probe(struct i2c_client *client,
 	snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
 		 ov8858->module_index, facing,
 		 OV8858_NAME, dev_name(sd->dev));
-	ret = v4l2_async_register_subdev_sensor_common(sd);
+	ret = v4l2_async_register_subdev_sensor(sd);
 	if (ret) {
 		dev_err(dev, "v4l2 async register subdev failed\n");
 		goto err_clean_entity;
@@ -2940,7 +2921,7 @@ static int ov8858_probe(struct i2c_client *client,
 	return 0;
 
 err_clean_entity:
-#if defined(CONFIG_MEDIA_CONTROLLER)
+#ifdef CONFIG_MEDIA_CONTROLLER
 	media_entity_cleanup(&sd->entity);
 #endif
 err_power_off:
@@ -2953,13 +2934,13 @@ static int ov8858_probe(struct i2c_client *client,
 	return ret;
 }
 
-static int ov8858_remove(struct i2c_client *client)
+static void ov8858_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct ov8858 *ov8858 = to_ov8858(sd);
 
 	v4l2_async_unregister_subdev(sd);
-#if defined(CONFIG_MEDIA_CONTROLLER)
+#ifdef CONFIG_MEDIA_CONTROLLER
 	media_entity_cleanup(&sd->entity);
 #endif
 	v4l2_ctrl_handler_free(&ov8858->ctrl_handler);
@@ -2973,8 +2954,6 @@ static int ov8858_remove(struct i2c_client *client)
 	if (!pm_runtime_status_suspended(&client->dev))
 		__ov8858_power_off(ov8858);
 	pm_runtime_set_suspended(&client->dev);
-
-	return 0;
 }
 
 #if IS_ENABLED(CONFIG_OF)
@@ -3001,18 +2980,7 @@ static struct i2c_driver ov8858_i2c_driver = {
 	.id_table	= ov8858_match_id,
 };
 
-static int __init sensor_mod_init(void)
-{
-	return i2c_add_driver(&ov8858_i2c_driver);
-}
-
-static void __exit sensor_mod_exit(void)
-{
-	i2c_del_driver(&ov8858_i2c_driver);
-}
-
-device_initcall_sync(sensor_mod_init);
-module_exit(sensor_mod_exit);
+module_i2c_driver(ov8858_i2c_driver);
 
 MODULE_DESCRIPTION("OmniVision ov8858 sensor driver");
 MODULE_LICENSE("GPL v2");
-- 
2.35.3

