mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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:
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user