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 <johan.korsnes@xxxxxxxxx> > --- > 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; >