media: i2c: support get dcg ratio from sensor

Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
Change-Id: I47e07dc1bb282e0fb24db87f3802dd3ef93907a8
This commit is contained in:
Zefa Chen
2021-03-05 09:24:45 +08:00
parent 6510f055fb
commit 6a81bb7794
2 changed files with 73 additions and 1 deletions

View File

@@ -9,6 +9,7 @@
* V0.0X01.0X02 add debug interface for conversion gain switch.
* V0.0X01.0X03 support enum sensor fmt
* V0.0X01.0X04 add quick stream on/off
* V0.0X01.0X05 support get dcg ratio from sensor
*/
#include <linux/clk.h>
@@ -31,7 +32,7 @@
#include <linux/rk-preisp.h>
#include "../platform/rockchip/isp/rkisp_tb_helper.h"
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x04)
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x05)
#ifndef V4L2_CID_DIGITAL_GAIN
#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
@@ -190,6 +191,7 @@ struct os04a10 {
bool is_thunderboot_ng;
bool is_first_streamoff;
u8 flip;
u32 dcg_ratio;
};
#define to_os04a10(sd) container_of(sd, struct os04a10, subdev)
@@ -1223,6 +1225,10 @@ static int os04a10_set_hdrae(struct os04a10 *os04a10,
if (!os04a10->has_init_exp && !os04a10->streaming) {
os04a10->init_hdrae_exp = *ae;
os04a10->has_init_exp = true;
if (os04a10->init_hdrae_exp.short_exp_reg >= 0x90) {
dev_err(&os04a10->client->dev, "short exposure must less than 0x90 before start stream!\n");
return -EINVAL;
}
dev_dbg(&os04a10->client->dev, "os04a10 don't stream, record exp for hdr!\n");
return ret;
}
@@ -1445,6 +1451,7 @@ static long os04a10_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
struct os04a10 *os04a10 = to_os04a10(sd);
struct rkmodule_hdr_cfg *hdr_cfg;
struct rkmodule_dcg_ratio *dcg;
long ret = 0;
u32 i, h, w;
u32 stream = 0;
@@ -1503,6 +1510,17 @@ static long os04a10_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
ret = os04a10_write_reg(os04a10->client, OS04A10_REG_CTRL_MODE,
OS04A10_REG_VALUE_08BIT, OS04A10_MODE_SW_STANDBY);
break;
case RKMODULE_GET_DCG_RATIO:
if (os04a10->dcg_ratio == 0)
return -EINVAL;
dcg = (struct rkmodule_dcg_ratio *)arg;
dcg->integer = (os04a10->dcg_ratio >> 8) & 0xff;
dcg->decimal = os04a10->dcg_ratio & 0xff;
dcg->div_coeff = 256;
dev_info(&os04a10->client->dev,
"get dcg ratio integer %d, decimal %d div_coeff %d\n",
dcg->integer, dcg->decimal, dcg->div_coeff);
break;
default:
ret = -ENOIOCTLCMD;
break;
@@ -1520,6 +1538,7 @@ static long os04a10_compat_ioctl32(struct v4l2_subdev *sd,
struct rkmodule_awb_cfg *cfg;
struct rkmodule_hdr_cfg *hdr;
struct preisp_hdrae_exp_s *hdrae;
struct rkmodule_dcg_ratio *dcg;
long ret;
u32 cg = 0;
u32 stream = 0;
@@ -1595,6 +1614,18 @@ static long os04a10_compat_ioctl32(struct v4l2_subdev *sd,
if (!ret)
ret = os04a10_ioctl(sd, cmd, &stream);
break;
case RKMODULE_GET_DCG_RATIO:
dcg = kzalloc(sizeof(*dcg), GFP_KERNEL);
if (!dcg) {
ret = -ENOMEM;
return ret;
}
ret = os04a10_ioctl(sd, cmd, dcg);
if (!ret)
ret = copy_to_user(up, dcg, sizeof(*dcg));
kfree(dcg);
break;
default:
ret = -ENOIOCTLCMD;
break;
@@ -2184,6 +2215,36 @@ static int os04a10_configure_regulators(struct os04a10 *os04a10)
os04a10->supplies);
}
static int os04a10_get_dcg_ratio(struct os04a10 *os04a10)
{
struct device *dev = &os04a10->client->dev;
u32 val = 0;
int ret = 0;
if (os04a10->is_thunderboot) {
ret = os04a10_read_reg(os04a10->client, 0x77fe,
OS04A10_REG_VALUE_16BIT, &val);
} else {
ret = os04a10_write_reg(os04a10->client, OS04A10_REG_CTRL_MODE,
OS04A10_REG_VALUE_08BIT, OS04A10_MODE_STREAMING);
usleep_range(5000, 6000);
ret |= os04a10_read_reg(os04a10->client, 0x77fe,
OS04A10_REG_VALUE_16BIT, &val);
ret |= os04a10_write_reg(os04a10->client, OS04A10_REG_CTRL_MODE,
OS04A10_REG_VALUE_08BIT, OS04A10_MODE_SW_STANDBY);
}
if (ret != 0 || val == 0) {
os04a10->dcg_ratio = 0;
dev_err(dev, "get dcg ratio fail, ret %d, dcg ratio %d\n", ret, val);
} else {
os04a10->dcg_ratio = val;
dev_info(dev, "get dcg ratio reg val 0x%04x\n", val);
}
return ret;
}
static int os04a10_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -2285,6 +2346,7 @@ static int os04a10_probe(struct i2c_client *client,
ret = os04a10_check_sensor_id(os04a10, client);
if (ret)
goto err_power_off;
ret = os04a10_get_dcg_ratio(os04a10);
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
sd->internal_ops = &os04a10_internal_ops;

View File

@@ -97,6 +97,10 @@
#define RKMODULE_GET_BT656_MBUS_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 17, struct rkmodule_bt656_mbus_info)
#define RKMODULE_GET_DCG_RATIO \
_IOR('V', BASE_VIDIOC_PRIVATE + 18, struct rkmodule_dcg_ratio)
/**
* struct rkmodule_base_inf - module base information
*
@@ -420,5 +424,11 @@ struct rkmodule_bt656_mbus_info {
__u32 id_en_bits;
} __attribute__ ((packed));
/* DCG ratio (float) = integer + decimal / div_coeff */
struct rkmodule_dcg_ratio {
u32 integer;
u32 decimal;
u32 div_coeff;
};
#endif /* _UAPI_RKMODULE_CAMERA_H */