From 072de836f53be56a70cecf70b43ae43b7ce17376 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 10:08:36 +0000
Subject: [PATCH] mk-rootfs.sh
---
kernel/drivers/media/i2c/ov02b10.c | 93 +++++++++++++++++++++++++++++++---------------
1 files changed, 63 insertions(+), 30 deletions(-)
diff --git a/kernel/drivers/media/i2c/ov02b10.c b/kernel/drivers/media/i2c/ov02b10.c
index 19ca156..94d5d7f 100644
--- a/kernel/drivers/media/i2c/ov02b10.c
+++ b/kernel/drivers/media/i2c/ov02b10.c
@@ -5,6 +5,7 @@
* Copyright (C) 2020 Rockchip Electronics Co., Ltd.
*
* V0.0X01.0X00 first version.
+ * V0.0X01.0X01 fix power on & off sequence
*/
#include <linux/clk.h>
@@ -27,7 +28,7 @@
#include <linux/rk-preisp.h>
#include "../platform/rockchip/isp/rkisp_tb_helper.h"
-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x00)
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
#ifndef V4L2_CID_DIGITAL_GAIN
#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
@@ -91,20 +92,11 @@
#define SENSOR_ID(_msb, _lsb) ((_msb) << 8 | (_lsb))
static const char * const OV02B10_supply_names[] = {
- "avdd", /* Analog power */
"dovdd", /* Digital I/O power */
- "dvdd", /* Digital core power */
+ "avdd", /* Analog power */
};
#define OV02B10_NUM_SUPPLIES ARRAY_SIZE(OV02B10_supply_names)
-
-enum ov02b10_max_pad {
- PAD0,
- PAD1,
- PAD2,
- PAD3,
- PAD_MAX,
-};
struct regval {
u8 addr;
@@ -534,14 +526,12 @@
struct ov02b10 *ov02b10 = to_ov02b10(sd);
const struct ov02b10_mode *mode = ov02b10->cur_mode;
- mutex_lock(&ov02b10->mutex);
fi->interval = mode->max_fps;
- mutex_unlock(&ov02b10->mutex);
return 0;
}
-static int ov02b10_g_mbus_config(struct v4l2_subdev *sd,
+static int ov02b10_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
struct v4l2_mbus_config *config)
{
struct ov02b10 *ov02b10 = to_ov02b10(sd);
@@ -558,7 +548,7 @@
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
V4L2_MBUS_CSI2_CHANNEL_1;
- config->type = V4L2_MBUS_CSI2;
+ config->type = V4L2_MBUS_CSI2_DPHY;
config->flags = val;
return 0;
@@ -639,8 +629,11 @@
}
ret = ov02b10_ioctl(sd, cmd, inf);
- if (!ret)
+ if (!ret) {
ret = copy_to_user(up, inf, sizeof(*inf));
+ if (ret)
+ ret = -EFAULT;
+ }
kfree(inf);
break;
case RKMODULE_AWB_CFG:
@@ -653,6 +646,8 @@
ret = copy_from_user(cfg, up, sizeof(*cfg));
if (!ret)
ret = ov02b10_ioctl(sd, cmd, cfg);
+ else
+ ret = -EFAULT;
kfree(cfg);
break;
case RKMODULE_GET_HDR_CFG:
@@ -663,8 +658,11 @@
}
ret = ov02b10_ioctl(sd, cmd, hdr);
- if (!ret)
+ if (!ret) {
ret = copy_to_user(up, hdr, sizeof(*hdr));
+ if (ret)
+ ret = -EFAULT;
+ }
kfree(hdr);
break;
case RKMODULE_SET_HDR_CFG:
@@ -677,6 +675,8 @@
ret = copy_from_user(hdr, up, sizeof(*hdr));
if (!ret)
ret = ov02b10_ioctl(sd, cmd, hdr);
+ else
+ ret = -EFAULT;
kfree(hdr);
break;
case PREISP_CMD_SET_HDRAE_EXP:
@@ -689,17 +689,23 @@
ret = copy_from_user(hdrae, up, sizeof(*hdrae));
if (!ret)
ret = ov02b10_ioctl(sd, cmd, hdrae);
+ else
+ ret = -EFAULT;
kfree(hdrae);
break;
case RKMODULE_SET_CONVERSION_GAIN:
ret = copy_from_user(&cg, up, sizeof(cg));
if (!ret)
ret = ov02b10_ioctl(sd, cmd, &cg);
+ else
+ ret = -EFAULT;
break;
case RKMODULE_SET_QUICK_STREAM:
ret = copy_from_user(&stream, up, sizeof(u32));
if (!ret)
ret = ov02b10_ioctl(sd, cmd, &stream);
+ else
+ ret = -EFAULT;
break;
default:
ret = -ENOIOCTLCMD;
@@ -813,6 +819,31 @@
return ret;
}
+static int ov02b10_enable_regulators(struct ov02b10 *ov02b10,
+ struct regulator_bulk_data *consumers)
+{
+ int i, j;
+ int ret = 0;
+ struct device *dev = &ov02b10->client->dev;
+ int num_consumers = OV02B10_NUM_SUPPLIES;
+
+ for (i = 0; i < num_consumers; i++) {
+
+ ret = regulator_enable(consumers[i].consumer);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable regulator: %s\n",
+ consumers[i].supply);
+ goto err;
+ }
+ }
+ return 0;
+err:
+ for (j = 0; j < i; j++)
+ regulator_disable(consumers[j].consumer);
+
+ return ret;
+}
+
static int __ov02b10_power_on(struct ov02b10 *ov02b10)
{
int ret;
@@ -829,11 +860,6 @@
dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
if (clk_get_rate(ov02b10->xvclk) != OV02B10_XVCLK_FREQ)
dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
- ret = clk_prepare_enable(ov02b10->xvclk);
- if (ret < 0) {
- dev_err(dev, "Failed to enable xvclk\n");
- return ret;
- }
if (!IS_ERR(ov02b10->pwdn_gpio))
gpiod_direction_output(ov02b10->pwdn_gpio, 1);
@@ -841,10 +867,16 @@
if (!IS_ERR(ov02b10->reset_gpio))
gpiod_direction_output(ov02b10->reset_gpio, 1);
- ret = regulator_bulk_enable(OV02B10_NUM_SUPPLIES, ov02b10->supplies);
+ ret = ov02b10_enable_regulators(ov02b10, ov02b10->supplies);
if (ret < 0) {
dev_err(dev, "Failed to enable regulators\n");
goto disable_clk;
+ }
+ usleep_range(100, 110);
+ ret = clk_prepare_enable(ov02b10->xvclk);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable xvclk\n");
+ return ret;
}
/* From spec: delay from power stable to pwdn off: 5ms */
@@ -872,13 +904,14 @@
int ret;
struct device *dev = &ov02b10->client->dev;
- if (!IS_ERR(ov02b10->pwdn_gpio))
- gpiod_direction_output(ov02b10->pwdn_gpio, 1);
+ if (!IS_ERR(ov02b10->reset_gpio))
+ gpiod_direction_output(ov02b10->reset_gpio, 1);
clk_disable_unprepare(ov02b10->xvclk);
- if (!IS_ERR(ov02b10->reset_gpio))
- gpiod_direction_output(ov02b10->reset_gpio, 1);
+ if (!IS_ERR(ov02b10->pwdn_gpio))
+ gpiod_direction_output(ov02b10->pwdn_gpio, 1);
+
if (!IS_ERR_OR_NULL(ov02b10->pins_sleep)) {
ret = pinctrl_select_state(ov02b10->pinctrl,
ov02b10->pins_sleep);
@@ -888,7 +921,7 @@
regulator_bulk_disable(OV02B10_NUM_SUPPLIES, ov02b10->supplies);
}
-static int ov02b10_runtime_resume(struct device *dev)
+static int __maybe_unused ov02b10_runtime_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -897,7 +930,7 @@
return __ov02b10_power_on(ov02b10);
}
-static int ov02b10_runtime_suspend(struct device *dev)
+static int __maybe_unused ov02b10_runtime_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -969,7 +1002,6 @@
static const struct v4l2_subdev_video_ops ov02b10_video_ops = {
.s_stream = ov02b10_s_stream,
.g_frame_interval = ov02b10_g_frame_interval,
- .g_mbus_config = ov02b10_g_mbus_config,
};
static const struct v4l2_subdev_pad_ops ov02b10_pad_ops = {
@@ -978,6 +1010,7 @@
.enum_frame_interval = ov02b10_enum_frame_interval,
.get_fmt = ov02b10_get_fmt,
.set_fmt = ov02b10_set_fmt,
+ .get_mbus_config = ov02b10_g_mbus_config,
};
static const struct v4l2_subdev_ops ov02b10_subdev_ops = {
--
Gitblit v1.6.2