diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2016-05-13 12:52:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-06-28 11:15:10 -0400 |
commit | 42e89bed23000c0bf985a741422ef943df0ee1e9 (patch) | |
tree | 14c65035c86e8ff1a2080242daa7570b02dccbb8 | |
parent | 0220990f63668852c8a2a8f03e3afb422780ef9d (diff) |
[media] v4l: vsp1: lut: Expose configuration through a control
Replace the custom ioctl with a V4L2 control in order to standardize the
API.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_lut.c | 76 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_lut.h | 6 | ||||
-rw-r--r-- | include/uapi/linux/vsp1.h | 34 |
3 files changed, 54 insertions, 62 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c index 4a4724965de1..db8f01dbab84 100644 --- a/drivers/media/platform/vsp1/vsp1_lut.c +++ b/drivers/media/platform/vsp1/vsp1_lut.c | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/gfp.h> | 15 | #include <linux/gfp.h> |
16 | #include <linux/vsp1.h> | ||
17 | 16 | ||
18 | #include <media/v4l2-subdev.h> | 17 | #include <media/v4l2-subdev.h> |
19 | 18 | ||
@@ -35,43 +34,60 @@ static inline void vsp1_lut_write(struct vsp1_lut *lut, struct vsp1_dl_list *dl, | |||
35 | } | 34 | } |
36 | 35 | ||
37 | /* ----------------------------------------------------------------------------- | 36 | /* ----------------------------------------------------------------------------- |
38 | * V4L2 Subdevice Core Operations | 37 | * Controls |
39 | */ | 38 | */ |
40 | 39 | ||
41 | static int lut_set_table(struct vsp1_lut *lut, struct vsp1_lut_config *config) | 40 | #define V4L2_CID_VSP1_LUT_TABLE (V4L2_CID_USER_BASE | 0x1001) |
41 | |||
42 | static int lut_set_table(struct vsp1_lut *lut, struct v4l2_ctrl *ctrl) | ||
42 | { | 43 | { |
43 | struct vsp1_dl_body *dlb; | 44 | struct vsp1_dl_body *dlb; |
44 | unsigned int i; | 45 | unsigned int i; |
45 | 46 | ||
46 | dlb = vsp1_dl_fragment_alloc(lut->entity.vsp1, ARRAY_SIZE(config->lut)); | 47 | dlb = vsp1_dl_fragment_alloc(lut->entity.vsp1, 256); |
47 | if (!dlb) | 48 | if (!dlb) |
48 | return -ENOMEM; | 49 | return -ENOMEM; |
49 | 50 | ||
50 | for (i = 0; i < ARRAY_SIZE(config->lut); ++i) | 51 | for (i = 0; i < 256; ++i) |
51 | vsp1_dl_fragment_write(dlb, VI6_LUT_TABLE + 4 * i, | 52 | vsp1_dl_fragment_write(dlb, VI6_LUT_TABLE + 4 * i, |
52 | config->lut[i]); | 53 | ctrl->p_new.p_u32[i]); |
53 | 54 | ||
54 | mutex_lock(&lut->lock); | ||
55 | swap(lut->lut, dlb); | 55 | swap(lut->lut, dlb); |
56 | mutex_unlock(&lut->lock); | ||
57 | 56 | ||
58 | vsp1_dl_fragment_free(dlb); | 57 | vsp1_dl_fragment_free(dlb); |
59 | return 0; | 58 | return 0; |
60 | } | 59 | } |
61 | 60 | ||
62 | static long lut_ioctl(struct v4l2_subdev *subdev, unsigned int cmd, void *arg) | 61 | static int lut_s_ctrl(struct v4l2_ctrl *ctrl) |
63 | { | 62 | { |
64 | struct vsp1_lut *lut = to_lut(subdev); | 63 | struct vsp1_lut *lut = |
65 | 64 | container_of(ctrl->handler, struct vsp1_lut, ctrls); | |
66 | switch (cmd) { | ||
67 | case VIDIOC_VSP1_LUT_CONFIG: | ||
68 | return lut_set_table(lut, arg); | ||
69 | 65 | ||
70 | default: | 66 | switch (ctrl->id) { |
71 | return -ENOIOCTLCMD; | 67 | case V4L2_CID_VSP1_LUT_TABLE: |
68 | lut_set_table(lut, ctrl); | ||
69 | break; | ||
72 | } | 70 | } |
71 | |||
72 | return 0; | ||
73 | } | 73 | } |
74 | 74 | ||
75 | static const struct v4l2_ctrl_ops lut_ctrl_ops = { | ||
76 | .s_ctrl = lut_s_ctrl, | ||
77 | }; | ||
78 | |||
79 | static const struct v4l2_ctrl_config lut_table_control = { | ||
80 | .ops = &lut_ctrl_ops, | ||
81 | .id = V4L2_CID_VSP1_LUT_TABLE, | ||
82 | .name = "Look-Up Table", | ||
83 | .type = V4L2_CTRL_TYPE_U32, | ||
84 | .min = 0x00000000, | ||
85 | .max = 0x00ffffff, | ||
86 | .step = 1, | ||
87 | .def = 0, | ||
88 | .dims = { 256}, | ||
89 | }; | ||
90 | |||
75 | /* ----------------------------------------------------------------------------- | 91 | /* ----------------------------------------------------------------------------- |
76 | * V4L2 Subdevice Pad Operations | 92 | * V4L2 Subdevice Pad Operations |
77 | */ | 93 | */ |
@@ -147,10 +163,6 @@ static int lut_set_format(struct v4l2_subdev *subdev, | |||
147 | * V4L2 Subdevice Operations | 163 | * V4L2 Subdevice Operations |
148 | */ | 164 | */ |
149 | 165 | ||
150 | static const struct v4l2_subdev_core_ops lut_core_ops = { | ||
151 | .ioctl = lut_ioctl, | ||
152 | }; | ||
153 | |||
154 | static const struct v4l2_subdev_pad_ops lut_pad_ops = { | 166 | static const struct v4l2_subdev_pad_ops lut_pad_ops = { |
155 | .init_cfg = vsp1_entity_init_cfg, | 167 | .init_cfg = vsp1_entity_init_cfg, |
156 | .enum_mbus_code = lut_enum_mbus_code, | 168 | .enum_mbus_code = lut_enum_mbus_code, |
@@ -160,7 +172,6 @@ static const struct v4l2_subdev_pad_ops lut_pad_ops = { | |||
160 | }; | 172 | }; |
161 | 173 | ||
162 | static const struct v4l2_subdev_ops lut_ops = { | 174 | static const struct v4l2_subdev_ops lut_ops = { |
163 | .core = &lut_core_ops, | ||
164 | .pad = &lut_pad_ops, | 175 | .pad = &lut_pad_ops, |
165 | }; | 176 | }; |
166 | 177 | ||
@@ -176,12 +187,14 @@ static void lut_configure(struct vsp1_entity *entity, | |||
176 | 187 | ||
177 | vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN); | 188 | vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN); |
178 | 189 | ||
179 | mutex_lock(&lut->lock); | 190 | mutex_lock(lut->ctrls.lock); |
191 | |||
180 | if (lut->lut) { | 192 | if (lut->lut) { |
181 | vsp1_dl_list_add_fragment(dl, lut->lut); | 193 | vsp1_dl_list_add_fragment(dl, lut->lut); |
182 | lut->lut = NULL; | 194 | lut->lut = NULL; |
183 | } | 195 | } |
184 | mutex_unlock(&lut->lock); | 196 | |
197 | mutex_unlock(lut->ctrls.lock); | ||
185 | } | 198 | } |
186 | 199 | ||
187 | static const struct vsp1_entity_operations lut_entity_ops = { | 200 | static const struct vsp1_entity_operations lut_entity_ops = { |
@@ -201,8 +214,6 @@ struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1) | |||
201 | if (lut == NULL) | 214 | if (lut == NULL) |
202 | return ERR_PTR(-ENOMEM); | 215 | return ERR_PTR(-ENOMEM); |
203 | 216 | ||
204 | mutex_init(&lut->lock); | ||
205 | |||
206 | lut->entity.ops = &lut_entity_ops; | 217 | lut->entity.ops = &lut_entity_ops; |
207 | lut->entity.type = VSP1_ENTITY_LUT; | 218 | lut->entity.type = VSP1_ENTITY_LUT; |
208 | 219 | ||
@@ -211,5 +222,20 @@ struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1) | |||
211 | if (ret < 0) | 222 | if (ret < 0) |
212 | return ERR_PTR(ret); | 223 | return ERR_PTR(ret); |
213 | 224 | ||
225 | /* Initialize the control handler. */ | ||
226 | v4l2_ctrl_handler_init(&lut->ctrls, 1); | ||
227 | v4l2_ctrl_new_custom(&lut->ctrls, &lut_table_control, NULL); | ||
228 | |||
229 | lut->entity.subdev.ctrl_handler = &lut->ctrls; | ||
230 | |||
231 | if (lut->ctrls.error) { | ||
232 | dev_err(vsp1->dev, "lut: failed to initialize controls\n"); | ||
233 | ret = lut->ctrls.error; | ||
234 | vsp1_entity_destroy(&lut->entity); | ||
235 | return ERR_PTR(ret); | ||
236 | } | ||
237 | |||
238 | v4l2_ctrl_handler_setup(&lut->ctrls); | ||
239 | |||
214 | return lut; | 240 | return lut; |
215 | } | 241 | } |
diff --git a/drivers/media/platform/vsp1/vsp1_lut.h b/drivers/media/platform/vsp1/vsp1_lut.h index cef874f22b6a..021898fc0ce5 100644 --- a/drivers/media/platform/vsp1/vsp1_lut.h +++ b/drivers/media/platform/vsp1/vsp1_lut.h | |||
@@ -13,9 +13,8 @@ | |||
13 | #ifndef __VSP1_LUT_H__ | 13 | #ifndef __VSP1_LUT_H__ |
14 | #define __VSP1_LUT_H__ | 14 | #define __VSP1_LUT_H__ |
15 | 15 | ||
16 | #include <linux/mutex.h> | ||
17 | |||
18 | #include <media/media-entity.h> | 16 | #include <media/media-entity.h> |
17 | #include <media/v4l2-ctrls.h> | ||
19 | #include <media/v4l2-subdev.h> | 18 | #include <media/v4l2-subdev.h> |
20 | 19 | ||
21 | #include "vsp1_entity.h" | 20 | #include "vsp1_entity.h" |
@@ -28,7 +27,8 @@ struct vsp1_device; | |||
28 | struct vsp1_lut { | 27 | struct vsp1_lut { |
29 | struct vsp1_entity entity; | 28 | struct vsp1_entity entity; |
30 | 29 | ||
31 | struct mutex lock; | 30 | struct v4l2_ctrl_handler ctrls; |
31 | |||
32 | struct vsp1_dl_body *lut; | 32 | struct vsp1_dl_body *lut; |
33 | }; | 33 | }; |
34 | 34 | ||
diff --git a/include/uapi/linux/vsp1.h b/include/uapi/linux/vsp1.h deleted file mode 100644 index 9a823696d816..000000000000 --- a/include/uapi/linux/vsp1.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /* | ||
2 | * vsp1.h | ||
3 | * | ||
4 | * Renesas R-Car VSP1 - User-space API | ||
5 | * | ||
6 | * Copyright (C) 2013 Renesas Corporation | ||
7 | * | ||
8 | * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __VSP1_USER_H__ | ||
16 | #define __VSP1_USER_H__ | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | #include <linux/videodev2.h> | ||
20 | |||
21 | /* | ||
22 | * Private IOCTLs | ||
23 | * | ||
24 | * VIDIOC_VSP1_LUT_CONFIG - Configure the lookup table | ||
25 | */ | ||
26 | |||
27 | #define VIDIOC_VSP1_LUT_CONFIG \ | ||
28 | _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct vsp1_lut_config) | ||
29 | |||
30 | struct vsp1_lut_config { | ||
31 | __u32 lut[256]; | ||
32 | }; | ||
33 | |||
34 | #endif /* __VSP1_USER_H__ */ | ||