mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
media: platform: rockchip: cif: optimize dts parameters config
Signed-off-by: Allon Huang <allon.huang@rock-chips.com> Change-Id: I2a8f471e52c2099f562f1bf765ea0c3e5d9e5845 Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user