@@ -807,7 +807,6 @@ static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
for (i = 0; i < RCAR_VIN_NUM; i++) {
if (group->vin[i] &&
group->vin[i]->parallel.subdev == sd) {
- group->vin[i]->is_csi = false;
ret = 0;
goto out;
}
@@ -865,8 +864,6 @@ static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
ret = rvin_set_channel_routing(group->vin[master_id], chsel);
if (ret)
goto out;
-
- vin->is_csi = true;
}
out:
mutex_unlock(&group->lock);
@@ -178,6 +178,28 @@ static bool rvin_scaler_needed(const struct rvin_dev *vin)
vin->compose.height == vin->format.height);
}
+static struct v4l2_subdev *rvin_remote_subdev(const struct rvin_dev *vin)
+{
+ struct media_pad *pad;
+
+ if (!vin->info->use_mc)
+ return vin->parallel.subdev;
+
+ pad = media_pad_remote_pad_first(&vin->pad);
+ if (!pad)
+ return NULL;
+
+ return media_entity_to_v4l2_subdev(pad->entity);
+}
+
+static bool rvin_remote_is_parallel(const struct rvin_dev *vin)
+{
+ if (!vin->parallel.subdev)
+ return false;
+
+ return rvin_remote_subdev(vin) == vin->parallel.subdev;
+}
+
struct vin_coeff {
unsigned short xs_value;
u32 coeff_set[24];
@@ -752,7 +774,7 @@ static int rvin_setup(struct rvin_dev *vin)
break;
case MEDIA_BUS_FMT_UYVY8_2X8:
/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
- if (!vin->is_csi &&
+ if (rvin_remote_is_parallel(vin) &&
vin->parallel.mbus_type == V4L2_MBUS_BT656)
vnmc |= VNMC_INF_YUV8_BT656;
else
@@ -765,7 +787,7 @@ static int rvin_setup(struct rvin_dev *vin)
break;
case MEDIA_BUS_FMT_UYVY10_2X10:
/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
- if (!vin->is_csi &&
+ if (rvin_remote_is_parallel(vin) &&
vin->parallel.mbus_type == V4L2_MBUS_BT656)
vnmc |= VNMC_INF_YUV10_BT656;
else
@@ -791,13 +813,13 @@ static int rvin_setup(struct rvin_dev *vin)
case VNMC_INF_YUV10_BT656:
case VNMC_INF_YUV16:
case VNMC_INF_RGB666:
- if (vin->is_csi) {
+ if (!rvin_remote_is_parallel(vin)) {
vin_err(vin, "Invalid setting in MIPI CSI2\n");
return -EINVAL;
}
break;
case VNMC_INF_RAW8:
- if (!vin->is_csi) {
+ if (rvin_remote_is_parallel(vin)) {
vin_err(vin, "Invalid setting in Digital Pins\n");
return -EINVAL;
}
@@ -813,7 +835,7 @@ static int rvin_setup(struct rvin_dev *vin)
else
dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
- if (!vin->is_csi) {
+ if (rvin_remote_is_parallel(vin)) {
/* Hsync Signal Polarity Select */
if (!(vin->parallel.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
dmr2 |= VNDMR2_HPS;
@@ -904,10 +926,10 @@ static int rvin_setup(struct rvin_dev *vin)
if (vin->info->model == RCAR_GEN3) {
/* Select between CSI-2 and parallel input */
- if (vin->is_csi)
- vnmc &= ~VNMC_DPINE;
- else
+ if (rvin_remote_is_parallel(vin))
vnmc |= VNMC_DPINE;
+ else
+ vnmc &= ~VNMC_DPINE;
}
}
@@ -1337,14 +1359,16 @@ static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd,
static int rvin_set_stream(struct rvin_dev *vin, int on)
{
- struct v4l2_subdev *sd;
+ struct v4l2_subdev *sd = rvin_remote_subdev(vin);
struct media_pad *pad;
int ret;
+ if (!sd)
+ return -EPIPE;
+
/* No media controller used, simply pass operation to subdevice. */
if (!vin->info->use_mc) {
- ret = v4l2_subdev_call(vin->parallel.subdev, video, s_stream,
- on);
+ ret = v4l2_subdev_call(sd, video, s_stream, on);
return ret == -ENOIOCTLCMD ? 0 : ret;
}
@@ -1353,8 +1377,6 @@ static int rvin_set_stream(struct rvin_dev *vin, int on)
if (!pad)
return -EPIPE;
- sd = media_entity_to_v4l2_subdev(pad->entity);
-
if (!on) {
video_device_pipeline_stop(&vin->vdev);
return v4l2_subdev_call(sd, video, s_stream, 0);
@@ -202,7 +202,6 @@ struct rvin_info {
* @sequence: V4L2 buffers sequence number
* @state: keeps track of operation state
*
- * @is_csi: flag to mark the VIN as using a CSI-2 subdevice
* @chsel: Cached value of the current CSI-2 channel selection
*
* @mbus_code: media bus format code
@@ -246,7 +245,6 @@ struct rvin_dev {
unsigned int sequence;
enum rvin_dma_state state;
- bool is_csi;
unsigned int chsel;
u32 mbus_code;
The video source connected to a VIN instance can be either be a CSI-2 receiver, a CS-ISP or a parallel device. Each one requiring slightly different configuration, sometimes reusing the same registers with different meaning depending on what video source is used. The video source type can change at run-time using the media device API. This was introduced with R-Car Gen3 with two possible video sources and have since been extended with one more. Instead of adding more flags that needs to be set/cleared when changing links in the media graph add functionality to use the media device to determine the video source type. Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> --- .../platform/renesas/rcar-vin/rcar-core.c | 3 -- .../platform/renesas/rcar-vin/rcar-dma.c | 48 ++++++++++++++----- .../platform/renesas/rcar-vin/rcar-vin.h | 2 - 3 files changed, 35 insertions(+), 18 deletions(-)