diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2015-11-01 09:19:42 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2016-04-13 16:42:43 -0400 |
commit | bd2fdd5aa919e3cb750147c9270034f11d106d94 (patch) | |
tree | d296852eabf9da568727d6e5e663764b4a6dc621 /drivers/media/platform/vsp1/vsp1_wpf.c | |
parent | 5fb2107346cfc6d8fe62117a2cbf91fc1f92cc84 (diff) |
[media] v4l: vsp1: rwpf: Don't program alpha value in control set handler
The datasheet clearly states that all but a few registers can't be
modified when the device is running. Programming the alpha value in
the control set handler is thus prohibited. Program it when starting the
module instead.
This requires storing the alpha value internally as the module can be
started from the frame completion interrupt handler, and accessing
control values requires taking a mutex.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/platform/vsp1/vsp1_wpf.c')
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_wpf.c | 55 |
1 files changed, 3 insertions, 52 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index 6afc9c8d9adc..2135cca2490e 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c | |||
@@ -27,12 +27,6 @@ | |||
27 | * Device Access | 27 | * Device Access |
28 | */ | 28 | */ |
29 | 29 | ||
30 | static inline u32 vsp1_wpf_read(struct vsp1_rwpf *wpf, u32 reg) | ||
31 | { | ||
32 | return vsp1_read(wpf->entity.vsp1, | ||
33 | reg + wpf->entity.index * VI6_WPF_OFFSET); | ||
34 | } | ||
35 | |||
36 | static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data) | 30 | static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data) |
37 | { | 31 | { |
38 | vsp1_mod_write(&wpf->entity, | 32 | vsp1_mod_write(&wpf->entity, |
@@ -40,35 +34,6 @@ static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data) | |||
40 | } | 34 | } |
41 | 35 | ||
42 | /* ----------------------------------------------------------------------------- | 36 | /* ----------------------------------------------------------------------------- |
43 | * Controls | ||
44 | */ | ||
45 | |||
46 | static int wpf_s_ctrl(struct v4l2_ctrl *ctrl) | ||
47 | { | ||
48 | struct vsp1_rwpf *wpf = | ||
49 | container_of(ctrl->handler, struct vsp1_rwpf, ctrls); | ||
50 | u32 value; | ||
51 | |||
52 | if (!vsp1_entity_is_streaming(&wpf->entity)) | ||
53 | return 0; | ||
54 | |||
55 | switch (ctrl->id) { | ||
56 | case V4L2_CID_ALPHA_COMPONENT: | ||
57 | value = vsp1_wpf_read(wpf, VI6_WPF_OUTFMT); | ||
58 | value &= ~VI6_WPF_OUTFMT_PDV_MASK; | ||
59 | value |= ctrl->val << VI6_WPF_OUTFMT_PDV_SHIFT; | ||
60 | vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, value); | ||
61 | break; | ||
62 | } | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static const struct v4l2_ctrl_ops wpf_ctrl_ops = { | ||
68 | .s_ctrl = wpf_s_ctrl, | ||
69 | }; | ||
70 | |||
71 | /* ----------------------------------------------------------------------------- | ||
72 | * V4L2 Subdevice Core Operations | 37 | * V4L2 Subdevice Core Operations |
73 | */ | 38 | */ |
74 | 39 | ||
@@ -153,15 +118,8 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable) | |||
153 | wpf->entity.formats[RWPF_PAD_SOURCE].code) | 118 | wpf->entity.formats[RWPF_PAD_SOURCE].code) |
154 | outfmt |= VI6_WPF_OUTFMT_CSC; | 119 | outfmt |= VI6_WPF_OUTFMT_CSC; |
155 | 120 | ||
156 | /* Take the control handler lock to ensure that the PDV value won't be | 121 | outfmt |= wpf->alpha << VI6_WPF_OUTFMT_PDV_SHIFT; |
157 | * changed behind our back by a set control operation. | ||
158 | */ | ||
159 | if (vsp1->info->uapi) | ||
160 | mutex_lock(wpf->ctrls.lock); | ||
161 | outfmt |= wpf->alpha->cur.val << VI6_WPF_OUTFMT_PDV_SHIFT; | ||
162 | vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt); | 122 | vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt); |
163 | if (vsp1->info->uapi) | ||
164 | mutex_unlock(wpf->ctrls.lock); | ||
165 | 123 | ||
166 | vsp1_mod_write(&wpf->entity, VI6_DPR_WPF_FPORCH(wpf->entity.index), | 124 | vsp1_mod_write(&wpf->entity, VI6_DPR_WPF_FPORCH(wpf->entity.index), |
167 | VI6_DPR_WPF_FPORCH_FP_WPFN); | 125 | VI6_DPR_WPF_FPORCH_FP_WPFN); |
@@ -272,17 +230,10 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) | |||
272 | vsp1_entity_init_formats(subdev, NULL); | 230 | vsp1_entity_init_formats(subdev, NULL); |
273 | 231 | ||
274 | /* Initialize the control handler. */ | 232 | /* Initialize the control handler. */ |
275 | v4l2_ctrl_handler_init(&wpf->ctrls, 1); | 233 | ret = vsp1_rwpf_init_ctrls(wpf); |
276 | wpf->alpha = v4l2_ctrl_new_std(&wpf->ctrls, &wpf_ctrl_ops, | 234 | if (ret < 0) { |
277 | V4L2_CID_ALPHA_COMPONENT, | ||
278 | 0, 255, 1, 255); | ||
279 | |||
280 | wpf->entity.subdev.ctrl_handler = &wpf->ctrls; | ||
281 | |||
282 | if (wpf->ctrls.error) { | ||
283 | dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n", | 235 | dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n", |
284 | index); | 236 | index); |
285 | ret = wpf->ctrls.error; | ||
286 | goto error; | 237 | goto error; |
287 | } | 238 | } |
288 | 239 | ||