diff options
author | Sakari Ailus <sakari.ailus@linux.intel.com> | 2014-05-21 15:58:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-08-21 16:25:12 -0400 |
commit | 0e2a6b7f2b9303410c93fd4724f9d36ebc7be1c3 (patch) | |
tree | 2478a1c79892546a62a6c94566cce319295e5f08 | |
parent | a913d8742e275dd2d80726afac02311a0f49d161 (diff) |
[media] smiapp: Implement the test pattern control
Add support for the V4L2_CID_TEST_PATTERN control. When the solid colour
mode is selected, additional controls become available for setting the
solid four solid colour components.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | drivers/media/i2c/smiapp/smiapp-core.c | 79 | ||||
-rw-r--r-- | drivers/media/i2c/smiapp/smiapp.h | 4 |
2 files changed, 78 insertions, 5 deletions
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 1eaf975d3612..437ec29bdf64 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c | |||
@@ -31,8 +31,9 @@ | |||
31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
32 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/slab.h> | ||
35 | #include <linux/regulator/consumer.h> | 34 | #include <linux/regulator/consumer.h> |
35 | #include <linux/slab.h> | ||
36 | #include <linux/smiapp.h> | ||
36 | #include <linux/v4l2-mediabus.h> | 37 | #include <linux/v4l2-mediabus.h> |
37 | #include <media/v4l2-device.h> | 38 | #include <media/v4l2-device.h> |
38 | 39 | ||
@@ -404,6 +405,14 @@ static void smiapp_update_mbus_formats(struct smiapp_sensor *sensor) | |||
404 | pixel_order_str[pixel_order]); | 405 | pixel_order_str[pixel_order]); |
405 | } | 406 | } |
406 | 407 | ||
408 | static const char * const smiapp_test_patterns[] = { | ||
409 | "Disabled", | ||
410 | "Solid Colour", | ||
411 | "Eight Vertical Colour Bars", | ||
412 | "Colour Bars With Fade to Grey", | ||
413 | "Pseudorandom Sequence (PN9)", | ||
414 | }; | ||
415 | |||
407 | static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl) | 416 | static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl) |
408 | { | 417 | { |
409 | struct smiapp_sensor *sensor = | 418 | struct smiapp_sensor *sensor = |
@@ -477,6 +486,35 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl) | |||
477 | 486 | ||
478 | return smiapp_pll_update(sensor); | 487 | return smiapp_pll_update(sensor); |
479 | 488 | ||
489 | case V4L2_CID_TEST_PATTERN: { | ||
490 | unsigned int i; | ||
491 | |||
492 | for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) | ||
493 | v4l2_ctrl_activate( | ||
494 | sensor->test_data[i], | ||
495 | ctrl->val == | ||
496 | V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR); | ||
497 | |||
498 | return smiapp_write( | ||
499 | sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val); | ||
500 | } | ||
501 | |||
502 | case V4L2_CID_TEST_PATTERN_RED: | ||
503 | return smiapp_write( | ||
504 | sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val); | ||
505 | |||
506 | case V4L2_CID_TEST_PATTERN_GREENR: | ||
507 | return smiapp_write( | ||
508 | sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val); | ||
509 | |||
510 | case V4L2_CID_TEST_PATTERN_BLUE: | ||
511 | return smiapp_write( | ||
512 | sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val); | ||
513 | |||
514 | case V4L2_CID_TEST_PATTERN_GREENB: | ||
515 | return smiapp_write( | ||
516 | sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val); | ||
517 | |||
480 | default: | 518 | default: |
481 | return -EINVAL; | 519 | return -EINVAL; |
482 | } | 520 | } |
@@ -489,10 +527,10 @@ static const struct v4l2_ctrl_ops smiapp_ctrl_ops = { | |||
489 | static int smiapp_init_controls(struct smiapp_sensor *sensor) | 527 | static int smiapp_init_controls(struct smiapp_sensor *sensor) |
490 | { | 528 | { |
491 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); | 529 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); |
492 | unsigned int max; | 530 | unsigned int max, i; |
493 | int rval; | 531 | int rval; |
494 | 532 | ||
495 | rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 7); | 533 | rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 12); |
496 | if (rval) | 534 | if (rval) |
497 | return rval; | 535 | return rval; |
498 | sensor->pixel_array->ctrl_handler.lock = &sensor->mutex; | 536 | sensor->pixel_array->ctrl_handler.lock = &sensor->mutex; |
@@ -535,6 +573,20 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor) | |||
535 | &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops, | 573 | &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops, |
536 | V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1); | 574 | V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1); |
537 | 575 | ||
576 | v4l2_ctrl_new_std_menu_items(&sensor->pixel_array->ctrl_handler, | ||
577 | &smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN, | ||
578 | ARRAY_SIZE(smiapp_test_patterns) - 1, | ||
579 | 0, 0, smiapp_test_patterns); | ||
580 | |||
581 | for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) { | ||
582 | int max_value = (1 << sensor->csi_format->width) - 1; | ||
583 | sensor->test_data[i] = | ||
584 | v4l2_ctrl_new_std( | ||
585 | &sensor->pixel_array->ctrl_handler, | ||
586 | &smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN_RED + i, | ||
587 | 0, max_value, 1, max_value); | ||
588 | } | ||
589 | |||
538 | if (sensor->pixel_array->ctrl_handler.error) { | 590 | if (sensor->pixel_array->ctrl_handler.error) { |
539 | dev_err(&client->dev, | 591 | dev_err(&client->dev, |
540 | "pixel array controls initialization failed (%d)\n", | 592 | "pixel array controls initialization failed (%d)\n", |
@@ -1671,17 +1723,34 @@ static int smiapp_set_format(struct v4l2_subdev *subdev, | |||
1671 | if (fmt->pad == ssd->source_pad) { | 1723 | if (fmt->pad == ssd->source_pad) { |
1672 | u32 code = fmt->format.code; | 1724 | u32 code = fmt->format.code; |
1673 | int rval = __smiapp_get_format(subdev, fh, fmt); | 1725 | int rval = __smiapp_get_format(subdev, fh, fmt); |
1726 | bool range_changed = false; | ||
1727 | unsigned int i; | ||
1674 | 1728 | ||
1675 | if (!rval && subdev == &sensor->src->sd) { | 1729 | if (!rval && subdev == &sensor->src->sd) { |
1676 | const struct smiapp_csi_data_format *csi_format = | 1730 | const struct smiapp_csi_data_format *csi_format = |
1677 | smiapp_validate_csi_data_format(sensor, code); | 1731 | smiapp_validate_csi_data_format(sensor, code); |
1678 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) | 1732 | |
1733 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | ||
1734 | if (csi_format->width != | ||
1735 | sensor->csi_format->width) | ||
1736 | range_changed = true; | ||
1737 | |||
1679 | sensor->csi_format = csi_format; | 1738 | sensor->csi_format = csi_format; |
1739 | } | ||
1740 | |||
1680 | fmt->format.code = csi_format->code; | 1741 | fmt->format.code = csi_format->code; |
1681 | } | 1742 | } |
1682 | 1743 | ||
1683 | mutex_unlock(&sensor->mutex); | 1744 | mutex_unlock(&sensor->mutex); |
1684 | return rval; | 1745 | if (rval || !range_changed) |
1746 | return rval; | ||
1747 | |||
1748 | for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) | ||
1749 | v4l2_ctrl_modify_range( | ||
1750 | sensor->test_data[i], | ||
1751 | 0, (1 << sensor->csi_format->width) - 1, 1, 0); | ||
1752 | |||
1753 | return 0; | ||
1685 | } | 1754 | } |
1686 | 1755 | ||
1687 | /* Sink pad. Width and height are changeable here. */ | 1756 | /* Sink pad. Width and height are changeable here. */ |
diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index 7cc5aae662fd..874b49ffd88f 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h | |||
@@ -54,6 +54,8 @@ | |||
54 | (1000 + (SMIAPP_RESET_DELAY_CLOCKS * 1000 \ | 54 | (1000 + (SMIAPP_RESET_DELAY_CLOCKS * 1000 \ |
55 | + (clk) / 1000 - 1) / ((clk) / 1000)) | 55 | + (clk) / 1000 - 1) / ((clk) / 1000)) |
56 | 56 | ||
57 | #define SMIAPP_COLOUR_COMPONENTS 4 | ||
58 | |||
57 | #include "smiapp-limits.h" | 59 | #include "smiapp-limits.h" |
58 | 60 | ||
59 | struct smiapp_quirk; | 61 | struct smiapp_quirk; |
@@ -241,6 +243,8 @@ struct smiapp_sensor { | |||
241 | /* src controls */ | 243 | /* src controls */ |
242 | struct v4l2_ctrl *link_freq; | 244 | struct v4l2_ctrl *link_freq; |
243 | struct v4l2_ctrl *pixel_rate_csi; | 245 | struct v4l2_ctrl *pixel_rate_csi; |
246 | /* test pattern colour components */ | ||
247 | struct v4l2_ctrl *test_data[SMIAPP_COLOUR_COMPONENTS]; | ||
244 | }; | 248 | }; |
245 | 249 | ||
246 | #define to_smiapp_subdev(_sd) \ | 250 | #define to_smiapp_subdev(_sd) \ |