|
@@ -38,6 +38,32 @@ static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, u32 reg, u32 data)
|
|
|
reg + rpf->entity.index * VI6_RPF_OFFSET, data);
|
|
|
}
|
|
|
|
|
|
+/* -----------------------------------------------------------------------------
|
|
|
+ * Controls
|
|
|
+ */
|
|
|
+
|
|
|
+static int rpf_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+{
|
|
|
+ struct vsp1_rwpf *rpf =
|
|
|
+ container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
|
|
|
+
|
|
|
+ if (!vsp1_entity_is_streaming(&rpf->entity))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ switch (ctrl->id) {
|
|
|
+ case V4L2_CID_ALPHA_COMPONENT:
|
|
|
+ vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET,
|
|
|
+ ctrl->val << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static const struct v4l2_ctrl_ops rpf_ctrl_ops = {
|
|
|
+ .s_ctrl = rpf_s_ctrl,
|
|
|
+};
|
|
|
+
|
|
|
/* -----------------------------------------------------------------------------
|
|
|
* V4L2 Subdevice Core Operations
|
|
|
*/
|
|
@@ -50,6 +76,11 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
|
|
|
const struct v4l2_rect *crop = &rpf->crop;
|
|
|
u32 pstride;
|
|
|
u32 infmt;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = vsp1_entity_set_streaming(&rpf->entity, enable);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
|
|
|
if (!enable)
|
|
|
return 0;
|
|
@@ -101,14 +132,13 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
|
|
|
(rpf->location.left << VI6_RPF_LOC_HCOORD_SHIFT) |
|
|
|
(rpf->location.top << VI6_RPF_LOC_VCOORD_SHIFT));
|
|
|
|
|
|
- /* Use the alpha channel (extended to 8 bits) when available or a
|
|
|
- * hardcoded 255 value otherwise. Disable color keying.
|
|
|
+ /* Use the alpha channel (extended to 8 bits) when available or an
|
|
|
+ * alpha value set through the V4L2_CID_ALPHA_COMPONENT control
|
|
|
+ * otherwise. Disable color keying.
|
|
|
*/
|
|
|
vsp1_rpf_write(rpf, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_AEXT_EXT |
|
|
|
(fmtinfo->alpha ? VI6_RPF_ALPH_SEL_ASEL_PACKED
|
|
|
: VI6_RPF_ALPH_SEL_ASEL_FIXED));
|
|
|
- vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET,
|
|
|
- 255 << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
|
|
|
vsp1_rpf_write(rpf, VI6_RPF_MSK_CTRL, 0);
|
|
|
vsp1_rpf_write(rpf, VI6_RPF_CKEY_CTRL, 0);
|
|
|
|
|
@@ -198,6 +228,20 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
|
|
|
|
|
|
vsp1_entity_init_formats(subdev, NULL);
|
|
|
|
|
|
+ /* Initialize the control handler. */
|
|
|
+ v4l2_ctrl_handler_init(&rpf->ctrls, 1);
|
|
|
+ v4l2_ctrl_new_std(&rpf->ctrls, &rpf_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
|
|
|
+ 0, 255, 1, 255);
|
|
|
+
|
|
|
+ rpf->entity.subdev.ctrl_handler = &rpf->ctrls;
|
|
|
+
|
|
|
+ if (rpf->ctrls.error) {
|
|
|
+ dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n",
|
|
|
+ index);
|
|
|
+ ret = rpf->ctrls.error;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
/* Initialize the video device. */
|
|
|
video = &rpf->video;
|
|
|
|