| @@ -13,7 +13,6 @@ · 12 unmodified lines |
| 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, · 15 unmodified lines |
| 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, · 69 unmodified lines |
| 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 = { · 3 unmodified lines |
| 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, · 9 unmodified lines |
| 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) · 13 unmodified lines |
| 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) · 2 unmodified lines |
| 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 | } |