vivid: Add HDMI (dis)connect emulation
Subsystems (2)
This patch series makes vivid V4L2-compliant* by adding HDMI (dis)- connect emulation. This is done by by adding a custom display_present control to vivid output HDMI devices, along with the following standard controls:
-ctrl_tx_edid_present
-ctrl_tx_hotplug
-ctrl_tx_rxsense
-ctrl_rx_power_present
* Fixes the following warning for HDMI input devices:
-V4L2_CID_DV_RX_POWER_PRESENT not found for input n
Fixes the following warnings for HDMI ouptut devices:
-V4L2_CID_DV_TX_HOTPLUG not found for output n -V4L2_CID_DV_TX_EDID_PRESENT not found for output n
Johan Korsnes (8):
media: vivid: make input dv_timings per-input
media: vivid: make input std_signal per-input
media: vivid: add display present control
media: vivid: add number of HDMI ports to device state
media: vivid: add HDMI (dis)connect TX emulation
media: vivid: add HDMI (dis)connect RX emulation
media: vivid: add CEC support to display present ctrl
media: vivid.rst: describe display present control
Documentation/media/v4l-drivers/vivid.rst | 5 + drivers/media/platform/vivid/vivid-core.c | 36 ++++-- drivers/media/platform/vivid/vivid-core.h | 32 +++-- drivers/media/platform/vivid/vivid-ctrls.c | 105 ++++++++++++++-- .../media/platform/vivid/vivid-kthread-cap.c | 8 +- drivers/media/platform/vivid/vivid-vbi-cap.c | 16 +-- drivers/media/platform/vivid/vivid-vid-cap.c | 119 +++++++++++------- .../media/platform/vivid/vivid-vid-common.c | 8 +- drivers/media/platform/vivid/vivid-vid-out.c | 6 + 9 files changed, 245 insertions(+), 90 deletions(-)
PATCH 1/8 media: vivid: make input dv_timings per-input
From: Johan Korsnes <[email protected]>
Make the following properties per-input
-DV Timings Signal Mode
-DV Timings
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 input device connected.
--- drivers/media/platform/vivid/vivid-core.c | 12 +++- drivers/media/platform/vivid/vivid-core.h | 11 ++-- drivers/media/platform/vivid/vivid-ctrls.c | 13 ++-- .../media/platform/vivid/vivid-kthread-cap.c | 2 +- drivers/media/platform/vivid/vivid-vid-cap.c | 63 ++++++++++++------- .../media/platform/vivid/vivid-vid-common.c | 2 +- 6 files changed, 69 insertions(+), 34 deletions(-)
drivers/media/platform/vivid/vivid-core.c +11 -1
@@ -1007,7 +1007,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) tvnorms_cap =V4L2_STD_ALL ;if (dev->output_type[0 ] ==SVID ) tvnorms_out =V4L2_STD_ALL ; - dev->dv_timings_cap = def_dv_timings; +for (i =0 ; i <MAX_INPUTS ; i++) + dev->dv_timings_cap[i] = def_dv_timings; dev->dv_timings_out = def_dv_timings; dev->tv_freq =2804 /* 175.25 * 16 */ ; dev->tv_audmode =V4L2_TUNER_MODE_STEREO ;
@@ -1037,6 +1038,15 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)if (ret) goto unreg_dev; +/* enable/disable interface specific controls */ +if (dev->num_inputs && dev->input_type[0 ] !=HDMI ) { +v4l2_ctrl_activate (dev->ctrl_dv_timings_signal_mode, false); +v4l2_ctrl_activate (dev->ctrl_dv_timings, false); + }else if (dev->num_inputs && dev->input_type[0 ] ==HDMI ) { +v4l2_ctrl_activate (dev->ctrl_std_signal_mode, false); +v4l2_ctrl_activate (dev->ctrl_standard, false); + } +/* * update the capture and output formats to do a proper initial * configuration.
drivers/media/platform/vivid/vivid-core.h +6 -5
@@ -304,18 +304,19 @@ struct vivid_dev {v4l2_std_id query_std;enum tpg_video_aspect std_aspect_ratio; -enum vivid_signal_mode dv_timings_signal_mode; +enum vivid_signal_mode dv_timings_signal_mode[MAX_INPUTS ];char **query_dv_timings_qmenu;char *query_dv_timings_qmenu_strings;unsigned query_dv_timings_size; -unsigned query_dv_timings_last; -unsigned query_dv_timings; -enum tpg_video_aspect dv_timings_aspect_ratio; +unsigned query_dv_timings_last[MAX_INPUTS ]; +unsigned query_dv_timings[MAX_INPUTS ]; +enum tpg_video_aspect dv_timings_aspect_ratio[MAX_INPUTS ];/* Input */ unsigned input;v4l2_std_id std_cap; -struct v4l2_dv_timings dv_timings_cap; +struct v4l2_dv_timings dv_timings_cap[MAX_INPUTS ]; +int dv_timings_cap_sel[MAX_INPUTS ];u32 service_set_cap;struct vivid_vbi_gen_data vbi_gen;u8 *edid;
drivers/media/platform/vivid/vivid-ctrls.c +8 -5
@@ -467,16 +467,19 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)tpg_s_video_aspect (&dev->tpg,vivid_get_video_aspect (dev));break ;case VIVID_CID_DV_TIMINGS_SIGNAL_MODE : - dev->dv_timings_signal_mode = dev->ctrl_dv_timings_signal_mode->val; -if (dev->dv_timings_signal_mode ==SELECTED_DV_TIMINGS ) - dev->query_dv_timings = dev->ctrl_dv_timings->val; + dev->dv_timings_signal_mode[dev->input] = + dev->ctrl_dv_timings_signal_mode->val; + dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val; +v4l2_ctrl_activate (dev->ctrl_dv_timings, - dev->dv_timings_signal_mode ==SELECTED_DV_TIMINGS ); + dev->dv_timings_signal_mode[dev->input] == +SELECTED_DV_TIMINGS ); +vivid_update_quality (dev);vivid_send_source_change (dev,HDMI );break ;case VIVID_CID_DV_TIMINGS_ASPECT_RATIO : - dev->dv_timings_aspect_ratio = ctrl->val; + dev->dv_timings_aspect_ratio[dev->input] = ctrl->val;tpg_s_video_aspect (&dev->tpg,vivid_get_video_aspect (dev));break ;case VIVID_CID_TSTAMP_SRC :
drivers/media/platform/vivid/vivid-kthread-cap.c +1 -1
@@ -421,7 +421,7 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) ((vivid_is_svid_cap (dev) && !VIVID_INVALID_SIGNAL (dev->std_signal_mode)) || (vivid_is_hdmi_cap (dev) && - !VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode)))) + !VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input])))) is_loop = true; buf->vb.sequence = dev->vid_cap_seq_count;
drivers/media/platform/vivid/vivid-vid-cap.c +42 -21
132 lines not on this page · raw message
drivers/media/platform/vivid/vivid-vid-common.c +1 -1
@@ -843,7 +843,7 @@ int vidioc_g_dv_timings(struct file *file, void *_fh,if (vdev->vfl_dir ==VFL_DIR_RX ) {if (!vivid_is_hdmi_cap (dev))return -ENODATA ; - *timings = dev->dv_timings_cap; + *timings = dev->dv_timings_cap[dev->input]; }else {if (!vivid_is_hdmi_out (dev))return -ENODATA ;
Signature · 1 line
2.17.1
PATCH 2/8 media: vivid: make input std_signal per-input
In reply to [email protected]From: Johan Korsnes <[email protected]>
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.
--- 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(-)
drivers/media/platform/vivid/vivid-core.c +3 -2
@@ -1001,14 +1001,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 ;
drivers/media/platform/vivid/vivid-core.h +5 -5
@@ -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;
drivers/media/platform/vivid/vivid-ctrls.c +8 -5
@@ -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 );
drivers/media/platform/vivid/vivid-kthread-cap.c +3 -3
@@ -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;
drivers/media/platform/vivid/vivid-vbi-cap.c +8 -8
@@ -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 ;
drivers/media/platform/vivid/vivid-vid-cap.c +30 -20
137 lines not on this page · raw message
drivers/media/platform/vivid/vivid-vid-common.c +2 -2
@@ -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;
@@ -825,7 +825,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 ;
Signature · 1 line
2.17.1
PATCH 3/8 media: vivid: add display present control
In reply to [email protected]From: Johan Korsnes <[email protected]>
Add a custom control for selecting the presence of a display connected to the active output. This control is part of an effort to implement proper HDMI (dis)connect behavior for vivid.
--- drivers/media/platform/vivid/vivid-core.c | 3 +++ drivers/media/platform/vivid/vivid-core.h | 2 ++ drivers/media/platform/vivid/vivid-ctrls.c | 18 ++++++++++++++++++ drivers/media/platform/vivid/vivid-vid-out.c | 6 ++++++ 4 files changed, 29 insertions(+)
drivers/media/platform/vivid/vivid-core.c +3 -0
@@ -732,6 +732,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)for (i =0 ; i < dev->num_outputs; i++) { dev->output_type[i] = ((output_types[inst] >> i) &1 ) ?HDMI :SVID ; dev->output_name_counter[i] = out_type_counter[dev->output_type[i]]++; + dev->display_present[i] = true; } dev->has_audio_outputs = out_type_counter[SVID ];if (out_type_counter[HDMI ] ==16 ) {
@@ -1040,6 +1041,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) goto unreg_dev;/* enable/disable interface specific controls */ +if (dev->num_outputs && dev->output_type[0 ] !=HDMI ) +v4l2_ctrl_activate (dev->ctrl_display_present, false);if (dev->num_inputs && dev->input_type[0 ] !=HDMI ) {v4l2_ctrl_activate (dev->ctrl_dv_timings_signal_mode, false);v4l2_ctrl_activate (dev->ctrl_dv_timings, false);
drivers/media/platform/vivid/vivid-core.h +2 -0
@@ -237,6 +237,7 @@ struct vivid_dev {struct v4l2_ctrl *ctrl_dv_timings_signal_mode;struct v4l2_ctrl *ctrl_dv_timings; }; +struct v4l2_ctrl *ctrl_display_present;struct v4l2_ctrl *ctrl_has_crop_cap;struct v4l2_ctrl *ctrl_has_compose_cap;struct v4l2_ctrl *ctrl_has_scaler_cap;
@@ -361,6 +362,7 @@ struct vivid_dev {u8 *scaled_line;u8 *blended_line;unsigned cur_scaled_line; +bool display_present[MAX_OUTPUTS ];/* Output Overlay */ void *fb_vbase_out;
drivers/media/platform/vivid/vivid-ctrls.c +18 -0
@@ -68,6 +68,7 @@#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41)#define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)#define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43) +#define VIVID_CID_DISPLAY_PRESENT (VIVID_CID_VIVID_BASE + 44)#define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)#define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
@@ -944,6 +945,12 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)if (dev->loop_video)vivid_send_source_change (dev,HDMI );break ; +case VIVID_CID_DISPLAY_PRESENT : +if (dev->output_type[dev->output] !=HDMI ) +break ; + + dev->display_present[dev->output] = ctrl->val; +break ; }return 0 ; }
@@ -982,6 +989,15 @@ static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = { .step = 1, }; +static const struct v4l2_ctrl_config vivid_ctrl_display_present = { + .ops = &vivid_vid_out_ctrl_ops, + .id =VIVID_CID_DISPLAY_PRESENT , + .name ="Display Present" , + .type =V4L2_CTRL_TYPE_BOOLEAN , + .max =1 , + .def =1 , + .step =1 , +};/* Streaming Controls */
@@ -1587,6 +1603,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, dev->ctrl_tx_mode =v4l2_ctrl_new_std_menu (hdl_vid_out,NULL ,V4L2_CID_DV_TX_MODE ,V4L2_DV_TX_MODE_HDMI ,0 ,V4L2_DV_TX_MODE_HDMI ); + dev->ctrl_display_present =v4l2_ctrl_new_custom (hdl_vid_out, + &vivid_ctrl_display_present,NULL ); }if ((dev->has_vid_cap && dev->has_vid_out) || (dev->has_vbi_cap && dev->has_vbi_out))
drivers/media/platform/vivid/vivid-vid-out.c +6 -0
@@ -1094,6 +1094,12 @@ int vidioc_s_output(struct file *file, void *priv, unsigned o) dev->vbi_out_dev.tvnorms = dev->vid_out_dev.tvnorms;vivid_update_format_out (dev); + +v4l2_ctrl_activate (dev->ctrl_display_present,vivid_is_hdmi_out (dev)); +if (vivid_is_hdmi_out (dev)) +v4l2_ctrl_s_ctrl (dev->ctrl_display_present, + dev->display_present[dev->output]); +return 0 ; }
Signature · 1 line
2.17.1
PATCH 4/8 media: vivid: add number of HDMI ports to device state
In reply to [email protected]From: Johan Korsnes <[email protected]>
This will be used for HDMI-specific controls such as hotplug detection and power present.
--- drivers/media/platform/vivid/vivid-core.c | 2 ++ drivers/media/platform/vivid/vivid-core.h | 2 ++ 2 files changed, 4 insertions(+)
drivers/media/platform/vivid/vivid-core.c +2 -0
@@ -722,6 +722,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) in_type_counter[HDMI ]--; dev->num_inputs--; } + dev->num_hdmi_inputs = in_type_counter[HDMI ];/* how many outputs do we have and of what type? */ dev->num_outputs = num_outputs[inst];
@@ -744,6 +745,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) out_type_counter[HDMI ]--; dev->num_outputs--; } + dev->num_hdmi_outputs = out_type_counter[HDMI ];/* do we create a video capture device? */ dev->has_vid_cap = node_type &0x0001 ;
drivers/media/platform/vivid/vivid-core.h +2 -0
@@ -180,9 +180,11 @@ struct vivid_dev {/* supported features */ bool multiplanar;unsigned num_inputs; +unsigned num_hdmi_inputs;u8 input_type[MAX_INPUTS ];u8 input_name_counter[MAX_INPUTS ];unsigned num_outputs; +unsigned num_hdmi_outputs;u8 output_type[MAX_OUTPUTS ];u8 output_name_counter[MAX_OUTPUTS ];bool has_audio_inputs;
Signature · 1 line
2.17.1
PATCH 5/8 media: vivid: add HDMI (dis)connect TX emulation
In reply to [email protected]From: Johan Korsnes <[email protected]>
Adds the following bitmask controls:
-V4L2_CID_DV_TX_EDID_PRESENT
-V4L2_CID_DV_TX_HOTPLUG
-V4L2_CID_DV_TX_RXSENSE
The bitmasks are all set based on the custom vivid DISPLAY_PRESENT control. This also removes 2/2 v4l2-compliance warnings for vivid output device.
--- drivers/media/platform/vivid/vivid-core.h | 3 +++ drivers/media/platform/vivid/vivid-ctrls.c | 25 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-)
drivers/media/platform/vivid/vivid-core.h +3 -0
@@ -248,6 +248,9 @@ struct vivid_dev {struct v4l2_ctrl *ctrl_has_scaler_out;struct v4l2_ctrl *ctrl_tx_mode;struct v4l2_ctrl *ctrl_tx_rgb_range; +struct v4l2_ctrl *ctrl_tx_edid_present; +struct v4l2_ctrl *ctrl_tx_hotplug; +struct v4l2_ctrl *ctrl_tx_rxsense;struct v4l2_ctrl *radio_tx_rds_pi;struct v4l2_ctrl *radio_tx_rds_pty;
drivers/media/platform/vivid/vivid-ctrls.c +24 -1
@@ -912,6 +912,8 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) { struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; +u32 display_present =0 ; +unsigned i, j;switch (ctrl->id) {case VIVID_CID_HAS_CROP_OUT :
@@ -950,6 +952,15 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)break ; dev->display_present[dev->output] = ctrl->val; + +for (i =0 , j =0 ; i < dev->num_outputs; i++) +if (dev->output_type[i] ==HDMI ) + display_present |= + dev->display_present[i] << j++; + +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, display_present); +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_rxsense, display_present); +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, display_present);break ; }return 0 ;
@@ -1592,7 +1603,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,V4L2_CID_DV_RX_RGB_RANGE ,V4L2_DV_RGB_RANGE_FULL , 0, V4L2_DV_RGB_RANGE_AUTO); } -if (has_hdmi && dev->has_vid_out) { +if (dev->num_hdmi_outputs) {/* * We aren't doing anything with this at the moment, but * HDMI outputs typically have this controls.
@@ -1605,6 +1616,18 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, 0, V4L2_DV_TX_MODE_HDMI); dev->ctrl_display_present =v4l2_ctrl_new_custom (hdl_vid_out, &vivid_ctrl_display_present,NULL ); + dev->ctrl_tx_hotplug =v4l2_ctrl_new_std (hdl_vid_out, +NULL ,V4L2_CID_DV_TX_HOTPLUG ,0 , + (2 << (dev->num_hdmi_outputs -1 )) -1 ,0 , + (2 << (dev->num_hdmi_outputs -1 )) -1 ); + dev->ctrl_tx_rxsense =v4l2_ctrl_new_std (hdl_vid_out, +NULL ,V4L2_CID_DV_TX_RXSENSE ,0 , + (2 << (dev->num_hdmi_outputs -1 )) -1 ,0 , + (2 << (dev->num_hdmi_outputs -1 )) -1 ); + dev->ctrl_tx_edid_present =v4l2_ctrl_new_std (hdl_vid_out, +NULL ,V4L2_CID_DV_TX_EDID_PRESENT ,0 , + (2 << (dev->num_hdmi_outputs -1 )) -1 ,0 , + (2 << (dev->num_hdmi_outputs -1 )) -1 ); }if ((dev->has_vid_cap && dev->has_vid_out) || (dev->has_vbi_cap && dev->has_vbi_out))
Signature · 1 line
2.17.1
PATCH 6/8 media: vivid: add HDMI (dis)connect RX emulation
In reply to [email protected]From: Johan Korsnes <[email protected]>
Adds the following bitmask control:
-V4L2_CID_DV_RX_POWER_PRESENT
The RX_POWER_PRESENT bitmask is set based on the digital video timings signal mode. This also removes 1/1 warnings for v4l2-compliance test on vivid instance with HDMI input.
--- drivers/media/platform/vivid/vivid-core.h | 4 ++++ drivers/media/platform/vivid/vivid-ctrls.c | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-)
drivers/media/platform/vivid/vivid-core.h +4 -0
@@ -252,6 +252,8 @@ struct vivid_dev {struct v4l2_ctrl *ctrl_tx_hotplug;struct v4l2_ctrl *ctrl_tx_rxsense; +struct v4l2_ctrl *ctrl_rx_power_present; +struct v4l2_ctrl *radio_tx_rds_pi;struct v4l2_ctrl *radio_tx_rds_pty;struct v4l2_ctrl *radio_tx_rds_mono_stereo;
@@ -335,6 +337,8 @@ struct vivid_dev {unsigned tv_field_cap;unsigned tv_audio_input; +u32 power_present; +/* Capture Overlay */ struct v4l2_framebuffer fb_cap;struct v4l2_fh *overlay_cap_owner;
drivers/media/platform/vivid/vivid-ctrls.c +17 -2
@@ -358,7 +358,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) V4L2_COLORSPACE_470_SYSTEM_BG, }; struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap); -unsigned i; +unsigned i, j;switch (ctrl->id) {case VIVID_CID_TEST_PATTERN :
@@ -472,6 +472,16 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) dev->ctrl_dv_timings_signal_mode->val; dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val; + dev->power_present =0 ; +for (i =0 , j =0 ; i <ARRAY_SIZE (dev->dv_timings_signal_mode); i++) +if (dev->input_type[i] ==HDMI ) { +if (dev->dv_timings_signal_mode[i] !=NO_SIGNAL ) + dev->power_present |= (1 << j); + j++; + } +__v4l2_ctrl_s_ctrl (dev->ctrl_rx_power_present, + dev->power_present); +v4l2_ctrl_activate (dev->ctrl_dv_timings, dev->dv_timings_signal_mode[dev->input] ==SELECTED_DV_TIMINGS );
@@ -1582,7 +1592,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,v4l2_ctrl_new_custom (hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced,NULL ); } -if (has_hdmi && dev->has_vid_cap) { +if (dev->num_hdmi_inputs) { dev->ctrl_dv_timings_signal_mode =v4l2_ctrl_new_custom (hdl_vid_cap, &vivid_ctrl_dv_timings_signal_mode,NULL );
@@ -1602,6 +1612,11 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, &vivid_vid_cap_ctrl_ops,V4L2_CID_DV_RX_RGB_RANGE ,V4L2_DV_RGB_RANGE_FULL , 0, V4L2_DV_RGB_RANGE_AUTO); + dev->ctrl_rx_power_present =v4l2_ctrl_new_std (hdl_vid_cap, +NULL ,V4L2_CID_DV_RX_POWER_PRESENT ,0 , + (2 << (dev->num_hdmi_inputs -1 )) -1 ,0 , + (2 << (dev->num_hdmi_inputs -1 )) -1 ); + }if (dev->num_hdmi_outputs) {/*
Signature · 1 line
2.17.1
PATCH 7/8 media: vivid: add CEC support to display present ctrl
In reply to [email protected]From: Johan Korsnes <[email protected]>
Set/invalidate physical addresses based on the configuration of the display present control. This is relevant not only when the display present control is modified, but also when the Vivid instance EDID is set/cleared.
--- drivers/media/platform/vivid/vivid-core.c | 16 ++++++------ drivers/media/platform/vivid/vivid-ctrls.c | 25 ++++++++++++++++--- drivers/media/platform/vivid/vivid-vid-cap.c | 6 ++++- .../media/platform/vivid/vivid-vid-common.c | 2 ++ 4 files changed, 36 insertions(+), 13 deletions(-)
drivers/media/platform/vivid/vivid-core.c +8 -8
@@ -1060,14 +1060,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)vivid_update_format_cap (dev, false);vivid_update_format_out (dev); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_cap); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_out); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_cap); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_out); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_rx); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_tx); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_sdr_cap); -/* initialize overlay */ dev->fb_cap.fmt.width = dev->src_rect.width; dev->fb_cap.fmt.height = dev->src_rect.height;
@@ -1488,6 +1480,14 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) }#endif +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_cap); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_out); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_cap); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_out); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_rx); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_tx); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_sdr_cap); +/* Now that everything is fine, let's add it to device list */ vivid_devs[inst] = dev;
drivers/media/platform/vivid/vivid-ctrls.c +21 -4
@@ -18,6 +18,7 @@#include "vivid-radio-common.h" #include "vivid-osd.h" #include "vivid-ctrls.h" +#include "vivid-cec.h" #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)#define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0)
@@ -923,7 +924,7 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;u32 display_present =0 ; -unsigned i, j; +unsigned i, j, bus_idx;switch (ctrl->id) {case VIVID_CID_HAS_CROP_OUT :
@@ -962,15 +963,31 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)break ; dev->display_present[dev->output] = ctrl->val; -for (i =0 , j =0 ; i < dev->num_outputs; i++)if (dev->output_type[i] ==HDMI ) display_present |= dev->display_present[i] << j++; -__v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, display_present);__v4l2_ctrl_s_ctrl (dev->ctrl_tx_rxsense, display_present); -__v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, display_present); + +if (dev->edid_blocks) { +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, + display_present); +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, + display_present); + } + +if (dev->cec_tx_adap ==NULL ) +break ; + + bus_idx = dev->cec_output2bus_map[dev->output]; +if (ctrl->val && dev->edid_blocks) +cec_s_phys_addr (dev->cec_tx_adap[bus_idx], + dev->cec_tx_adap[bus_idx]->phys_addr, + false); +else +cec_phys_addr_invalidate (dev->cec_tx_adap[bus_idx]); +break ; }return 0 ;
drivers/media/platform/vivid/vivid-vid-cap.c +5 -1
@@ -1760,6 +1760,7 @@ int vidioc_s_edid(struct file *file, void *_fh,return -EINVAL ;if (edid->blocks ==0 ) { dev->edid_blocks =0 ; +v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, false); phys_addr =CEC_PHYS_ADDR_INVALID ; goto set_phys_addr; }
@@ -1777,6 +1778,7 @@ int vidioc_s_edid(struct file *file, void *_fh, dev->edid_blocks = edid->blocks;memcpy (dev->edid, edid->edid, edid->blocks *128 ); +v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, true); set_phys_addr:/* TODO: a proper hotplug detect cycle should be emulated here */
@@ -1784,7 +1786,9 @@ int vidioc_s_edid(struct file *file, void *_fh,for (i =0 ; i <MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)cec_s_phys_addr (dev->cec_tx_adap[i], -v4l2_phys_addr_for_input (phys_addr, i +1 ), + dev->display_present[i] ? +v4l2_phys_addr_for_input (phys_addr, i +1 ) : +CEC_PHYS_ADDR_INVALID , false);return 0 ; }
drivers/media/platform/vivid/vivid-vid-common.c +2 -0
@@ -907,6 +907,8 @@ int vidioc_g_edid(struct file *file, void *_fh,return -EINVAL ;if (dev->output_type[edid->pad] !=HDMI )return -EINVAL ; +if (!dev->display_present[dev->output]) +return -ENODATA ; bus_idx = dev->cec_output2bus_map[edid->pad]; adap = dev->cec_tx_adap[bus_idx]; }
Signature · 1 line
2.17.1
Re: [PATCH 7/8] media: vivid: add CEC support to display present ctrl
Hi Johan,
Thanks for this patch series!
The previous patches all look good, but this one needs a bit more work:
Quoted 39 lines · On 5/28/19 7:19 PM, [email protected] wrote:
From: Johan Korsnes <[email protected]>
Set/invalidate physical addresses based on the configuration of the display present control. This is relevant not only when the display present control is modified, but also when the Vivid instance EDID is set/cleared.
Signed-off-by Johan Korsnes <[email protected]>--- drivers/media/platform/vivid/vivid-core.c | 16 ++++++------ drivers/media/platform/vivid/vivid-ctrls.c | 25 ++++++++++++++++--- drivers/media/platform/vivid/vivid-vid-cap.c | 6 ++++- .../media/platform/vivid/vivid-vid-common.c | 2 ++ 4 files changed, 36 insertions(+), 13 deletions(-)drivers/media/platform/vivid/vivid-core.c +1
-8@@ -1060,14 +1060,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)vivid_update_format_cap (dev, false);vivid_update_format_out (dev); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_cap); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_out); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_cap); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_out); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_rx); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_tx); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_sdr_cap); -/* initialize overlay */ dev->fb_cap.fmt.width = dev->src_rect.width; dev->fb_cap.fmt.height = dev->src_rect.height;@@ -1488,6 +1480,14 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) }#endif +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_cap);
drivers/media/platform/vivid/vivid-core.c static int vivid_create_instance(struct platform_device *pdev, int inst) · line 1493
Quoted 10 lines
drivers/media/platform/vivid/vivid-core.c +7
-0+v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_out); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_cap); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_out); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_rx); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_tx); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_sdr_cap); +/* Now that everything is fine, let's add it to device list */ vivid_devs[inst] = dev;
This change should be in a patch of its own.
It also needs more work. The reason for this change is that v4l2_ctrl_handler_setup() expects that the cec adapters are up and running, so moving these calls until after the creation of the adapters fixes that.
However, that now means that controls change after the creation of the video devices, which isn't right.
If you look at the probe() function you'll see that things are done in two stages:
first all the vb2 queues are created, and only if that succeeded are the video devices created.
The same should be done for the CEC adapters: they should be allocated (vivid_cec_alloc_adap) in the first stage, then call v4l2_ctrl_handler_setup(), and finally create the actual device nodes (cec_register_adapter).
That way the controls are configured correctly before any device nodes are created.
Quoted 61 lines
drivers/media/platform/vivid/vivid-ctrls.c +21
-4@@ -18,6 +18,7 @@#include "vivid-radio-common.h" #include "vivid-osd.h" #include "vivid-ctrls.h" +#include "vivid-cec.h" #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)#define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0)@@ -923,7 +924,7 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;u32 display_present =0 ; -unsigned i, j; +unsigned i, j, bus_idx;switch (ctrl->id) {case VIVID_CID_HAS_CROP_OUT :@@ -962,15 +963,31 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)break ; dev->display_present[dev->output] = ctrl->val; -for (i =0 , j =0 ; i < dev->num_outputs; i++)if (dev->output_type[i] ==HDMI ) display_present |= dev->display_present[i] << j++; -__v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, display_present);__v4l2_ctrl_s_ctrl (dev->ctrl_tx_rxsense, display_present); -__v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, display_present); + +if (dev->edid_blocks) { +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, + display_present); +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, + display_present); + } + +if (dev->cec_tx_adap ==NULL ) +break ; + + bus_idx = dev->cec_output2bus_map[dev->output]; +if (ctrl->val && dev->edid_blocks) +cec_s_phys_addr (dev->cec_tx_adap[bus_idx], + dev->cec_tx_adap[bus_idx]->phys_addr, + false); +else +cec_phys_addr_invalidate (dev->cec_tx_adap[bus_idx]); +break ; }return 0 ;drivers/media/platform/vivid/vivid-vid-cap.c +0
-0
drivers/media/platform/vivid/vivid-vid-cap.c int vidioc_s_edid(struct file *file, void *_fh, · line 1763
Quoted 4 lines
drivers/media/platform/vivid/vivid-vid-cap.c +1
-0@@ -1760,6 +1760,7 @@ int vidioc_s_edid(struct file *file, void *_fh,return -EINVAL ;if (edid->blocks ==0 ) { dev->edid_blocks =0 ; +v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, false);
false should be 0 (it's a bitmask control). The tx_hotplug control should be set to 0 as well.
drivers/media/platform/vivid/vivid-vid-cap.c int vidioc_s_edid(struct file *file, void *_fh, · line 1781
Quoted 8 lines
drivers/media/platform/vivid/vivid-vid-cap.c +1
-0phys_addr =CEC_PHYS_ADDR_INVALID ; goto set_phys_addr; }@@ -1777,6 +1778,7 @@ int vidioc_s_edid(struct file *file, void *_fh, dev->edid_blocks = edid->blocks;memcpy (dev->edid, edid->edid, edid->blocks *128 ); +v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, true);
true should be a display_present mask. And the tx_hotplug control should be set as well with the same mask.
It's probably best to just recalculate the display_present mask, just as you did in vivid_vid_out_s_ctrl().
Quoted 19 lines
drivers/media/platform/vivid/vivid-vid-cap.c +3
-1set_phys_addr:/* TODO: a proper hotplug detect cycle should be emulated here */ @@ -1784,7 +1786,9 @@ int vidioc_s_edid(struct file *file, void *_fh,for (i =0 ; i <MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)cec_s_phys_addr (dev->cec_tx_adap[i], -v4l2_phys_addr_for_input (phys_addr, i +1 ), + dev->display_present[i] ? +v4l2_phys_addr_for_input (phys_addr, i +1 ) : +CEC_PHYS_ADDR_INVALID , false);return 0 ; }drivers/media/platform/vivid/vivid-vid-common.c +0
-0
drivers/media/platform/vivid/vivid-vid-common.c int vidioc_g_edid(struct file *file, void *_fh, · line 910
Quoted 4 lines
drivers/media/platform/vivid/vivid-vid-common.c +1
-0@@ -907,6 +907,8 @@ int vidioc_g_edid(struct file *file, void *_fh,return -EINVAL ;if (dev->output_type[edid->pad] !=HDMI )return -EINVAL ; +if (!dev->display_present[dev->output])
dev->output should be edid->pad. VIDIOC_G_EDID gets the EDID of the specified output, not of the current output.
drivers/media/platform/vivid/vivid-vid-common.c int vidioc_g_edid(struct file *file, void *_fh, · line 914
Quoted 5 lines
drivers/media/platform/vivid/vivid-vid-common.c +1
-0+return -ENODATA ; bus_idx = dev->cec_output2bus_map[edid->pad]; adap = dev->cec_tx_adap[bus_idx]; }
Regards,
Hans
Re: [PATCH 7/8] media: vivid: add CEC support to display present ctrl
Thank you for the review Hans. My comments are inline. A v2 of this series is under way.
Quoted 70 lines · Hans Verkuil
Hi Johan,
Thanks for this patch series!
The previous patches all look good, but this one needs a bit more work:
Quoted 39 lines · On 5/28/19 7:19 PM, [email protected] wrote:
From: Johan Korsnes <[email protected]>
Set/invalidate physical addresses based on the configuration of the display present control. This is relevant not only when the display present control is modified, but also when the Vivid instance EDID is set/cleared.
Signed-off-by Johan Korsnes <[email protected]>--- drivers/media/platform/vivid/vivid-core.c | 16 ++++++------ drivers/media/platform/vivid/vivid-ctrls.c | 25 ++++++++++++++++--- drivers/media/platform/vivid/vivid-vid-cap.c | 6 ++++- .../media/platform/vivid/vivid-vid-common.c | 2 ++ 4 files changed, 36 insertions(+), 13 deletions(-)drivers/media/platform/vivid/vivid-core.c +1
-8@@ -1060,14 +1060,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)vivid_update_format_cap (dev, false);vivid_update_format_out (dev); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_cap); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_out); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_cap); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_out); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_rx); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_tx); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_sdr_cap); -/* initialize overlay */ dev->fb_cap.fmt.width = dev->src_rect.width; dev->fb_cap.fmt.height = dev->src_rect.height;@@ -1488,6 +1480,14 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) }#endif +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_cap);drivers/media/platform/vivid/vivid-core.c static int vivid_create_instance(struct platform_device *pdev, int inst) · line 1493
Quoted 10 lines
drivers/media/platform/vivid/vivid-core.c +7
-0+v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_out); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_cap); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_out); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_rx); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_tx); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_sdr_cap); +/* Now that everything is fine, let's add it to device list */ vivid_devs[inst] = dev;This change should be in a patch of its own.
It also needs more work. The reason for this change is that
v4l2_ctrl_handler_setup()expects that the cec adapters are up and running, so moving these calls until after the creation of the adapters fixes that.However, that now means that controls change after the creation of the video devices, which isn't right.
If you look at the
probe()function you'll see that things are done in two stages:
first all the vb2 queues are created, and only if that succeeded are the video devices created.
Quoted 5 lines
The same should be done for the CEC adapters: they should be allocated (
vivid_cec_alloc_adap) in the first stage, then callv4l2_ctrl_handler_setup(), and finally create the actual device nodes (cec_register_adapter).That way the controls are configured correctly before any device nodes are created.
I have split up the allocation and registration in v2. Why is this order important? Some race condition with user space?
Quoted 82 lines
Quoted 62 lines
drivers/media/platform/vivid/vivid-ctrls.c +21
-4@@ -18,6 +18,7 @@#include "vivid-radio-common.h" #include "vivid-osd.h" #include "vivid-ctrls.h" +#include "vivid-cec.h" #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)#define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0)@@ -923,7 +924,7 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;u32 display_present =0 ; -unsigned i, j; +unsigned i, j, bus_idx;switch (ctrl->id) {case VIVID_CID_HAS_CROP_OUT :@@ -962,15 +963,31 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)break ; dev->display_present[dev->output] = ctrl->val; -for (i =0 , j =0 ; i < dev->num_outputs; i++)if (dev->output_type[i] ==HDMI ) display_present |= dev->display_present[i] << j++; -__v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, display_present);__v4l2_ctrl_s_ctrl (dev->ctrl_tx_rxsense, display_present); -__v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, display_present); + +if (dev->edid_blocks) { +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, + display_present); +__v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, + display_present); + } + +if (dev->cec_tx_adap ==NULL ) +break ; + + bus_idx = dev->cec_output2bus_map[dev->output]; +if (ctrl->val && dev->edid_blocks) +cec_s_phys_addr (dev->cec_tx_adap[bus_idx], + dev->cec_tx_adap[bus_idx]->phys_addr, + false); +else +cec_phys_addr_invalidate (dev->cec_tx_adap[bus_idx]); +break ; }return 0 ;drivers/media/platform/vivid/vivid-vid-cap.c +0
-0drivers/media/platform/vivid/vivid-vid-cap.c int vidioc_s_edid(struct file *file, void *_fh, · line 1763
Quoted 4 lines
drivers/media/platform/vivid/vivid-vid-cap.c +1
-0@@ -1760,6 +1760,7 @@ int vidioc_s_edid(struct file *file, void *_fh,return -EINVAL ;if (edid->blocks ==0 ) { dev->edid_blocks =0 ; +v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, false);false should be 0 (it's a bitmask control). The
tx_hotplugcontrol should be set to 0 as well.drivers/media/platform/vivid/vivid-vid-cap.c int vidioc_s_edid(struct file *file, void *_fh, · line 1781
Quoted 8 lines
drivers/media/platform/vivid/vivid-vid-cap.c +1
-0phys_addr =CEC_PHYS_ADDR_INVALID ; goto set_phys_addr; }@@ -1777,6 +1778,7 @@ int vidioc_s_edid(struct file *file, void *_fh, dev->edid_blocks = edid->blocks;memcpy (dev->edid, edid->edid, edid->blocks *128 ); +v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, true);true should be a
display_presentmask. And thetx_hotplugcontrol should be set as well with the same mask.
Quoted 2 lines
It's probably best to just recalculate the
display_presentmask, just as you did invivid_vid_out_s_ctrl().
Not sure what I was thinking here. Will fix!
Quoted 19 lines
Quoted 19 lines
drivers/media/platform/vivid/vivid-vid-cap.c +3
-1set_phys_addr:/* TODO: a proper hotplug detect cycle should be emulated here */ @@ -1784,7 +1786,9 @@ int vidioc_s_edid(struct file *file, void *_fh,for (i =0 ; i <MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)cec_s_phys_addr (dev->cec_tx_adap[i], -v4l2_phys_addr_for_input (phys_addr, i +1 ), + dev->display_present[i] ? +v4l2_phys_addr_for_input (phys_addr, i +1 ) : +CEC_PHYS_ADDR_INVALID , false);return 0 ; }drivers/media/platform/vivid/vivid-vid-common.c +0
-0
Quoted 9 lines
drivers/media/platform/vivid/vivid-vid-common.c int vidioc_g_edid(struct file *file, void *_fh, · line 910
Quoted 5 lines
drivers/media/platform/vivid/vivid-vid-common.c +1
-0@@ -907,6 +907,8 @@ int vidioc_g_edid(struct file *file, void *_fh,return -EINVAL ;if (dev->output_type[edid->pad] !=HDMI )return -EINVAL ; +if (!dev->display_present[dev->output])
dev->outputshould beedid->pad.VIDIOC_G_EDIDgets the EDID of the specified output, not of the current output.
Will fix this in v2.
Quoted 10 lines
drivers/media/platform/vivid/vivid-vid-common.c int vidioc_g_edid(struct file *file, void *_fh, · line 914
Quoted 5 lines
drivers/media/platform/vivid/vivid-vid-common.c +1
-0+return -ENODATA ; bus_idx = dev->cec_output2bus_map[edid->pad]; adap = dev->cec_tx_adap[bus_idx]; }Regards,
Hans
Re: [PATCH 7/8] media: vivid: add CEC support to display present ctrl
Quoted 74 lines · Johan Korsnes
Thank you for the review Hans. My comments are inline. A v2 of this series is under way.
Quoted 70 lines · Hans Verkuil
Hi Johan,
Thanks for this patch series!
The previous patches all look good, but this one needs a bit more work:
Quoted 39 lines · On 5/28/19 7:19 PM, [email protected] wrote:
From: Johan Korsnes <[email protected]>
Set/invalidate physical addresses based on the configuration of the display present control. This is relevant not only when the display present control is modified, but also when the Vivid instance EDID is set/cleared.
Signed-off-by Johan Korsnes <[email protected]>--- drivers/media/platform/vivid/vivid-core.c | 16 ++++++------ drivers/media/platform/vivid/vivid-ctrls.c | 25 ++++++++++++++++--- drivers/media/platform/vivid/vivid-vid-cap.c | 6 ++++- .../media/platform/vivid/vivid-vid-common.c | 2 ++ 4 files changed, 36 insertions(+), 13 deletions(-)drivers/media/platform/vivid/vivid-core.c +1
-8@@ -1060,14 +1060,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)vivid_update_format_cap (dev, false);vivid_update_format_out (dev); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_cap); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_out); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_cap); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_out); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_rx); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_tx); -v4l2_ctrl_handler_setup (&dev->ctrl_hdl_sdr_cap); -/* initialize overlay */ dev->fb_cap.fmt.width = dev->src_rect.width; dev->fb_cap.fmt.height = dev->src_rect.height;@@ -1488,6 +1480,14 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) }#endif +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_cap);drivers/media/platform/vivid/vivid-core.c static int vivid_create_instance(struct platform_device *pdev, int inst) · line 1493
Quoted 10 lines
drivers/media/platform/vivid/vivid-core.c +7
-0+v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vid_out); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_cap); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_vbi_out); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_rx); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_radio_tx); +v4l2_ctrl_handler_setup (&dev->ctrl_hdl_sdr_cap); +/* Now that everything is fine, let's add it to device list */ vivid_devs[inst] = dev;This change should be in a patch of its own.
It also needs more work. The reason for this change is that
v4l2_ctrl_handler_setup()expects that the cec adapters are up and running, so moving these calls until after the creation of the adapters fixes that.However, that now means that controls change after the creation of the video devices, which isn't right.
If you look at the
probe()function you'll see that things are done in two stages:
first all the vb2 queues are created, and only if that succeeded are the video devices created.
Quoted 8 lines
Quoted 5 lines
The same should be done for the CEC adapters: they should be allocated (
vivid_cec_alloc_adap) in the first stage, then callv4l2_ctrl_handler_setup(), and finally create the actual device nodes (cec_register_adapter).That way the controls are configured correctly before any device nodes are created.
I have split up the allocation and registration in v2. Why is this order important? Some race condition with user space?
Yes. Once a device node is created under /dev userspace can start to use it. And in fact something like systemd can open it immediately after creation.
So the complete state of the device should be ready before you create the device node. Still changing/adding things *after* device node creation indeed creates a race condition.
Note that a lot of (mostly older) drivers do this wrong, but vivid, being somewhat of a reference driver, should do this right.
Regards,
Hans
PATCH 8/8 media: vivid.rst: describe display present control
In reply to [email protected]From: Johan Korsnes <[email protected]>
--- Documentation/media/v4l-drivers/vivid.rst | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/media/v4l-drivers/vivid.rst +5 -0
@@ -941,6 +941,11 @@ Digital Video Controls affects the reported colorspace since DVI_D outputs will always use sRGB. +- Display Present: + + sets the presence of a "display" on the HDMI output. This affects + the tx_edid_present, tx_hotplug and tx_rxsense controls. + FM Radio Receiver Controls ~~~~~~~~~~~~~~~~~~~~~~~~~~
Signature · 1 line
2.17.1