Commit 009e1256 authored by Paweł Anikiel's avatar Paweł Anikiel Committed by Hans Verkuil

media: v4l2-subdev: Add pad versions of dv timing subdev calls

Currently, subdev dv timing calls (i.e. g/s/query_dv_timings) are video
ops without a pad argument. This is a problem if the subdevice can have
different dv timings for each pad (e.g. a DisplayPort receiver with
multiple virtual channels).

To solve this, change these calls to include a pad argument, and put
them into pad ops. Keep the old ones temporarily to make the switch
easier.
Signed-off-by: default avatarPaweł Anikiel <panikiel@google.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 682f4968
...@@ -369,6 +369,36 @@ static int call_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid) ...@@ -369,6 +369,36 @@ static int call_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
return check_edid(sd, edid) ? : sd->ops->pad->set_edid(sd, edid); return check_edid(sd, edid) ? : sd->ops->pad->set_edid(sd, edid);
} }
static int call_s_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_dv_timings *timings)
{
if (!timings)
return -EINVAL;
return check_pad(sd, pad) ? :
sd->ops->pad->s_dv_timings(sd, pad, timings);
}
static int call_g_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_dv_timings *timings)
{
if (!timings)
return -EINVAL;
return check_pad(sd, pad) ? :
sd->ops->pad->g_dv_timings(sd, pad, timings);
}
static int call_query_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_dv_timings *timings)
{
if (!timings)
return -EINVAL;
return check_pad(sd, pad) ? :
sd->ops->pad->query_dv_timings(sd, pad, timings);
}
static int call_dv_timings_cap(struct v4l2_subdev *sd, static int call_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap) struct v4l2_dv_timings_cap *cap)
{ {
...@@ -487,6 +517,9 @@ static const struct v4l2_subdev_pad_ops v4l2_subdev_call_pad_wrappers = { ...@@ -487,6 +517,9 @@ static const struct v4l2_subdev_pad_ops v4l2_subdev_call_pad_wrappers = {
.set_frame_interval = call_set_frame_interval, .set_frame_interval = call_set_frame_interval,
.get_edid = call_get_edid, .get_edid = call_get_edid,
.set_edid = call_set_edid, .set_edid = call_set_edid,
.s_dv_timings = call_s_dv_timings,
.g_dv_timings = call_g_dv_timings,
.query_dv_timings = call_query_dv_timings,
.dv_timings_cap = call_dv_timings_cap, .dv_timings_cap = call_dv_timings_cap,
.enum_dv_timings = call_enum_dv_timings, .enum_dv_timings = call_enum_dv_timings,
.get_frame_desc = call_get_frame_desc, .get_frame_desc = call_get_frame_desc,
......
...@@ -791,6 +791,14 @@ struct v4l2_subdev_state { ...@@ -791,6 +791,14 @@ struct v4l2_subdev_state {
* *
* @set_edid: callback for VIDIOC_SUBDEV_S_EDID() ioctl handler code. * @set_edid: callback for VIDIOC_SUBDEV_S_EDID() ioctl handler code.
* *
* @s_dv_timings: Set custom dv timings in the sub device. This is used
* when sub device is capable of setting detailed timing information
* in the hardware to generate/detect the video signal.
*
* @g_dv_timings: Get custom dv timings in the sub device.
*
* @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code.
*
* @dv_timings_cap: callback for VIDIOC_SUBDEV_DV_TIMINGS_CAP() ioctl handler * @dv_timings_cap: callback for VIDIOC_SUBDEV_DV_TIMINGS_CAP() ioctl handler
* code. * code.
* *
...@@ -864,6 +872,12 @@ struct v4l2_subdev_pad_ops { ...@@ -864,6 +872,12 @@ struct v4l2_subdev_pad_ops {
struct v4l2_subdev_frame_interval *interval); struct v4l2_subdev_frame_interval *interval);
int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
int (*s_dv_timings)(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_dv_timings *timings);
int (*g_dv_timings)(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_dv_timings *timings);
int (*query_dv_timings)(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_dv_timings *timings);
int (*dv_timings_cap)(struct v4l2_subdev *sd, int (*dv_timings_cap)(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap); struct v4l2_dv_timings_cap *cap);
int (*enum_dv_timings)(struct v4l2_subdev *sd, int (*enum_dv_timings)(struct v4l2_subdev *sd,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment