media: platform: rockchip: cif: optimize dts parameters config

Signed-off-by: Allon Huang <allon.huang@rock-chips.com>
Change-Id: I2a8f471e52c2099f562f1bf765ea0c3e5d9e5845
This commit is contained in:
Allon Huang
2021-03-25 15:05:51 +08:00
committed by Tao Huang
parent 279747103f
commit ef6aee87d2
5 changed files with 136 additions and 20 deletions

View File

@@ -434,20 +434,31 @@ static struct v4l2_subdev *get_remote_sensor(struct rkcif_stream *stream, u16 *i
{
struct media_pad *local, *remote;
struct media_entity *sensor_me;
struct v4l2_subdev *sub = NULL;
local = &stream->vnode.vdev.entity.pads[0];
if (!local)
if (!local) {
v4l2_err(&stream->cifdev->v4l2_dev,
"%s: video pad[0] is null\n", __func__);
return NULL;
}
remote = media_entity_remote_pad(local);
if (!remote)
if (!remote) {
v4l2_err(&stream->cifdev->v4l2_dev,
"%s: remote pad is null\n", __func__);
return NULL;
}
if (index)
*index = remote->index;
sensor_me = remote->entity;
return media_entity_to_v4l2_subdev(sensor_me);
sub = media_entity_to_v4l2_subdev(sensor_me);
return sub;
}
static void get_remote_terminal_sensor(struct rkcif_stream *stream,
@@ -2325,8 +2336,12 @@ int rkcif_update_sensor_info(struct rkcif_stream *stream)
int ret = 0;
sensor_sd = get_remote_sensor(stream, NULL);
if (!sensor_sd)
if (!sensor_sd) {
v4l2_err(&stream->cifdev->v4l2_dev,
"%s: stream[%d] get remote sensor_sd failed!\n",
__func__, stream->id);
return -ENODEV;
}
sensor = sd_to_sensor(stream->cifdev, sensor_sd);
if (!sensor) {
@@ -2982,6 +2997,7 @@ static int rkcif_fh_open(struct file *filp)
v4l2_err(vdev,
"update sensor info failed %d\n",
ret);
return ret;
}

View File

@@ -457,7 +457,6 @@ static int rkcif_create_links(struct rkcif_device *dev)
unsigned int s, pad, id, stream_num = 0;
bool mipi_lvds_linked = false;
if (dev->chip_id < CHIP_RV1126_CIF) {
if (dev->inf_id == RKCIF_MIPI_LVDS)
stream_num = RKCIF_MAX_STREAM_MIPI;
@@ -602,12 +601,52 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
{
struct rkcif_device *dev;
struct rkcif_sensor_info *sensor;
struct v4l2_subdev *sd;
struct v4l2_device *v4l2_dev = NULL;
int ret, index;
dev = container_of(notifier, struct rkcif_device, notifier);
v4l2_dev = &dev->v4l2_dev;
for (index = 0; index < dev->num_sensors; index++) {
sensor = &dev->sensors[index];
list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
if (sd->ops) {
if (sd == sensor->sd) {
ret = v4l2_subdev_call(sd,
video,
g_mbus_config,
&sensor->mbus);
if (ret)
v4l2_err(v4l2_dev,
"get mbus config failed for linking\n");
}
}
}
if (sensor->mbus.type == V4L2_MBUS_CCP2 ||
sensor->mbus.type == V4L2_MBUS_CSI2) {
switch (sensor->mbus.flags & V4L2_MBUS_CSI2_LANES) {
case V4L2_MBUS_CSI2_1_LANE:
sensor->lanes = 1;
break;
case V4L2_MBUS_CSI2_2_LANE:
sensor->lanes = 2;
break;
case V4L2_MBUS_CSI2_3_LANE:
sensor->lanes = 3;
break;
case V4L2_MBUS_CSI2_4_LANE:
sensor->lanes = 4;
break;
default:
sensor->lanes = 1;
}
}
if (sensor->mbus.type == V4L2_MBUS_CCP2) {
ret = rkcif_register_lvds_subdev(dev);
if (ret < 0) {
@@ -676,15 +715,19 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
struct rkcif_async_subdev *s_asd = container_of(asd,
struct rkcif_async_subdev, asd);
if (cif_dev->num_sensors == ARRAY_SIZE(cif_dev->sensors))
if (cif_dev->num_sensors == ARRAY_SIZE(cif_dev->sensors)) {
v4l2_err(&cif_dev->v4l2_dev,
"%s: the num of subdev is beyond %d\n",
__func__, cif_dev->num_sensors);
return -EBUSY;
}
cif_dev->sensors[cif_dev->num_sensors].lanes = s_asd->lanes;
cif_dev->sensors[cif_dev->num_sensors].mbus = s_asd->mbus;
cif_dev->sensors[cif_dev->num_sensors].sd = subdev;
++cif_dev->num_sensors;
v4l2_dbg(1, rkcif_debug, subdev, "Async registered subdev\n");
v4l2_err(subdev, "Async registered subdev\n");
return 0;
}
@@ -731,11 +774,17 @@ static int cif_subdev_notifier(struct rkcif_device *cif_dev)
ret = v4l2_async_notifier_parse_fwnode_endpoints(
dev, ntf, sizeof(struct rkcif_async_subdev), rkcif_fwnode_parse);
if (ret < 0)
if (ret < 0) {
v4l2_err(&cif_dev->v4l2_dev,
"%s: parse fwnode failed\n", __func__);
return ret;
}
if (!ntf->num_subdevs)
if (!ntf->num_subdevs) {
v4l2_warn(&cif_dev->v4l2_dev,
"%s: no subdev be found!\n", __func__);
return -ENODEV; /* no endpoint */
}
ntf->ops = &subdev_notifier_ops;

View File

@@ -207,6 +207,40 @@ static struct v4l2_subdev *get_remote_sensor(struct v4l2_subdev *sd)
return media_entity_to_v4l2_subdev(sensor_me);
}
static void csi2_update_sensor_info(struct csi2_dev *csi2)
{
struct csi2_sensor *sensor = &csi2->sensors[0];
struct v4l2_mbus_config mbus;
int ret = 0;
ret = v4l2_subdev_call(sensor->sd, video, g_mbus_config, &mbus);
if (ret) {
v4l2_err(&csi2->sd, "update sensor info failed!\n");
return;
}
csi2->bus.flags = mbus.flags;
switch (csi2->bus.flags & V4L2_MBUS_CSI2_LANES) {
case V4L2_MBUS_CSI2_1_LANE:
csi2->bus.num_data_lanes = 1;
break;
case V4L2_MBUS_CSI2_2_LANE:
csi2->bus.num_data_lanes = 2;
break;
case V4L2_MBUS_CSI2_3_LANE:
csi2->bus.num_data_lanes = 3;
break;
case V4L2_MBUS_CSI2_4_LANE:
csi2->bus.num_data_lanes = 4;
break;
default:
v4l2_warn(&csi2->sd, "lane num is invalid\n");
csi2->bus.num_data_lanes = 0;
break;
}
}
static void csi2_disable(struct csi2_dev *csi2)
{
void __iomem *base = csi2->base;
@@ -261,6 +295,8 @@ static int csi2_start(struct csi2_dev *csi2)
}
}
csi2_update_sensor_info(csi2);
if (csi2->format_mbus.code == MEDIA_BUS_FMT_RGB888_1X24)
host_type = RK_DSI_RXHOST;
else
@@ -514,12 +550,16 @@ static int csi2_set_selection(struct v4l2_subdev *sd,
static int csi2_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *mbus)
{
struct csi2_dev *csi2 = sd_to_dev(sd);
struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
int ret;
ret = v4l2_subdev_call(sensor_sd, video, g_mbus_config, mbus);
if (ret)
return ret;
if (ret) {
mbus->type = V4L2_MBUS_CSI2;
mbus->flags = csi2->bus.flags;
mbus->flags |= BIT(csi2->bus.num_data_lanes - 1);
}
return 0;
}
@@ -596,10 +636,8 @@ static int csi2_parse_endpoint(struct device *dev,
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct csi2_dev *csi2 = sd_to_dev(sd);
if (vep->bus_type != V4L2_MBUS_CSI2) {
v4l2_err(&csi2->sd,
"invalid bus type: %d, must be MIPI CSI2\n",
vep->bus_type);
if (vep->base.port != 0) {
dev_err(dev, "The csi host node needs to parse port 0\n");
return -EINVAL;
}
@@ -621,9 +659,12 @@ csi2_notifier_bound(struct v4l2_async_notifier *notifier,
struct media_link *link;
unsigned int pad, ret;
if (csi2->num_sensors == ARRAY_SIZE(csi2->sensors))
if (csi2->num_sensors == ARRAY_SIZE(csi2->sensors)) {
v4l2_err(&csi2->sd,
"%s: the num of sd is beyond:%d\n",
__func__, csi2->num_sensors);
return -EBUSY;
}
sensor = &csi2->sensors[csi2->num_sensors++];
sensor->sd = sd;
@@ -673,6 +714,7 @@ static void csi2_notifier_unbind(struct v4l2_async_notifier *notifier,
struct csi2_sensor *sensor = sd_to_sensor(csi2, sd);
sensor->sd = NULL;
}
static const struct
@@ -800,7 +842,10 @@ static int csi2_notifier(struct csi2_dev *csi2)
v4l2_async_notifier_cleanup(&csi2->notifier);
return ret;
}
return v4l2_async_register_subdev(&csi2->sd);
ret = v4l2_async_register_subdev(&csi2->sd);
return ret;
}
static const struct csi2_match_data rk1808_csi2_match_data = {

View File

@@ -75,7 +75,12 @@ static int sditf_get_set_fmt(struct v4l2_subdev *sd,
rkcif_update_sensor_info(&cif_dev->stream[0]);
if (cif_dev->terminal_sensor.sd) {
v4l2_subdev_call(cif_dev->terminal_sensor.sd, pad, get_fmt, NULL, fmt);
ret = v4l2_subdev_call(cif_dev->terminal_sensor.sd, pad, get_fmt, NULL, fmt);
if (ret) {
v4l2_err(&priv->sd,
"%s: get sensor format failed\n", __func__);
return ret;
}
input_sel.target = V4L2_SEL_TGT_CROP_BOUNDS;
ret = v4l2_subdev_call(cif_dev->terminal_sensor.sd,
@@ -87,7 +92,7 @@ static int sditf_get_set_fmt(struct v4l2_subdev *sd,
}
}
return ret;
return 0;
}
static int sditf_get_selection(struct v4l2_subdev *sd,

View File

@@ -60,6 +60,7 @@
*v0.1.10
*1. rv1126/rk356x support bt656/bt1120 multi channels function
*2. add dynamic cropping function
*3. optimize dts config of cif's pipeline
*/
#define RKCIF_DRIVER_VERSION RKCIF_API_VERSION