On 6/16/19 8:22 PM, Johan Korsnes wrote:
> Make the following properties per-input:
>
> -Standard Signal Mode
> -Standard
>
> These properties need to be per-input in order to implement proper HDMI
> (dis)connect-behavior, where the signal mode will be used to signify
> whether or not there is an inpute device connected.
>
> Signed-off-by: Johan Korsnes <[email protected]>
> ---
> drivers/media/platform/vivid/vivid-core.c | 5 +-
> drivers/media/platform/vivid/vivid-core.h | 10 ++--
> drivers/media/platform/vivid/vivid-ctrls.c | 13 +++--
> .../media/platform/vivid/vivid-kthread-cap.c | 6 +--
> drivers/media/platform/vivid/vivid-vbi-cap.c | 16 +++---
> drivers/media/platform/vivid/vivid-vid-cap.c | 50 +++++++++++--------
> .../media/platform/vivid/vivid-vid-common.c | 4 +-
> 7 files changed, 59 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/media/platform/vivid/vivid-core.c
> b/drivers/media/platform/vivid/vivid-core.c
> index f481f1768184..85e6aaf7bf0d 100644
> --- a/drivers/media/platform/vivid/vivid-core.c
> +++ b/drivers/media/platform/vivid/vivid-core.c
> @@ -999,14 +999,15 @@ static int vivid_create_instance(struct platform_device
> *pdev, int inst)
> dev->webcam_size_idx = 1;
> dev->webcam_ival_idx = 3;
> tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
> - dev->std_cap = V4L2_STD_PAL;
> dev->std_out = V4L2_STD_PAL;
> if (dev->input_type[0] == TV || dev->input_type[0] == SVID)
> tvnorms_cap = V4L2_STD_ALL;
> if (dev->output_type[0] == SVID)
> tvnorms_out = V4L2_STD_ALL;
> - for (i = 0; i < MAX_INPUTS; i++)
> + for (i = 0; i < MAX_INPUTS; i++) {
> dev->dv_timings_cap[i] = def_dv_timings;
> + dev->std_cap[i] = V4L2_STD_PAL;
> + }
> dev->dv_timings_out = def_dv_timings;
> dev->tv_freq = 2804 /* 175.25 * 16 */;
> dev->tv_audmode = V4L2_TUNER_MODE_STEREO;
> diff --git a/drivers/media/platform/vivid/vivid-core.h
> b/drivers/media/platform/vivid/vivid-core.h
> index a77c548f47d8..a18fd19215b6 100644
> --- a/drivers/media/platform/vivid/vivid-core.h
> +++ b/drivers/media/platform/vivid/vivid-core.h
> @@ -299,10 +299,10 @@ struct vivid_dev {
> bool time_wrap;
> u64 time_wrap_offset;
> unsigned perc_dropped_buffers;
> - enum vivid_signal_mode std_signal_mode;
> - unsigned query_std_last;
> - v4l2_std_id query_std;
> - enum tpg_video_aspect std_aspect_ratio;
> + enum vivid_signal_mode std_signal_mode[MAX_INPUTS];
> + unsigned query_std_last[MAX_INPUTS];
> + v4l2_std_id query_std[MAX_INPUTS];
> + enum tpg_video_aspect std_aspect_ratio[MAX_INPUTS];
>
> enum vivid_signal_mode dv_timings_signal_mode[MAX_INPUTS];
> char **query_dv_timings_qmenu;
> @@ -314,7 +314,7 @@ struct vivid_dev {
>
> /* Input */
> unsigned input;
> - v4l2_std_id std_cap;
> + v4l2_std_id std_cap[MAX_INPUTS];
> struct v4l2_dv_timings dv_timings_cap[MAX_INPUTS];
> int dv_timings_cap_sel[MAX_INPUTS];
> u32 service_set_cap;
> diff --git a/drivers/media/platform/vivid/vivid-ctrls.c
> b/drivers/media/platform/vivid/vivid-ctrls.c
> index a3c9661caf95..74b2c92fbfa0 100644
> --- a/drivers/media/platform/vivid/vivid-ctrls.c
> +++ b/drivers/media/platform/vivid/vivid-ctrls.c
> @@ -463,7 +463,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
> tpg_s_show_square(&dev->tpg, ctrl->val);
> break;
> case VIVID_CID_STD_ASPECT_RATIO:
> - dev->std_aspect_ratio = ctrl->val;
> + dev->std_aspect_ratio[dev->input] = ctrl->val;
> tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
> break;
> case VIVID_CID_DV_TIMINGS_SIGNAL_MODE:
> @@ -1130,10 +1130,13 @@ static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl
> *ctrl)
>
> switch (ctrl->id) {
> case VIVID_CID_STD_SIGNAL_MODE:
> - dev->std_signal_mode = dev->ctrl_std_signal_mode->val;
> - if (dev->std_signal_mode == SELECTED_STD)
> - dev->query_std =
> vivid_standard[dev->ctrl_standard->val];
> - v4l2_ctrl_activate(dev->ctrl_standard, dev->std_signal_mode ==
> SELECTED_STD);
> + dev->std_signal_mode[dev->input] =
> dev->ctrl_std_signal_mode->val;
> + if (dev->std_signal_mode[dev->input] == SELECTED_STD)
> + dev->query_std[dev->input] =
> + vivid_standard[dev->ctrl_standard->val];
> + v4l2_ctrl_activate(dev->ctrl_standard,
> + dev->std_signal_mode[dev->input] ==
> + SELECTED_STD);
> vivid_update_quality(dev);
> vivid_send_source_change(dev, TV);
> vivid_send_source_change(dev, SVID);
> diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c
> b/drivers/media/platform/vivid/vivid-kthread-cap.c
> index b4eee952e1c9..6cf495a7d5cc 100644
> --- a/drivers/media/platform/vivid/vivid-kthread-cap.c
> +++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
> @@ -43,7 +43,7 @@
> static inline v4l2_std_id vivid_get_std_cap(const struct vivid_dev *dev)
> {
> if (vivid_is_sdtv_cap(dev))
> - return dev->std_cap;
> + return dev->std_cap[dev->input];
> return 0;
> }
>
> @@ -408,7 +408,7 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct
> vivid_buffer *buf)
> unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
> unsigned line_height = 16 / factor;
> bool is_tv = vivid_is_sdtv_cap(dev);
> - bool is_60hz = is_tv && (dev->std_cap & V4L2_STD_525_60);
> + bool is_60hz = is_tv && (dev->std_cap[dev->input] & V4L2_STD_525_60);
> unsigned p;
> int line = 1;
> u8 *basep[TPG_MAX_PLANES][2];
> @@ -419,7 +419,7 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct
> vivid_buffer *buf)
>
> if (dev->loop_video && dev->can_loop_video &&
> ((vivid_is_svid_cap(dev) &&
> - !VIVID_INVALID_SIGNAL(dev->std_signal_mode)) ||
> + !VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) ||
> (vivid_is_hdmi_cap(dev) &&
>
> !VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input]))))
> is_loop = true;
> diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c
> b/drivers/media/platform/vivid/vivid-vbi-cap.c
> index 40ecd7902b56..1a9348eea781 100644
> --- a/drivers/media/platform/vivid/vivid-vbi-cap.c
> +++ b/drivers/media/platform/vivid/vivid-vbi-cap.c
> @@ -18,7 +18,7 @@
> static void vivid_sliced_vbi_cap_fill(struct vivid_dev *dev, unsigned seqnr)
> {
> struct vivid_vbi_gen_data *vbi_gen = &dev->vbi_gen;
> - bool is_60hz = dev->std_cap & V4L2_STD_525_60;
> + bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
>
> vivid_vbi_gen_sliced(vbi_gen, is_60hz, seqnr);
>
> @@ -65,7 +65,7 @@ static void vivid_sliced_vbi_cap_fill(struct vivid_dev
> *dev, unsigned seqnr)
>
> static void vivid_g_fmt_vbi_cap(struct vivid_dev *dev, struct
> v4l2_vbi_format *vbi)
> {
> - bool is_60hz = dev->std_cap & V4L2_STD_525_60;
> + bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
>
> vbi->sampling_rate = 27000000;
> vbi->offset = 24;
> @@ -93,7 +93,7 @@ void vivid_raw_vbi_cap_process(struct vivid_dev *dev,
> struct vivid_buffer *buf)
>
> memset(vbuf, 0x10, vb2_plane_size(&buf->vb.vb2_buf, 0));
>
> - if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode))
> + if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input]))
> vivid_vbi_gen_raw(&dev->vbi_gen, &vbi, vbuf);
> }
>
> @@ -111,7 +111,7 @@ void vivid_sliced_vbi_cap_process(struct vivid_dev *dev,
> vivid_sliced_vbi_cap_fill(dev, buf->vb.sequence);
>
> memset(vbuf, 0, vb2_plane_size(&buf->vb.vb2_buf, 0));
> - if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode)) {
> + if (!VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) {
> unsigned i;
>
> for (i = 0; i < 25; i++)
> @@ -124,7 +124,7 @@ static int vbi_cap_queue_setup(struct vb2_queue *vq,
> unsigned sizes[], struct device *alloc_devs[])
> {
> struct vivid_dev *dev = vb2_get_drv_priv(vq);
> - bool is_60hz = dev->std_cap & V4L2_STD_525_60;
> + bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
> unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE ?
> 36 * sizeof(struct v4l2_sliced_vbi_data) :
> 1440 * 2 * (is_60hz ? 12 : 18);
> @@ -144,7 +144,7 @@ static int vbi_cap_queue_setup(struct vb2_queue *vq,
> static int vbi_cap_buf_prepare(struct vb2_buffer *vb)
> {
> struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
> - bool is_60hz = dev->std_cap & V4L2_STD_525_60;
> + bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
> unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
> ?
> 36 * sizeof(struct v4l2_sliced_vbi_data) :
> 1440 * 2 * (is_60hz ? 12 : 18);
> @@ -302,7 +302,7 @@ int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void
> *fh, struct v4l2_forma
> {
> struct vivid_dev *dev = video_drvdata(file);
> struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
> - bool is_60hz = dev->std_cap & V4L2_STD_525_60;
> + bool is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
> u32 service_set = vbi->service_set;
>
> if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap)
> @@ -337,7 +337,7 @@ int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
> struct v4l2_sliced_vbi_
> bool is_60hz;
>
> if (vdev->vfl_dir == VFL_DIR_RX) {
> - is_60hz = dev->std_cap & V4L2_STD_525_60;
> + is_60hz = dev->std_cap[dev->input] & V4L2_STD_525_60;
> if (!vivid_is_sdtv_cap(dev) || !dev->has_sliced_vbi_cap ||
> cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
> return -EINVAL;
> diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c
> b/drivers/media/platform/vivid/vivid-vid-cap.c
> index f4354c800088..ca15c13abf6c 100644
> --- a/drivers/media/platform/vivid/vivid-vid-cap.c
> +++ b/drivers/media/platform/vivid/vivid-vid-cap.c
> @@ -196,7 +196,7 @@ static void vid_cap_buf_finish(struct vb2_buffer *vb)
> * test this.
> */
> vbuf->flags |= V4L2_BUF_FLAG_TIMECODE;
> - if (dev->std_cap & V4L2_STD_525_60)
> + if (dev->std_cap[dev->input] & V4L2_STD_525_60)
> fps = 30;
> tc->type = (fps == 30) ? V4L2_TC_TYPE_30FPS : V4L2_TC_TYPE_25FPS;
> tc->flags = 0;
> @@ -304,7 +304,8 @@ void vivid_update_quality(struct vivid_dev *dev)
> tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);
> return;
> }
> - if (vivid_is_sdtv_cap(dev) &&
> VIVID_INVALID_SIGNAL(dev->std_signal_mode)) {
> + if (vivid_is_sdtv_cap(dev) &&
> + VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) {
> tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0);
> return;
> }
> @@ -359,7 +360,7 @@ static enum tpg_quality vivid_get_quality(struct
> vivid_dev *dev, s32 *afc)
> enum tpg_video_aspect vivid_get_video_aspect(const struct vivid_dev *dev)
> {
> if (vivid_is_sdtv_cap(dev))
> - return dev->std_aspect_ratio;
> + return dev->std_aspect_ratio[dev->input];
>
> if (vivid_is_hdmi_cap(dev))
> return dev->dv_timings_aspect_ratio[dev->input];
> @@ -370,7 +371,7 @@ enum tpg_video_aspect vivid_get_video_aspect(const struct
> vivid_dev *dev)
> static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev
> *dev)
> {
> if (vivid_is_sdtv_cap(dev))
> - return (dev->std_cap & V4L2_STD_525_60) ?
> + return (dev->std_cap[dev->input] & V4L2_STD_525_60) ?
> TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
>
> if (vivid_is_hdmi_cap(dev) &&
> @@ -404,7 +405,7 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool
> keep_controls)
> case SVID:
> dev->field_cap = dev->tv_field_cap;
> dev->src_rect.width = 720;
> - if (dev->std_cap & V4L2_STD_525_60) {
> + if (dev->std_cap[dev->input] & V4L2_STD_525_60) {
> dev->src_rect.height = 480;
> dev->timeperframe_vid_cap = (struct v4l2_fract) { 1001,
> 30000 };
> dev->service_set_cap = V4L2_SLICED_CAPTION_525;
> @@ -587,7 +588,7 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
> h = sz->height;
> } else if (vivid_is_sdtv_cap(dev)) {
> w = 720;
> - h = (dev->std_cap & V4L2_STD_525_60) ? 480 : 576;
> + h = (dev->std_cap[dev->input] & V4L2_STD_525_60) ? 480 : 576;
> } else {
> w = dev->src_rect.width;
> h = dev->src_rect.height;
> @@ -1323,9 +1324,9 @@ int vidioc_enum_input(struct file *file, void *priv,
> if (dev->sensor_vflip)
> inp->status |= V4L2_IN_ST_VFLIP;
> if (dev->input == inp->index && vivid_is_sdtv_cap(dev)) {
> - if (dev->std_signal_mode == NO_SIGNAL) {
> + if (dev->std_signal_mode[dev->input] == NO_SIGNAL) {
> inp->status |= V4L2_IN_ST_NO_SIGNAL;
> - } else if (dev->std_signal_mode == NO_LOCK) {
> + } else if (dev->std_signal_mode[dev->input] == NO_LOCK) {
> inp->status |= V4L2_IN_ST_NO_H_LOCK;
> } else if (vivid_is_tv_cap(dev)) {
> switch (tpg_g_quality(&dev->tpg)) {
> @@ -1415,11 +1416,20 @@ int vidioc_s_input(struct file *file, void *priv,
> unsigned i)
> v4l2_ctrl_activate(dev->ctrl_dv_timings, vivid_is_hdmi_cap(dev) &&
> dev->dv_timings_signal_mode[dev->input] ==
> SELECTED_DV_TIMINGS);
> + v4l2_ctrl_activate(dev->ctrl_std_signal_mode, vivid_is_sdtv_cap(dev));
> + v4l2_ctrl_activate(dev->ctrl_standard, vivid_is_sdtv_cap(dev) &&
> + dev->std_signal_mode[dev->input]);
> +
> if (vivid_is_hdmi_cap(dev)) {
> v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings_signal_mode,
> dev->dv_timings_signal_mode[dev->input]);
> v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings,
> dev->query_dv_timings[dev->input]);
> + } else if (vivid_is_sdtv_cap(dev)) {
> + v4l2_ctrl_s_ctrl(dev->ctrl_std_signal_mode,
> + dev->std_signal_mode[dev->input]);
> + v4l2_ctrl_s_ctrl(dev->ctrl_standard,
> + dev->std_signal_mode[dev->input]);
> }
>
> return 0;
> @@ -1515,7 +1525,7 @@ int vivid_video_g_tuner(struct file *file, void *fh,
> struct v4l2_tuner *vt)
> vt->rxsubchans = V4L2_TUNER_SUB_MONO;
> } else {
> unsigned channel_nr = dev->tv_freq / (6 * 16);
> - unsigned options = (dev->std_cap & V4L2_STD_NTSC_M) ? 4 : 3;
> + unsigned options = (dev->std_cap[dev->input] & V4L2_STD_NTSC_M)
> ? 4 : 3;
>
> switch (channel_nr % options) {
> case 0:
> @@ -1525,7 +1535,7 @@ int vivid_video_g_tuner(struct file *file, void *fh,
> struct v4l2_tuner *vt)
> vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
> break;
> case 2:
> - if (dev->std_cap & V4L2_STD_NTSC_M)
> + if (dev->std_cap[dev->input] & V4L2_STD_NTSC_M)
> vt->rxsubchans = V4L2_TUNER_SUB_MONO |
> V4L2_TUNER_SUB_SAP;
> else
> vt->rxsubchans = V4L2_TUNER_SUB_LANG1 |
> V4L2_TUNER_SUB_LANG2;
> @@ -1585,20 +1595,20 @@ int vidioc_querystd(struct file *file, void *priv,
> v4l2_std_id *id)
>
> if (!vivid_is_sdtv_cap(dev))
> return -ENODATA;
> - if (dev->std_signal_mode == NO_SIGNAL ||
> - dev->std_signal_mode == NO_LOCK) {
> + if (dev->std_signal_mode[dev->input] == NO_SIGNAL ||
> + dev->std_signal_mode[dev->input] == NO_LOCK) {
> *id = V4L2_STD_UNKNOWN;
> return 0;
> }
> if (vivid_is_tv_cap(dev) && tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE)
> {
> *id = V4L2_STD_UNKNOWN;
> - } else if (dev->std_signal_mode == CURRENT_STD) {
> - *id = dev->std_cap;
> - } else if (dev->std_signal_mode == SELECTED_STD) {
> - *id = dev->query_std;
> + } else if (dev->std_signal_mode[dev->input] == CURRENT_STD) {
> + *id = dev->std_cap[dev->input];
> + } else if (dev->std_signal_mode[dev->input] == SELECTED_STD) {
> + *id = dev->query_std[dev->input];
> } else {
> - *id = vivid_standard[dev->query_std_last];
> - dev->query_std_last = (dev->query_std_last + 1) %
> ARRAY_SIZE(vivid_standard);
> + *id = vivid_standard[dev->query_std_last[dev->input]];
> + dev->query_std_last[dev->input] =
> (dev->query_std_last[dev->input] + 1) % ARRAY_SIZE(vivid_standard);
Please reformat this: this line is way too long :-)
I suggest adding a temp variable:
unsigned int last = dev->query_std_last[dev->input];
*id = vivid_standard[last];
dev->query_std_last[dev->input] =
(last + 1) % ARRAY_SIZE(vivid_standard);
Regards,
Hans
> }
>
> return 0;
> @@ -1610,11 +1620,11 @@ int vivid_vid_cap_s_std(struct file *file, void
> *priv, v4l2_std_id id)
>
> if (!vivid_is_sdtv_cap(dev))
> return -ENODATA;
> - if (dev->std_cap == id)
> + if (dev->std_cap[dev->input] == id)
> return 0;
> if (vb2_is_busy(&dev->vb_vid_cap_q) || vb2_is_busy(&dev->vb_vbi_cap_q))
> return -EBUSY;
> - dev->std_cap = id;
> + dev->std_cap[dev->input] = id;
> vivid_update_format_cap(dev, false);
> return 0;
> }
> diff --git a/drivers/media/platform/vivid/vivid-vid-common.c
> b/drivers/media/platform/vivid/vivid-vid-common.c
> index 98c0e5b4d391..10a344c29a1a 100644
> --- a/drivers/media/platform/vivid/vivid-vid-common.c
> +++ b/drivers/media/platform/vivid/vivid-vid-common.c
> @@ -645,7 +645,7 @@ bool vivid_vid_can_loop(struct vivid_dev *dev)
> dev->field_cap == V4L2_FIELD_SEQ_BT)
> return false;
> if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
> - if (!(dev->std_cap & V4L2_STD_525_60) !=
> + if (!(dev->std_cap[dev->input] & V4L2_STD_525_60) !=
> !(dev->std_out & V4L2_STD_525_60))
> return false;
> return true;
> @@ -805,7 +805,7 @@ int vidioc_g_std(struct file *file, void *priv,
> v4l2_std_id *id)
> if (vdev->vfl_dir == VFL_DIR_RX) {
> if (!vivid_is_sdtv_cap(dev))
> return -ENODATA;
> - *id = dev->std_cap;
> + *id = dev->std_cap[dev->input];
> } else {
> if (!vivid_is_svid_out(dev))
> return -ENODATA;
>