aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/t613.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/t613.c')
-rw-r--r--drivers/media/video/gspca/t613.c172
1 files changed, 161 insertions, 11 deletions
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 668a7536af90..63014372adbc 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -44,7 +44,10 @@ struct sd {
44 u8 gamma; 44 u8 gamma;
45 u8 sharpness; 45 u8 sharpness;
46 u8 freq; 46 u8 freq;
47 u8 whitebalance; 47 u8 red_balance; /* split balance */
48 u8 blue_balance;
49 u8 global_gain; /* aka gain */
50 u8 whitebalance; /* set default r/g/b and activate */
48 u8 mirror; 51 u8 mirror;
49 u8 effect; 52 u8 effect;
50 53
@@ -70,8 +73,17 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 73static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
71static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 74static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 75static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
76
77
73static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
74static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
80static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val);
86
75static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val); 87static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
76static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val); 88static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); 89static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
@@ -79,6 +91,7 @@ static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_querymenu(struct gspca_dev *gspca_dev, 91static int sd_querymenu(struct gspca_dev *gspca_dev,
80 struct v4l2_querymenu *menu); 92 struct v4l2_querymenu *menu);
81 93
94
82static const struct ctrl sd_ctrls[] = { 95static const struct ctrl sd_ctrls[] = {
83 { 96 {
84 { 97 {
@@ -139,7 +152,7 @@ static const struct ctrl sd_ctrls[] = {
139 }, 152 },
140 { 153 {
141 { 154 {
142 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight, 155 .id = V4L2_CID_BACKLIGHT_COMPENSATION, /* Activa lowlight,
143 * some apps dont bring up the 156 * some apps dont bring up the
144 * backligth_compensation control) */ 157 * backligth_compensation control) */
145 .type = V4L2_CTRL_TYPE_INTEGER, 158 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -183,7 +196,7 @@ static const struct ctrl sd_ctrls[] = {
183 196
184 { 197 {
185 { 198 {
186 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, 199 .id = V4L2_CID_AUTO_WHITE_BALANCE,
187 .type = V4L2_CTRL_TYPE_INTEGER, 200 .type = V4L2_CTRL_TYPE_INTEGER,
188 .name = "White Balance", 201 .name = "White Balance",
189 .minimum = 0, 202 .minimum = 0,
@@ -223,6 +236,48 @@ static const struct ctrl sd_ctrls[] = {
223 .set = sd_seteffect, 236 .set = sd_seteffect,
224 .get = sd_geteffect 237 .get = sd_geteffect
225 }, 238 },
239 {
240 {
241 .id = V4L2_CID_BLUE_BALANCE,
242 .type = V4L2_CTRL_TYPE_INTEGER,
243 .name = "Blue Balance",
244 .minimum = 0x10,
245 .maximum = 0x40,
246 .step = 1,
247#define BLUE_BALANCE_DEF 0x20
248 .default_value = BLUE_BALANCE_DEF,
249 },
250 .set = sd_setblue_balance,
251 .get = sd_getblue_balance,
252 },
253 {
254 {
255 .id = V4L2_CID_RED_BALANCE,
256 .type = V4L2_CTRL_TYPE_INTEGER,
257 .name = "Red Balance",
258 .minimum = 0x10,
259 .maximum = 0x40,
260 .step = 1,
261#define RED_BALANCE_DEF 0x20
262 .default_value = RED_BALANCE_DEF,
263 },
264 .set = sd_setred_balance,
265 .get = sd_getred_balance,
266 },
267 {
268 {
269 .id = V4L2_CID_GAIN,
270 .type = V4L2_CTRL_TYPE_INTEGER,
271 .name = "Gain",
272 .minimum = 0x10,
273 .maximum = 0x40,
274 .step = 1,
275#define global_gain_DEF 0x20
276 .default_value = global_gain_DEF,
277 },
278 .set = sd_setglobal_gain,
279 .get = sd_getglobal_gain,
280 },
226}; 281};
227 282
228static char *effects_control[] = { 283static char *effects_control[] = {
@@ -523,6 +578,10 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
523 u8 *tmpbuf; 578 u8 *tmpbuf;
524 579
525 tmpbuf = kmalloc(len, GFP_KERNEL); 580 tmpbuf = kmalloc(len, GFP_KERNEL);
581 if (!tmpbuf) {
582 err("Out of memory");
583 return;
584 }
526 memcpy(tmpbuf, buffer, len); 585 memcpy(tmpbuf, buffer, len);
527 usb_control_msg(gspca_dev->dev, 586 usb_control_msg(gspca_dev->dev,
528 usb_sndctrlpipe(gspca_dev->dev, 0), 587 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -542,10 +601,15 @@ static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
542 int i; 601 int i;
543 u8 *p, *tmpbuf; 602 u8 *p, *tmpbuf;
544 603
545 if (len * 2 <= USB_BUF_SZ) 604 if (len * 2 <= USB_BUF_SZ) {
546 p = tmpbuf = gspca_dev->usb_buf; 605 p = tmpbuf = gspca_dev->usb_buf;
547 else 606 } else {
548 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL); 607 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
608 if (!tmpbuf) {
609 err("Out of memory");
610 return;
611 }
612 }
549 i = len; 613 i = len;
550 while (--i >= 0) { 614 while (--i >= 0) {
551 *p++ = reg++; 615 *p++ = reg++;
@@ -642,6 +706,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
642 sd->whitebalance = WHITE_BALANCE_DEF; 706 sd->whitebalance = WHITE_BALANCE_DEF;
643 sd->sharpness = SHARPNESS_DEF; 707 sd->sharpness = SHARPNESS_DEF;
644 sd->effect = EFFECTS_DEF; 708 sd->effect = EFFECTS_DEF;
709 sd->red_balance = RED_BALANCE_DEF;
710 sd->blue_balance = BLUE_BALANCE_DEF;
711 sd->global_gain = global_gain_DEF;
712
645 return 0; 713 return 0;
646} 714}
647 715
@@ -693,18 +761,40 @@ static void setgamma(struct gspca_dev *gspca_dev)
693 reg_w_ixbuf(gspca_dev, 0x90, 761 reg_w_ixbuf(gspca_dev, 0x90,
694 gamma_table[sd->gamma], sizeof gamma_table[0]); 762 gamma_table[sd->gamma], sizeof gamma_table[0]);
695} 763}
764static void setglobalgain(struct gspca_dev *gspca_dev)
765{
696 766
697static void setwhitebalance(struct gspca_dev *gspca_dev) 767 struct sd *sd = (struct sd *) gspca_dev;
768 reg_w(gspca_dev, (sd->red_balance << 8) + 0x87);
769 reg_w(gspca_dev, (sd->blue_balance << 8) + 0x88);
770 reg_w(gspca_dev, (sd->global_gain << 8) + 0x89);
771}
772
773/* Generic fnc for r/b balance, exposure and whitebalance */
774static void setbalance(struct gspca_dev *gspca_dev)
698{ 775{
699 struct sd *sd = (struct sd *) gspca_dev; 776 struct sd *sd = (struct sd *) gspca_dev;
700 777
701 u8 white_balance[8] = 778 /* on whitebalance leave defaults values */
702 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38}; 779 if (sd->whitebalance) {
780 reg_w(gspca_dev, 0x3c80);
781 } else {
782 reg_w(gspca_dev, 0x3880);
783 /* shoud we wait here.. */
784 /* update and reset 'global gain' with webcam parameters */
785 sd->red_balance = reg_r(gspca_dev, 0x0087);
786 sd->blue_balance = reg_r(gspca_dev, 0x0088);
787 sd->global_gain = reg_r(gspca_dev, 0x0089);
788 setglobalgain(gspca_dev);
789 }
790
791}
792
703 793
704 if (sd->whitebalance)
705 white_balance[7] = 0x3c;
706 794
707 reg_w_buf(gspca_dev, white_balance, sizeof white_balance); 795static void setwhitebalance(struct gspca_dev *gspca_dev)
796{
797 setbalance(gspca_dev);
708} 798}
709 799
710static void setsharpness(struct gspca_dev *gspca_dev) 800static void setsharpness(struct gspca_dev *gspca_dev)
@@ -1018,6 +1108,66 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1018 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 1108 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1019} 1109}
1020 1110
1111
1112static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1113{
1114 struct sd *sd = (struct sd *) gspca_dev;
1115
1116 sd->blue_balance = val;
1117 if (gspca_dev->streaming)
1118 reg_w(gspca_dev, (val << 8) + 0x88);
1119 return 0;
1120}
1121
1122static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1123{
1124 struct sd *sd = (struct sd *) gspca_dev;
1125
1126 *val = sd->blue_balance;
1127 return 0;
1128}
1129
1130static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1131{
1132 struct sd *sd = (struct sd *) gspca_dev;
1133
1134 sd->red_balance = val;
1135 if (gspca_dev->streaming)
1136 reg_w(gspca_dev, (val << 8) + 0x87);
1137
1138 return 0;
1139}
1140
1141static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1142{
1143 struct sd *sd = (struct sd *) gspca_dev;
1144
1145 *val = sd->red_balance;
1146 return 0;
1147}
1148
1149
1150
1151static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val)
1152{
1153 struct sd *sd = (struct sd *) gspca_dev;
1154
1155 sd->global_gain = val;
1156 if (gspca_dev->streaming)
1157 setglobalgain(gspca_dev);
1158
1159 return 0;
1160}
1161
1162static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val)
1163{
1164 struct sd *sd = (struct sd *) gspca_dev;
1165
1166 *val = sd->global_gain;
1167 return 0;
1168}
1169
1170
1021static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1171static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1022{ 1172{
1023 struct sd *sd = (struct sd *) gspca_dev; 1173 struct sd *sd = (struct sd *) gspca_dev;