aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2010-12-12 06:45:22 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:50 -0400
commitcf6832afe59f37b154bf0e41bf5e59cfd7f46d24 (patch)
treecdcf384327617060c060c5acc5a8dbf80af60968
parente3d5ef0410806d94cf58afd87a753ad5932ca8a8 (diff)
[media] tvp514x: use the control framework
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/tvp514x.c236
1 files changed, 57 insertions, 179 deletions
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 45bcf0358a1d..9b3e828b0775 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -37,6 +37,7 @@
37#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
38#include <media/v4l2-mediabus.h> 38#include <media/v4l2-mediabus.h>
39#include <media/v4l2-chip-ident.h> 39#include <media/v4l2-chip-ident.h>
40#include <media/v4l2-ctrls.h>
40#include <media/tvp514x.h> 41#include <media/tvp514x.h>
41 42
42#include "tvp514x_regs.h" 43#include "tvp514x_regs.h"
@@ -97,6 +98,7 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
97 */ 98 */
98struct tvp514x_decoder { 99struct tvp514x_decoder {
99 struct v4l2_subdev sd; 100 struct v4l2_subdev sd;
101 struct v4l2_ctrl_handler hdl;
100 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; 102 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
101 const struct tvp514x_platform_data *pdata; 103 const struct tvp514x_platform_data *pdata;
102 104
@@ -238,6 +240,11 @@ static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd)
238 return container_of(sd, struct tvp514x_decoder, sd); 240 return container_of(sd, struct tvp514x_decoder, sd);
239} 241}
240 242
243static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
244{
245 return &container_of(ctrl->handler, struct tvp514x_decoder, hdl)->sd;
246}
247
241 248
242/** 249/**
243 * tvp514x_read_reg() - Read a value from a register in an TVP5146/47. 250 * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
@@ -719,213 +726,54 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
719} 726}
720 727
721/** 728/**
722 * tvp514x_queryctrl() - V4L2 decoder interface handler for queryctrl
723 * @sd: pointer to standard V4L2 sub-device structure
724 * @qctrl: standard V4L2 v4l2_queryctrl structure
725 *
726 * If the requested control is supported, returns the control information.
727 * Otherwise, returns -EINVAL if the control is not supported.
728 */
729static int
730tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
731{
732 int err = -EINVAL;
733
734 if (qctrl == NULL)
735 return err;
736
737 switch (qctrl->id) {
738 case V4L2_CID_BRIGHTNESS:
739 /* Brightness supported is (0-255), */
740 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
741 break;
742 case V4L2_CID_CONTRAST:
743 case V4L2_CID_SATURATION:
744 /**
745 * Saturation and Contrast supported is -
746 * Contrast: 0 - 255 (Default - 128)
747 * Saturation: 0 - 255 (Default - 128)
748 */
749 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
750 break;
751 case V4L2_CID_HUE:
752 /* Hue Supported is -
753 * Hue - -180 - +180 (Default - 0, Step - +180)
754 */
755 err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
756 break;
757 case V4L2_CID_AUTOGAIN:
758 /**
759 * Auto Gain supported is -
760 * 0 - 1 (Default - 1)
761 */
762 err = v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
763 break;
764 default:
765 v4l2_err(sd, "invalid control id %d\n", qctrl->id);
766 return err;
767 }
768
769 v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d\n",
770 qctrl->name, qctrl->minimum, qctrl->maximum,
771 qctrl->default_value);
772
773 return err;
774}
775
776/**
777 * tvp514x_g_ctrl() - V4L2 decoder interface handler for g_ctrl
778 * @sd: pointer to standard V4L2 sub-device structure
779 * @ctrl: pointer to v4l2_control structure
780 *
781 * If the requested control is supported, returns the control's current
782 * value from the decoder. Otherwise, returns -EINVAL if the control is not
783 * supported.
784 */
785static int
786tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
787{
788 struct tvp514x_decoder *decoder = to_decoder(sd);
789
790 if (ctrl == NULL)
791 return -EINVAL;
792
793 switch (ctrl->id) {
794 case V4L2_CID_BRIGHTNESS:
795 ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val;
796 break;
797 case V4L2_CID_CONTRAST:
798 ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val;
799 break;
800 case V4L2_CID_SATURATION:
801 ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val;
802 break;
803 case V4L2_CID_HUE:
804 ctrl->value = decoder->tvp514x_regs[REG_HUE].val;
805 if (ctrl->value == 0x7F)
806 ctrl->value = 180;
807 else if (ctrl->value == 0x80)
808 ctrl->value = -180;
809 else
810 ctrl->value = 0;
811
812 break;
813 case V4L2_CID_AUTOGAIN:
814 ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val;
815 if ((ctrl->value & 0x3) == 3)
816 ctrl->value = 1;
817 else
818 ctrl->value = 0;
819
820 break;
821 default:
822 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
823 return -EINVAL;
824 }
825
826 v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d\n",
827 ctrl->id, ctrl->value);
828 return 0;
829}
830
831/**
832 * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl 729 * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl
833 * @sd: pointer to standard V4L2 sub-device structure 730 * @ctrl: pointer to v4l2_ctrl structure
834 * @ctrl: pointer to v4l2_control structure
835 * 731 *
836 * If the requested control is supported, sets the control's current 732 * If the requested control is supported, sets the control's current
837 * value in HW. Otherwise, returns -EINVAL if the control is not supported. 733 * value in HW. Otherwise, returns -EINVAL if the control is not supported.
838 */ 734 */
839static int 735static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl)
840tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
841{ 736{
737 struct v4l2_subdev *sd = to_sd(ctrl);
842 struct tvp514x_decoder *decoder = to_decoder(sd); 738 struct tvp514x_decoder *decoder = to_decoder(sd);
843 int err = -EINVAL, value; 739 int err = -EINVAL, value;
844 740
845 if (ctrl == NULL) 741 value = ctrl->val;
846 return err;
847
848 value = ctrl->value;
849 742
850 switch (ctrl->id) { 743 switch (ctrl->id) {
851 case V4L2_CID_BRIGHTNESS: 744 case V4L2_CID_BRIGHTNESS:
852 if (ctrl->value < 0 || ctrl->value > 255) { 745 err = tvp514x_write_reg(sd, REG_BRIGHTNESS, value);
853 v4l2_err(sd, "invalid brightness setting %d\n", 746 if (!err)
854 ctrl->value); 747 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
855 return -ERANGE;
856 }
857 err = tvp514x_write_reg(sd, REG_BRIGHTNESS,
858 value);
859 if (err)
860 return err;
861
862 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
863 break; 748 break;
864 case V4L2_CID_CONTRAST: 749 case V4L2_CID_CONTRAST:
865 if (ctrl->value < 0 || ctrl->value > 255) {
866 v4l2_err(sd, "invalid contrast setting %d\n",
867 ctrl->value);
868 return -ERANGE;
869 }
870 err = tvp514x_write_reg(sd, REG_CONTRAST, value); 750 err = tvp514x_write_reg(sd, REG_CONTRAST, value);
871 if (err) 751 if (!err)
872 return err; 752 decoder->tvp514x_regs[REG_CONTRAST].val = value;
873
874 decoder->tvp514x_regs[REG_CONTRAST].val = value;
875 break; 753 break;
876 case V4L2_CID_SATURATION: 754 case V4L2_CID_SATURATION:
877 if (ctrl->value < 0 || ctrl->value > 255) {
878 v4l2_err(sd, "invalid saturation setting %d\n",
879 ctrl->value);
880 return -ERANGE;
881 }
882 err = tvp514x_write_reg(sd, REG_SATURATION, value); 755 err = tvp514x_write_reg(sd, REG_SATURATION, value);
883 if (err) 756 if (!err)
884 return err; 757 decoder->tvp514x_regs[REG_SATURATION].val = value;
885
886 decoder->tvp514x_regs[REG_SATURATION].val = value;
887 break; 758 break;
888 case V4L2_CID_HUE: 759 case V4L2_CID_HUE:
889 if (value == 180) 760 if (value == 180)
890 value = 0x7F; 761 value = 0x7F;
891 else if (value == -180) 762 else if (value == -180)
892 value = 0x80; 763 value = 0x80;
893 else if (value == 0)
894 value = 0;
895 else {
896 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
897 return -ERANGE;
898 }
899 err = tvp514x_write_reg(sd, REG_HUE, value); 764 err = tvp514x_write_reg(sd, REG_HUE, value);
900 if (err) 765 if (!err)
901 return err; 766 decoder->tvp514x_regs[REG_HUE].val = value;
902
903 decoder->tvp514x_regs[REG_HUE].val = value;
904 break; 767 break;
905 case V4L2_CID_AUTOGAIN: 768 case V4L2_CID_AUTOGAIN:
906 if (value == 1) 769 err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value ? 0x0f : 0x0c);
907 value = 0x0F; 770 if (!err)
908 else if (value == 0) 771 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
909 value = 0x0C;
910 else {
911 v4l2_err(sd, "invalid auto gain setting %d\n",
912 ctrl->value);
913 return -ERANGE;
914 }
915 err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value);
916 if (err)
917 return err;
918
919 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
920 break; 772 break;
921 default:
922 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
923 return err;
924 } 773 }
925 774
926 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n", 775 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n",
927 ctrl->id, ctrl->value); 776 ctrl->id, ctrl->val);
928
929 return err; 777 return err;
930} 778}
931 779
@@ -1104,10 +952,18 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
1104 return err; 952 return err;
1105} 953}
1106 954
1107static const struct v4l2_subdev_core_ops tvp514x_core_ops = { 955static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = {
1108 .queryctrl = tvp514x_queryctrl,
1109 .g_ctrl = tvp514x_g_ctrl,
1110 .s_ctrl = tvp514x_s_ctrl, 956 .s_ctrl = tvp514x_s_ctrl,
957};
958
959static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
960 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
961 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
962 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
963 .g_ctrl = v4l2_subdev_g_ctrl,
964 .s_ctrl = v4l2_subdev_s_ctrl,
965 .queryctrl = v4l2_subdev_queryctrl,
966 .querymenu = v4l2_subdev_querymenu,
1111 .s_std = tvp514x_s_std, 967 .s_std = tvp514x_s_std,
1112}; 968};
1113 969
@@ -1190,6 +1046,27 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
1190 sd = &decoder->sd; 1046 sd = &decoder->sd;
1191 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops); 1047 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
1192 1048
1049 v4l2_ctrl_handler_init(&decoder->hdl, 5);
1050 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1051 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1052 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1053 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1054 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1055 V4L2_CID_SATURATION, 0, 255, 1, 128);
1056 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1057 V4L2_CID_HUE, -180, 180, 180, 0);
1058 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1059 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1060 sd->ctrl_handler = &decoder->hdl;
1061 if (decoder->hdl.error) {
1062 int err = decoder->hdl.error;
1063
1064 v4l2_ctrl_handler_free(&decoder->hdl);
1065 kfree(decoder);
1066 return err;
1067 }
1068 v4l2_ctrl_handler_setup(&decoder->hdl);
1069
1193 v4l2_info(sd, "%s decoder driver registered !!\n", sd->name); 1070 v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
1194 1071
1195 return 0; 1072 return 0;
@@ -1209,6 +1086,7 @@ static int tvp514x_remove(struct i2c_client *client)
1209 struct tvp514x_decoder *decoder = to_decoder(sd); 1086 struct tvp514x_decoder *decoder = to_decoder(sd);
1210 1087
1211 v4l2_device_unregister_subdev(sd); 1088 v4l2_device_unregister_subdev(sd);
1089 v4l2_ctrl_handler_free(&decoder->hdl);
1212 kfree(decoder); 1090 kfree(decoder);
1213 return 0; 1091 return 0;
1214} 1092}