diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2011-09-07 04:12:03 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-03 16:28:37 -0400 |
commit | 91b6286ff3190fece7314b61ef330da96c4d644f (patch) | |
tree | 1767842d3d4faeda9ce4bba19fc7ab40896441bc /drivers/media/video | |
parent | 839b48dff10990c03f7d41afdaf5853cb3c0ab83 (diff) |
[media] ov772x: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
[g.liakhovetski@gmx.de: simplified pointer arithmetic]
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/ov772x.c | 114 |
1 files changed, 36 insertions, 78 deletions
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index f77e8995fe40..9b540421e2cb 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <media/ov772x.h> | 25 | #include <media/ov772x.h> |
26 | #include <media/soc_camera.h> | 26 | #include <media/soc_camera.h> |
27 | #include <media/soc_mediabus.h> | 27 | #include <media/soc_mediabus.h> |
28 | #include <media/v4l2-ctrls.h> | ||
28 | #include <media/v4l2-chip-ident.h> | 29 | #include <media/v4l2-chip-ident.h> |
29 | #include <media/v4l2-subdev.h> | 30 | #include <media/v4l2-subdev.h> |
30 | 31 | ||
@@ -401,6 +402,7 @@ struct ov772x_win_size { | |||
401 | 402 | ||
402 | struct ov772x_priv { | 403 | struct ov772x_priv { |
403 | struct v4l2_subdev subdev; | 404 | struct v4l2_subdev subdev; |
405 | struct v4l2_ctrl_handler hdl; | ||
404 | struct ov772x_camera_info *info; | 406 | struct ov772x_camera_info *info; |
405 | const struct ov772x_color_format *cfmt; | 407 | const struct ov772x_color_format *cfmt; |
406 | const struct ov772x_win_size *win; | 408 | const struct ov772x_win_size *win; |
@@ -518,36 +520,6 @@ static const struct ov772x_win_size ov772x_win_qvga = { | |||
518 | .regs = ov772x_qvga_regs, | 520 | .regs = ov772x_qvga_regs, |
519 | }; | 521 | }; |
520 | 522 | ||
521 | static const struct v4l2_queryctrl ov772x_controls[] = { | ||
522 | { | ||
523 | .id = V4L2_CID_VFLIP, | ||
524 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
525 | .name = "Flip Vertically", | ||
526 | .minimum = 0, | ||
527 | .maximum = 1, | ||
528 | .step = 1, | ||
529 | .default_value = 0, | ||
530 | }, | ||
531 | { | ||
532 | .id = V4L2_CID_HFLIP, | ||
533 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
534 | .name = "Flip Horizontally", | ||
535 | .minimum = 0, | ||
536 | .maximum = 1, | ||
537 | .step = 1, | ||
538 | .default_value = 0, | ||
539 | }, | ||
540 | { | ||
541 | .id = V4L2_CID_BAND_STOP_FILTER, | ||
542 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
543 | .name = "Band-stop filter", | ||
544 | .minimum = 0, | ||
545 | .maximum = 256, | ||
546 | .step = 1, | ||
547 | .default_value = 0, | ||
548 | }, | ||
549 | }; | ||
550 | |||
551 | /* | 523 | /* |
552 | * general function | 524 | * general function |
553 | */ | 525 | */ |
@@ -621,52 +593,30 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) | |||
621 | return 0; | 593 | return 0; |
622 | } | 594 | } |
623 | 595 | ||
624 | static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 596 | static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl) |
625 | { | ||
626 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); | ||
627 | |||
628 | switch (ctrl->id) { | ||
629 | case V4L2_CID_VFLIP: | ||
630 | ctrl->value = priv->flag_vflip; | ||
631 | break; | ||
632 | case V4L2_CID_HFLIP: | ||
633 | ctrl->value = priv->flag_hflip; | ||
634 | break; | ||
635 | case V4L2_CID_BAND_STOP_FILTER: | ||
636 | ctrl->value = priv->band_filter; | ||
637 | break; | ||
638 | } | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
643 | { | 597 | { |
598 | struct ov772x_priv *priv = container_of(ctrl->handler, | ||
599 | struct ov772x_priv, hdl); | ||
600 | struct v4l2_subdev *sd = &priv->subdev; | ||
644 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 601 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
645 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); | ||
646 | int ret = 0; | 602 | int ret = 0; |
647 | u8 val; | 603 | u8 val; |
648 | 604 | ||
649 | switch (ctrl->id) { | 605 | switch (ctrl->id) { |
650 | case V4L2_CID_VFLIP: | 606 | case V4L2_CID_VFLIP: |
651 | val = ctrl->value ? VFLIP_IMG : 0x00; | 607 | val = ctrl->val ? VFLIP_IMG : 0x00; |
652 | priv->flag_vflip = ctrl->value; | 608 | priv->flag_vflip = ctrl->val; |
653 | if (priv->info->flags & OV772X_FLAG_VFLIP) | 609 | if (priv->info->flags & OV772X_FLAG_VFLIP) |
654 | val ^= VFLIP_IMG; | 610 | val ^= VFLIP_IMG; |
655 | ret = ov772x_mask_set(client, COM3, VFLIP_IMG, val); | 611 | return ov772x_mask_set(client, COM3, VFLIP_IMG, val); |
656 | break; | ||
657 | case V4L2_CID_HFLIP: | 612 | case V4L2_CID_HFLIP: |
658 | val = ctrl->value ? HFLIP_IMG : 0x00; | 613 | val = ctrl->val ? HFLIP_IMG : 0x00; |
659 | priv->flag_hflip = ctrl->value; | 614 | priv->flag_hflip = ctrl->val; |
660 | if (priv->info->flags & OV772X_FLAG_HFLIP) | 615 | if (priv->info->flags & OV772X_FLAG_HFLIP) |
661 | val ^= HFLIP_IMG; | 616 | val ^= HFLIP_IMG; |
662 | ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val); | 617 | return ov772x_mask_set(client, COM3, HFLIP_IMG, val); |
663 | break; | ||
664 | case V4L2_CID_BAND_STOP_FILTER: | 618 | case V4L2_CID_BAND_STOP_FILTER: |
665 | if ((unsigned)ctrl->value > 256) | 619 | if (!ctrl->val) { |
666 | ctrl->value = 256; | ||
667 | if (ctrl->value == priv->band_filter) | ||
668 | break; | ||
669 | if (!ctrl->value) { | ||
670 | /* Switch the filter off, it is on now */ | 620 | /* Switch the filter off, it is on now */ |
671 | ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff); | 621 | ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff); |
672 | if (!ret) | 622 | if (!ret) |
@@ -674,7 +624,7 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
674 | BNDF_ON_OFF, 0); | 624 | BNDF_ON_OFF, 0); |
675 | } else { | 625 | } else { |
676 | /* Switch the filter on, set AEC low limit */ | 626 | /* Switch the filter on, set AEC low limit */ |
677 | val = 256 - ctrl->value; | 627 | val = 256 - ctrl->val; |
678 | ret = ov772x_mask_set(client, COM8, | 628 | ret = ov772x_mask_set(client, COM8, |
679 | BNDF_ON_OFF, BNDF_ON_OFF); | 629 | BNDF_ON_OFF, BNDF_ON_OFF); |
680 | if (!ret) | 630 | if (!ret) |
@@ -682,11 +632,11 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
682 | 0xff, val); | 632 | 0xff, val); |
683 | } | 633 | } |
684 | if (!ret) | 634 | if (!ret) |
685 | priv->band_filter = ctrl->value; | 635 | priv->band_filter = ctrl->val; |
686 | break; | 636 | return ret; |
687 | } | 637 | } |
688 | 638 | ||
689 | return ret; | 639 | return -EINVAL; |
690 | } | 640 | } |
691 | 641 | ||
692 | static int ov772x_g_chip_ident(struct v4l2_subdev *sd, | 642 | static int ov772x_g_chip_ident(struct v4l2_subdev *sd, |
@@ -1042,18 +992,14 @@ static int ov772x_video_probe(struct soc_camera_device *icd, | |||
1042 | ver, | 992 | ver, |
1043 | i2c_smbus_read_byte_data(client, MIDH), | 993 | i2c_smbus_read_byte_data(client, MIDH), |
1044 | i2c_smbus_read_byte_data(client, MIDL)); | 994 | i2c_smbus_read_byte_data(client, MIDL)); |
1045 | 995 | return v4l2_ctrl_handler_setup(&priv->hdl); | |
1046 | return 0; | ||
1047 | } | 996 | } |
1048 | 997 | ||
1049 | static struct soc_camera_ops ov772x_ops = { | 998 | static const struct v4l2_ctrl_ops ov772x_ctrl_ops = { |
1050 | .controls = ov772x_controls, | 999 | .s_ctrl = ov772x_s_ctrl, |
1051 | .num_controls = ARRAY_SIZE(ov772x_controls), | ||
1052 | }; | 1000 | }; |
1053 | 1001 | ||
1054 | static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { | 1002 | static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { |
1055 | .g_ctrl = ov772x_g_ctrl, | ||
1056 | .s_ctrl = ov772x_s_ctrl, | ||
1057 | .g_chip_ident = ov772x_g_chip_ident, | 1003 | .g_chip_ident = ov772x_g_chip_ident, |
1058 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1004 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1059 | .g_register = ov772x_g_register, | 1005 | .g_register = ov772x_g_register, |
@@ -1139,12 +1085,24 @@ static int ov772x_probe(struct i2c_client *client, | |||
1139 | priv->info = icl->priv; | 1085 | priv->info = icl->priv; |
1140 | 1086 | ||
1141 | v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); | 1087 | v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); |
1088 | v4l2_ctrl_handler_init(&priv->hdl, 3); | ||
1089 | v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, | ||
1090 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
1091 | v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, | ||
1092 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
1093 | v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, | ||
1094 | V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0); | ||
1095 | priv->subdev.ctrl_handler = &priv->hdl; | ||
1096 | if (priv->hdl.error) { | ||
1097 | int err = priv->hdl.error; | ||
1142 | 1098 | ||
1143 | icd->ops = &ov772x_ops; | 1099 | kfree(priv); |
1100 | return err; | ||
1101 | } | ||
1144 | 1102 | ||
1145 | ret = ov772x_video_probe(icd, client); | 1103 | ret = ov772x_video_probe(icd, client); |
1146 | if (ret) { | 1104 | if (ret) { |
1147 | icd->ops = NULL; | 1105 | v4l2_ctrl_handler_free(&priv->hdl); |
1148 | kfree(priv); | 1106 | kfree(priv); |
1149 | } | 1107 | } |
1150 | 1108 | ||
@@ -1154,9 +1112,9 @@ static int ov772x_probe(struct i2c_client *client, | |||
1154 | static int ov772x_remove(struct i2c_client *client) | 1112 | static int ov772x_remove(struct i2c_client *client) |
1155 | { | 1113 | { |
1156 | struct ov772x_priv *priv = to_ov772x(client); | 1114 | struct ov772x_priv *priv = to_ov772x(client); |
1157 | struct soc_camera_device *icd = client->dev.platform_data; | ||
1158 | 1115 | ||
1159 | icd->ops = NULL; | 1116 | v4l2_device_unregister_subdev(&priv->subdev); |
1117 | v4l2_ctrl_handler_free(&priv->hdl); | ||
1160 | kfree(priv); | 1118 | kfree(priv); |
1161 | return 0; | 1119 | return 0; |
1162 | } | 1120 | } |