media: spi: rk1608: add virtual sub sensor for dsp combine mode.

dts example:
virtual-sub-sensor-config-0 {
    id = <1>;
    in_mipi = <2>;
    out_mipi = <1>;
};

Signed-off-by: Sach Lin <sach.lin@rock-chips.com>
Change-Id: I990c2969783301816560514a0be986bf61cd4192
This commit is contained in:
Sach Lin
2022-06-06 16:25:55 +08:00
committed by Tao Huang
parent 0ed2bfbb09
commit 2cfc358387
4 changed files with 157 additions and 16 deletions
+92 -15
View File
@@ -556,16 +556,17 @@ static int rk1608_lsb_w32(struct spi_device *spi, s32 addr, s32 data)
}
static int rk1608_msg_init_sensor(struct rk1608_state *pdata,
struct msg_init *msg, int id)
struct msg_init *msg, int in_mipi, int out_mipi,
int id, int cam_id)
{
u32 idx = pdata->dphy[id]->fmt_inf_idx;
msg->msg_head.size = sizeof(struct msg_init);
msg->msg_head.type = id_msg_init_sensor_t;
msg->msg_head.id.camera_id = id;
msg->msg_head.id.camera_id = cam_id;
msg->msg_head.mux.sync = 1;
msg->in_mipi_phy = pdata->dphy[id]->in_mipi;
msg->out_mipi_phy = pdata->dphy[id]->out_mipi;
msg->in_mipi_phy = in_mipi;
msg->out_mipi_phy = out_mipi;
msg->mipi_lane = pdata->dphy[id]->fmt_inf[idx].mipi_lane;
msg->bayer = 0;
memcpy(msg->sensor_name, pdata->dphy[id]->sensor_name,
@@ -573,6 +574,7 @@ static int rk1608_msg_init_sensor(struct rk1608_state *pdata,
msg->i2c_slave_addr = pdata->dphy[id]->i2c_addr;
msg->i2c_bus = pdata->dphy[id]->i2c_bus;
msg->sub_sensor_num = pdata->dphy[id]->sub_sensor_num;
return rk1608_send_msg_to_dsp(pdata, &msg->msg_head);
}
@@ -598,7 +600,7 @@ static int rk1608_msg_init_dsp_time(struct rk1608_state *pdata,
}
static int rk1608_msg_set_input_size(struct rk1608_state *pdata,
struct msg_in_size *msg, int id)
struct msg_in_size *msg, int id, int cam_id)
{
u32 i;
u32 msg_size = sizeof(struct msg);
@@ -620,14 +622,14 @@ static int rk1608_msg_set_input_size(struct rk1608_state *pdata,
msg->msg_head.size = msg_size / sizeof(int);
msg->msg_head.type = id_msg_set_input_size_t;
msg->msg_head.id.camera_id = id;
msg->msg_head.id.camera_id = cam_id;
msg->msg_head.mux.sync = 1;
return rk1608_send_msg_to_dsp(pdata, &msg->msg_head);
}
static int rk1608_msg_set_output_size(struct rk1608_state *pdata,
struct msg_set_output_size *msg, int id)
struct msg_set_output_size *msg, int id, int cam_id)
{
u32 i;
u32 msg_size = sizeof(struct msg_out_size_head);
@@ -649,7 +651,7 @@ static int rk1608_msg_set_output_size(struct rk1608_state *pdata,
msg->head.msg_head.size = msg_size / sizeof(int);
msg->head.msg_head.type = id_msg_set_output_size_t;
msg->head.msg_head.id.camera_id = id;
msg->head.msg_head.id.camera_id = cam_id;
msg->head.msg_head.mux.sync = 1;
msg->head.width = fmt_inf->hactive;
msg->head.height = fmt_inf->vactive;
@@ -933,6 +935,54 @@ static int rk1608_disp_read_eeprom_request(struct rk1608_state *pdata)
return ret;
}
static int rk1608_init_virtual_sub_sensor(
struct rk1608_state *pdata, int id, int index)
{
struct msg *msg = NULL;
struct msg_init *msg_init = NULL;
struct msg_in_size *msg_in_size = NULL;
struct msg_set_output_size *msg_out_size = NULL;
int cam_id = pdata->dphy[id]->sub_sensor[index].id;
int in_mipi = pdata->dphy[id]->sub_sensor[index].in_mipi;
int out_mipi = pdata->dphy[id]->sub_sensor[index].out_mipi;
int ret = 0;
msg = kzalloc(sizeof(*msg), GFP_KERNEL);
if (!msg) {
ret = -ENOMEM;
goto err;
}
msg_init = kzalloc(sizeof(*msg_init), GFP_KERNEL);
if (!msg_init) {
ret = -ENOMEM;
goto err;
}
msg_in_size = kzalloc(sizeof(*msg_in_size), GFP_KERNEL);
if (!msg_in_size) {
ret = -ENOMEM;
goto err;
}
msg_out_size = kzalloc(sizeof(*msg_out_size), GFP_KERNEL);
if (!msg_out_size) {
ret = -ENOMEM;
goto err;
}
ret = rk1608_msg_init_sensor(pdata, msg_init, in_mipi, out_mipi, id, cam_id);
ret |= rk1608_msg_set_input_size(pdata, msg_in_size, id, cam_id);
ret |= rk1608_msg_set_output_size(pdata, msg_out_size, id, cam_id);
ret |= rk1608_msg_set_stream_in_on(pdata, msg, cam_id);
err:
kfree(msg_init);
kfree(msg_in_size);
kfree(msg_out_size);
kfree(msg);
return ret;
}
static int rk1608_init_sensor(struct rk1608_state *pdata, int id)
{
struct msg *msg = NULL;
@@ -940,6 +990,9 @@ static int rk1608_init_sensor(struct rk1608_state *pdata, int id)
struct msg_in_size *msg_in_size = NULL;
struct msg_set_output_size *msg_out_size = NULL;
struct msg_init_dsp_time *msg_init_time = NULL;
int in_mipi = pdata->dphy[id]->in_mipi;
int out_mipi = pdata->dphy[id]->out_mipi;
int cam_id = id;
int ret = 0;
if (!pdata->sensor[id]) {
@@ -975,12 +1028,13 @@ static int rk1608_init_sensor(struct rk1608_state *pdata, int id)
goto err;
}
ret = rk1608_msg_init_sensor(pdata, msg_init, id);
ret = rk1608_msg_init_sensor(pdata, msg_init, in_mipi, out_mipi, id, cam_id);
ret |= rk1608_msg_init_dsp_time(pdata, msg_init_time, id);
ret |= rk1608_msg_set_input_size(pdata, msg_in_size, id);
ret |= rk1608_msg_set_output_size(pdata, msg_out_size, id);
ret |= rk1608_msg_set_stream_in_on(pdata, msg, id);
ret |= rk1608_msg_set_stream_out_on(pdata, msg, id);
ret |= rk1608_msg_set_input_size(pdata, msg_in_size, id, cam_id);
ret |= rk1608_msg_set_output_size(pdata, msg_out_size, id, cam_id);
ret |= rk1608_msg_set_stream_in_on(pdata, msg, cam_id);
ret |= rk1608_msg_set_stream_out_on(pdata, msg, cam_id);
err:
kfree(msg_init);
@@ -1175,11 +1229,25 @@ static int rk1608_sensor_power(struct v4l2_subdev *sd, int on)
static int rk1608_stream_on(struct rk1608_state *pdata)
{
int id = 0, cnt = 0, ret = 0;
int sub_sensor_num = 0, index = 0;
mutex_lock(&pdata->lock);
id = pdata->sd.grp_id;
pdata->sensor_cnt = 0;
pdata->set_exp_cnt = 1;
sub_sensor_num = pdata->dphy[id]->sub_sensor_num;
for (index = 0; index < sub_sensor_num; index++) {
ret = rk1608_init_virtual_sub_sensor(pdata, id, index);
if (ret) {
dev_err(pdata->dev, "Init rk1608[%d] sub[%d] is failed!",
id,
index);
mutex_unlock(&pdata->lock);
return ret;
}
}
ret = rk1608_init_sensor(pdata, id);
if (ret) {
dev_err(pdata->dev, "Init rk1608[%d] is failed!",
@@ -1221,9 +1289,18 @@ static int rk1608_stream_on(struct rk1608_state *pdata)
static int rk1608_stream_off(struct rk1608_state *pdata)
{
u32 sub_sensor_num = 0, index = 0, sub_id = 0;
mutex_lock(&pdata->sensor_lock);
pdata->sensor_cnt = 0;
mutex_unlock(&pdata->sensor_lock);
sub_sensor_num = pdata->dphy[pdata->sd.grp_id]->sub_sensor_num;
for (index = 0; index < sub_sensor_num; index++) {
sub_id = pdata->dphy[pdata->sd.grp_id]->sub_sensor[index].id;
rk1608_deinit(pdata, sub_id);
}
rk1608_deinit(pdata, pdata->sd.grp_id);
return 0;
@@ -2096,7 +2173,7 @@ static int rk1608_get_calib_version_temperature_sn(struct rk1608_state *pdata,
goto err;
}
if (head->item[i].size > 128) {
if (head->item[i].size > sizeof(calibdata_->calib_sn_code)) {
dev_err(pdata->dev, "%s: %s size:%d error!\n",
__func__, head->item[i].name, head->item[i].size);
goto err;
@@ -2113,7 +2190,7 @@ static int rk1608_get_calib_version_temperature_sn(struct rk1608_state *pdata,
pos = head->item[i].offset;
ret = kernel_read(fp, (char *)&calibdata_->calib_sn_code, head->item[i].size, &pos);
ret = kernel_read(fp, (char *)calibdata_->calib_sn_code, head->item[i].size, &pos);
if (ret <= 0) {
dev_err(pdata->dev, "%s: read error: ret=%d\n", __func__, ret);
goto err;
+2 -1
View File
@@ -213,6 +213,7 @@ struct msg_init {
s8 bayer;
u8 sensor_name[32];
u8 i2c_slave_addr;
u8 sub_sensor_num;
};
struct preisp_vc_cfg {
@@ -330,7 +331,7 @@ struct msg_calib_temp {
u32 calib_exist;
u32 calib_sn_size;
u32 calib_sn_offset;
u32 calib_sn_code;
u8 calib_sn_code[64];
#endif
};
+52
View File
@@ -235,6 +235,10 @@ static int rk1608_g_frame_interval(struct v4l2_subdev *sd,
{
struct rk1608_dphy *pdata = to_state(sd);
if (!(pdata->rk1608_sd)) {
dev_info(pdata->dev, "pdata->rk1608_sd NULL\n");
return -EFAULT;
}
pdata->rk1608_sd->grp_id = sd->grp_id;
v4l2_subdev_call(pdata->rk1608_sd,
video,
@@ -597,6 +601,7 @@ static int rk1608_dphy_dt_property(struct rk1608_dphy *dphy)
struct device_node *parent_node = of_node_get(node);
struct device_node *prev_node = NULL;
u32 idx = 0;
u32 sub_idx = 0;
ret = of_property_read_u32(node, "id", &dphy->sd.grp_id);
if (ret)
@@ -754,6 +759,53 @@ static int rk1608_dphy_dt_property(struct rk1608_dphy *dphy)
}
dphy->fmt_inf_num = idx;
prev_node = NULL;
/* get virtual sub sensor */
node = NULL;
while (!IS_ERR_OR_NULL(node =
of_get_next_child(parent_node, prev_node))) {
if (!strncasecmp(node->name,
"virtual-sub-sensor-config",
strlen("virtual-sub-sensor-config"))) {
if (sub_idx >= 4) {
dev_err(dphy->dev, "get too mach sub_sensor node, max 4.\n");
break;
}
ret = of_property_read_u32(node, "id",
&dphy->sub_sensor[sub_idx].id);
if (ret)
dev_warn(dphy->dev, "Can not get sub sensor id!");
else
dev_info(dphy->dev, "get sub sensor id:%d",
dphy->sub_sensor[sub_idx].id);
ret = of_property_read_u32(node, "in_mipi",
&dphy->sub_sensor[sub_idx].in_mipi);
if (ret)
dev_warn(dphy->dev, "Can not get sub sensor in_mipi!");
else
dev_info(dphy->dev, "get sub sensor in_mipi:%d",
dphy->sub_sensor[sub_idx].in_mipi);
ret = of_property_read_u32(node, "out_mipi",
&dphy->sub_sensor[sub_idx].out_mipi);
if (ret)
dev_warn(dphy->dev, "Can not get sub sensor out_mipi!");
else
dev_info(dphy->dev, "get sub sensor out_mipi:%d",
dphy->sub_sensor[sub_idx].out_mipi);
sub_idx++;
}
of_node_put(prev_node);
prev_node = node;
}
dphy->sub_sensor_num = sub_idx;
/* get virtual sub sensor end */
of_node_put(prev_node);
of_node_put(parent_node);
+11
View File
@@ -28,6 +28,13 @@ struct rk1608_fmt_inf {
u32 vcrop;
};
struct rk1608_sub_sensor_cfg {
u32 id;
u32 in_mipi;
u32 out_mipi;
u32 reserved;
};
struct rk1608_dphy {
struct v4l2_subdev sd;
struct v4l2_subdev *rk1608_sd;
@@ -63,6 +70,10 @@ struct rk1608_dphy {
struct rk1608_fmt_inf fmt_inf[RK1608_MAX_FMTINF];
bool first_stream;
/* for virtual sub sensor */
u32 sub_sensor_num;
struct rk1608_sub_sensor_cfg sub_sensor[4];
};
#endif