aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vimc/vimc-sensor.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2017-11-06 05:20:01 -0500
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2017-12-08 10:44:55 -0500
commit52cf1d964e4ca89ed80f97a8451245c9bb13a63d (patch)
treed3db867af41176b73df079df2078f0418c1ba8f7 /drivers/media/platform/vimc/vimc-sensor.c
parente2a067048d6263613cee8c5c36aa6f2d755ef425 (diff)
media: vimc: add test_pattern and h/vflip controls to the sensor
Add support for the test_pattern control and the h/vflip controls. This makes it possible to switch to more interesting test patterns and to test control handling in v4l-subdevs. There are more tpg-related controls that can be added, but this is a good start. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> [hans.verkuil@cisco.com: fix small whitespace checkpatch warning] Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/platform/vimc/vimc-sensor.c')
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index 02e68c8fc02b..ca1c52232d1e 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -22,6 +22,7 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/v4l2-mediabus.h> 23#include <linux/v4l2-mediabus.h>
24#include <linux/vmalloc.h> 24#include <linux/vmalloc.h>
25#include <media/v4l2-ctrls.h>
25#include <media/v4l2-subdev.h> 26#include <media/v4l2-subdev.h>
26#include <media/v4l2-tpg.h> 27#include <media/v4l2-tpg.h>
27 28
@@ -38,6 +39,7 @@ struct vimc_sen_device {
38 u8 *frame; 39 u8 *frame;
39 /* The active format */ 40 /* The active format */
40 struct v4l2_mbus_framefmt mbus_format; 41 struct v4l2_mbus_framefmt mbus_format;
42 struct v4l2_ctrl_handler hdl;
41}; 43};
42 44
43static const struct v4l2_mbus_framefmt fmt_default = { 45static const struct v4l2_mbus_framefmt fmt_default = {
@@ -291,6 +293,31 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {
291 .video = &vimc_sen_video_ops, 293 .video = &vimc_sen_video_ops,
292}; 294};
293 295
296static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl)
297{
298 struct vimc_sen_device *vsen =
299 container_of(ctrl->handler, struct vimc_sen_device, hdl);
300
301 switch (ctrl->id) {
302 case VIMC_CID_TEST_PATTERN:
303 tpg_s_pattern(&vsen->tpg, ctrl->val);
304 break;
305 case V4L2_CID_HFLIP:
306 tpg_s_hflip(&vsen->tpg, ctrl->val);
307 break;
308 case V4L2_CID_VFLIP:
309 tpg_s_vflip(&vsen->tpg, ctrl->val);
310 break;
311 default:
312 return -EINVAL;
313 }
314 return 0;
315}
316
317static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = {
318 .s_ctrl = vimc_sen_s_ctrl,
319};
320
294static void vimc_sen_comp_unbind(struct device *comp, struct device *master, 321static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
295 void *master_data) 322 void *master_data)
296{ 323{
@@ -299,10 +326,28 @@ static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
299 container_of(ved, struct vimc_sen_device, ved); 326 container_of(ved, struct vimc_sen_device, ved);
300 327
301 vimc_ent_sd_unregister(ved, &vsen->sd); 328 vimc_ent_sd_unregister(ved, &vsen->sd);
329 v4l2_ctrl_handler_free(&vsen->hdl);
302 tpg_free(&vsen->tpg); 330 tpg_free(&vsen->tpg);
303 kfree(vsen); 331 kfree(vsen);
304} 332}
305 333
334/* Image Processing Controls */
335static const struct v4l2_ctrl_config vimc_sen_ctrl_class = {
336 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
337 .id = VIMC_CID_VIMC_CLASS,
338 .name = "VIMC Controls",
339 .type = V4L2_CTRL_TYPE_CTRL_CLASS,
340};
341
342static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = {
343 .ops = &vimc_sen_ctrl_ops,
344 .id = VIMC_CID_TEST_PATTERN,
345 .name = "Test Pattern",
346 .type = V4L2_CTRL_TYPE_MENU,
347 .max = TPG_PAT_NOISE,
348 .qmenu = tpg_pattern_strings,
349};
350
306static int vimc_sen_comp_bind(struct device *comp, struct device *master, 351static int vimc_sen_comp_bind(struct device *comp, struct device *master,
307 void *master_data) 352 void *master_data)
308{ 353{
@@ -316,6 +361,20 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
316 if (!vsen) 361 if (!vsen)
317 return -ENOMEM; 362 return -ENOMEM;
318 363
364 v4l2_ctrl_handler_init(&vsen->hdl, 4);
365
366 v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_class, NULL);
367 v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_test_pattern, NULL);
368 v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
369 V4L2_CID_VFLIP, 0, 1, 1, 0);
370 v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
371 V4L2_CID_HFLIP, 0, 1, 1, 0);
372 vsen->sd.ctrl_handler = &vsen->hdl;
373 if (vsen->hdl.error) {
374 ret = vsen->hdl.error;
375 goto err_free_vsen;
376 }
377
319 /* Initialize ved and sd */ 378 /* Initialize ved and sd */
320 ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev, 379 ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
321 pdata->entity_name, 380 pdata->entity_name,
@@ -323,7 +382,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
323 (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, 382 (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
324 &vimc_sen_ops); 383 &vimc_sen_ops);
325 if (ret) 384 if (ret)
326 goto err_free_vsen; 385 goto err_free_hdl;
327 386
328 dev_set_drvdata(comp, &vsen->ved); 387 dev_set_drvdata(comp, &vsen->ved);
329 vsen->dev = comp; 388 vsen->dev = comp;
@@ -342,6 +401,8 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
342 401
343err_unregister_ent_sd: 402err_unregister_ent_sd:
344 vimc_ent_sd_unregister(&vsen->ved, &vsen->sd); 403 vimc_ent_sd_unregister(&vsen->ved, &vsen->sd);
404err_free_hdl:
405 v4l2_ctrl_handler_free(&vsen->hdl);
345err_free_vsen: 406err_free_vsen:
346 kfree(vsen); 407 kfree(vsen);
347 408