media: vivid: add display present control
authorJohan Korsnes <johan.korsnes@gmail.com>
Tue, 18 Jun 2019 07:37:20 +0000 (03:37 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Fri, 21 Jun 2019 21:31:06 +0000 (17:31 -0400)
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.

Signed-off-by: Johan Korsnes <johan.korsnes@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/platform/vivid/vivid-core.c
drivers/media/platform/vivid/vivid-core.h
drivers/media/platform/vivid/vivid-ctrls.c
drivers/media/platform/vivid/vivid-vid-out.c

index 85e6aaf7bf0d8dae75bd5a710c9ec210ff8ebde4..b1d5332b363f0b3515089fcf3c56ea604f555cd9 100644 (file)
@@ -730,6 +730,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) {
@@ -1038,6 +1039,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);
index f9d26a42b370c9b56d38b5b1f45f2cf134255600..3b89e930eb0d587a8bcf5920986ac9ac23012407 100644 (file)
@@ -225,6 +225,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;
@@ -349,6 +350,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;
index e27103f694c5af285f3d12b86f264e12f0ec88b5..6e6e8e0fb4bd415dca61ec86ef82c972a036add0 100644 (file)
@@ -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 */
 
@@ -1588,6 +1604,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))
index 9350ca65dd9190acadceb6435597a1085b14531a..148b663a60754940c0c39f9064c54ff4c197b511 100644 (file)
@@ -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;
 }