aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sunplus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/sunplus.c')
-rw-r--r--drivers/media/video/gspca/sunplus.c237
1 files changed, 54 insertions, 183 deletions
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index c80f0c0c75b6..9ccfcb1c6479 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -30,18 +30,13 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32 32
33#define QUALITY 85
34
33/* specific webcam descriptor */ 35/* specific webcam descriptor */
34struct sd { 36struct sd {
35 struct gspca_dev gspca_dev; /* !! must be the first item */ 37 struct gspca_dev gspca_dev; /* !! must be the first item */
36 38
37 s8 brightness; 39 bool autogain;
38 u8 contrast;
39 u8 colors;
40 u8 autogain;
41 u8 quality;
42#define QUALITY_MIN 70
43#define QUALITY_MAX 95
44#define QUALITY_DEF 85
45 40
46 u8 bridge; 41 u8 bridge;
47#define BRIDGE_SPCA504 0 42#define BRIDGE_SPCA504 0
@@ -59,75 +54,6 @@ struct sd {
59 u8 jpeg_hdr[JPEG_HDR_SZ]; 54 u8 jpeg_hdr[JPEG_HDR_SZ];
60}; 55};
61 56
62/* V4L2 controls supported by the driver */
63static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
64static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
65static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
66static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
67static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
68static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
69static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
71
72static const struct ctrl sd_ctrls[] = {
73 {
74 {
75 .id = V4L2_CID_BRIGHTNESS,
76 .type = V4L2_CTRL_TYPE_INTEGER,
77 .name = "Brightness",
78 .minimum = -128,
79 .maximum = 127,
80 .step = 1,
81#define BRIGHTNESS_DEF 0
82 .default_value = BRIGHTNESS_DEF,
83 },
84 .set = sd_setbrightness,
85 .get = sd_getbrightness,
86 },
87 {
88 {
89 .id = V4L2_CID_CONTRAST,
90 .type = V4L2_CTRL_TYPE_INTEGER,
91 .name = "Contrast",
92 .minimum = 0,
93 .maximum = 0xff,
94 .step = 1,
95#define CONTRAST_DEF 0x20
96 .default_value = CONTRAST_DEF,
97 },
98 .set = sd_setcontrast,
99 .get = sd_getcontrast,
100 },
101 {
102 {
103 .id = V4L2_CID_SATURATION,
104 .type = V4L2_CTRL_TYPE_INTEGER,
105 .name = "Color",
106 .minimum = 0,
107 .maximum = 0xff,
108 .step = 1,
109#define COLOR_DEF 0x1a
110 .default_value = COLOR_DEF,
111 },
112 .set = sd_setcolors,
113 .get = sd_getcolors,
114 },
115 {
116 {
117 .id = V4L2_CID_AUTOGAIN,
118 .type = V4L2_CTRL_TYPE_BOOLEAN,
119 .name = "Auto Gain",
120 .minimum = 0,
121 .maximum = 1,
122 .step = 1,
123#define AUTOGAIN_DEF 1
124 .default_value = AUTOGAIN_DEF,
125 },
126 .set = sd_setautogain,
127 .get = sd_getautogain,
128 },
129};
130
131static const struct v4l2_pix_format vga_mode[] = { 57static const struct v4l2_pix_format vga_mode[] = {
132 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 58 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
133 .bytesperline = 320, 59 .bytesperline = 320,
@@ -597,31 +523,31 @@ static void spca504B_setQtable(struct gspca_dev *gspca_dev)
597 spca504B_PollingDataReady(gspca_dev); 523 spca504B_PollingDataReady(gspca_dev);
598} 524}
599 525
600static void setbrightness(struct gspca_dev *gspca_dev) 526static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
601{ 527{
602 struct sd *sd = (struct sd *) gspca_dev; 528 struct sd *sd = (struct sd *) gspca_dev;
603 u16 reg; 529 u16 reg;
604 530
605 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7; 531 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
606 reg_w_riv(gspca_dev, 0x00, reg, sd->brightness); 532 reg_w_riv(gspca_dev, 0x00, reg, val);
607} 533}
608 534
609static void setcontrast(struct gspca_dev *gspca_dev) 535static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
610{ 536{
611 struct sd *sd = (struct sd *) gspca_dev; 537 struct sd *sd = (struct sd *) gspca_dev;
612 u16 reg; 538 u16 reg;
613 539
614 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8; 540 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
615 reg_w_riv(gspca_dev, 0x00, reg, sd->contrast); 541 reg_w_riv(gspca_dev, 0x00, reg, val);
616} 542}
617 543
618static void setcolors(struct gspca_dev *gspca_dev) 544static void setcolors(struct gspca_dev *gspca_dev, s32 val)
619{ 545{
620 struct sd *sd = (struct sd *) gspca_dev; 546 struct sd *sd = (struct sd *) gspca_dev;
621 u16 reg; 547 u16 reg;
622 548
623 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae; 549 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
624 reg_w_riv(gspca_dev, 0x00, reg, sd->colors); 550 reg_w_riv(gspca_dev, 0x00, reg, val);
625} 551}
626 552
627static void init_ctl_reg(struct gspca_dev *gspca_dev) 553static void init_ctl_reg(struct gspca_dev *gspca_dev)
@@ -629,10 +555,6 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev)
629 struct sd *sd = (struct sd *) gspca_dev; 555 struct sd *sd = (struct sd *) gspca_dev;
630 int pollreg = 1; 556 int pollreg = 1;
631 557
632 setbrightness(gspca_dev);
633 setcontrast(gspca_dev);
634 setcolors(gspca_dev);
635
636 switch (sd->bridge) { 558 switch (sd->bridge) {
637 case BRIDGE_SPCA504: 559 case BRIDGE_SPCA504:
638 case BRIDGE_SPCA504C: 560 case BRIDGE_SPCA504C:
@@ -704,11 +626,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
704 cam->nmodes = ARRAY_SIZE(vga_mode2); 626 cam->nmodes = ARRAY_SIZE(vga_mode2);
705 break; 627 break;
706 } 628 }
707 sd->brightness = BRIGHTNESS_DEF;
708 sd->contrast = CONTRAST_DEF;
709 sd->colors = COLOR_DEF;
710 sd->autogain = AUTOGAIN_DEF;
711 sd->quality = QUALITY_DEF;
712 return 0; 629 return 0;
713} 630}
714 631
@@ -807,7 +724,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
807 /* create the JPEG header */ 724 /* create the JPEG header */
808 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 725 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
809 0x22); /* JPEG 411 */ 726 0x22); /* JPEG 411 */
810 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 727 jpeg_set_qual(sd->jpeg_hdr, QUALITY);
811 728
812 if (sd->bridge == BRIDGE_SPCA504B) 729 if (sd->bridge == BRIDGE_SPCA504B)
813 spca504B_setQtable(gspca_dev); 730 spca504B_setQtable(gspca_dev);
@@ -1012,116 +929,69 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1012 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 929 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1013} 930}
1014 931
1015static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 932static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1016{
1017 struct sd *sd = (struct sd *) gspca_dev;
1018
1019 sd->brightness = val;
1020 if (gspca_dev->streaming)
1021 setbrightness(gspca_dev);
1022 return gspca_dev->usb_err;
1023}
1024
1025static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1026{
1027 struct sd *sd = (struct sd *) gspca_dev;
1028
1029 *val = sd->brightness;
1030 return 0;
1031}
1032
1033static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1034{ 933{
1035 struct sd *sd = (struct sd *) gspca_dev; 934 struct gspca_dev *gspca_dev =
935 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
936 struct sd *sd = (struct sd *)gspca_dev;
1036 937
1037 sd->contrast = val; 938 gspca_dev->usb_err = 0;
1038 if (gspca_dev->streaming)
1039 setcontrast(gspca_dev);
1040 return gspca_dev->usb_err;
1041}
1042 939
1043static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 940 if (!gspca_dev->streaming)
1044{ 941 return 0;
1045 struct sd *sd = (struct sd *) gspca_dev;
1046 942
1047 *val = sd->contrast; 943 switch (ctrl->id) {
1048 return 0; 944 case V4L2_CID_BRIGHTNESS:
1049} 945 setbrightness(gspca_dev, ctrl->val);
1050 946 break;
1051static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) 947 case V4L2_CID_CONTRAST:
1052{ 948 setcontrast(gspca_dev, ctrl->val);
1053 struct sd *sd = (struct sd *) gspca_dev; 949 break;
1054 950 case V4L2_CID_SATURATION:
1055 sd->colors = val; 951 setcolors(gspca_dev, ctrl->val);
1056 if (gspca_dev->streaming) 952 break;
1057 setcolors(gspca_dev); 953 case V4L2_CID_AUTOGAIN:
954 sd->autogain = ctrl->val;
955 break;
956 }
1058 return gspca_dev->usb_err; 957 return gspca_dev->usb_err;
1059} 958}
1060 959
1061static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 960static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1062{ 961 .s_ctrl = sd_s_ctrl,
1063 struct sd *sd = (struct sd *) gspca_dev; 962};
1064
1065 *val = sd->colors;
1066 return 0;
1067}
1068
1069static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1070{
1071 struct sd *sd = (struct sd *) gspca_dev;
1072
1073 sd->autogain = val;
1074 return 0;
1075}
1076
1077static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1078{
1079 struct sd *sd = (struct sd *) gspca_dev;
1080
1081 *val = sd->autogain;
1082 return 0;
1083}
1084
1085static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1086 struct v4l2_jpegcompression *jcomp)
1087{
1088 struct sd *sd = (struct sd *) gspca_dev;
1089
1090 if (jcomp->quality < QUALITY_MIN)
1091 sd->quality = QUALITY_MIN;
1092 else if (jcomp->quality > QUALITY_MAX)
1093 sd->quality = QUALITY_MAX;
1094 else
1095 sd->quality = jcomp->quality;
1096 if (gspca_dev->streaming)
1097 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1098 return gspca_dev->usb_err;
1099}
1100 963
1101static int sd_get_jcomp(struct gspca_dev *gspca_dev, 964static int sd_init_controls(struct gspca_dev *gspca_dev)
1102 struct v4l2_jpegcompression *jcomp)
1103{ 965{
1104 struct sd *sd = (struct sd *) gspca_dev; 966 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1105 967
1106 memset(jcomp, 0, sizeof *jcomp); 968 gspca_dev->vdev.ctrl_handler = hdl;
1107 jcomp->quality = sd->quality; 969 v4l2_ctrl_handler_init(hdl, 4);
1108 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 970 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1109 | V4L2_JPEG_MARKER_DQT; 971 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
972 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
973 V4L2_CID_CONTRAST, 0, 255, 1, 0x20);
974 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
975 V4L2_CID_SATURATION, 0, 255, 1, 0x1a);
976 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
977 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
978
979 if (hdl->error) {
980 pr_err("Could not initialize controls\n");
981 return hdl->error;
982 }
1110 return 0; 983 return 0;
1111} 984}
1112 985
1113/* sub-driver description */ 986/* sub-driver description */
1114static const struct sd_desc sd_desc = { 987static const struct sd_desc sd_desc = {
1115 .name = MODULE_NAME, 988 .name = MODULE_NAME,
1116 .ctrls = sd_ctrls,
1117 .nctrls = ARRAY_SIZE(sd_ctrls),
1118 .config = sd_config, 989 .config = sd_config,
1119 .init = sd_init, 990 .init = sd_init,
991 .init_controls = sd_init_controls,
1120 .start = sd_start, 992 .start = sd_start,
1121 .stopN = sd_stopN, 993 .stopN = sd_stopN,
1122 .pkt_scan = sd_pkt_scan, 994 .pkt_scan = sd_pkt_scan,
1123 .get_jcomp = sd_get_jcomp,
1124 .set_jcomp = sd_set_jcomp,
1125}; 995};
1126 996
1127/* -- module initialisation -- */ 997/* -- module initialisation -- */
@@ -1208,6 +1078,7 @@ static struct usb_driver sd_driver = {
1208#ifdef CONFIG_PM 1078#ifdef CONFIG_PM
1209 .suspend = gspca_suspend, 1079 .suspend = gspca_suspend,
1210 .resume = gspca_resume, 1080 .resume = gspca_resume,
1081 .reset_resume = gspca_resume,
1211#endif 1082#endif
1212}; 1083};
1213 1084