diff options
Diffstat (limited to 'drivers/media/video/gspca/t613.c')
-rw-r--r-- | drivers/media/video/gspca/t613.c | 172 |
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); | |||
70 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | 73 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); |
71 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | 74 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); |
72 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | 75 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); |
76 | |||
77 | |||
73 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); | 78 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); |
74 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); | 79 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); |
80 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
81 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
82 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
83 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
84 | static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val); | ||
85 | static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val); | ||
86 | |||
75 | static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val); | 87 | static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val); |
76 | static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val); | 88 | static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val); |
77 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); | 89 | static 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); | |||
79 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 91 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
80 | struct v4l2_querymenu *menu); | 92 | struct v4l2_querymenu *menu); |
81 | 93 | ||
94 | |||
82 | static const struct ctrl sd_ctrls[] = { | 95 | static 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 | ||
228 | static char *effects_control[] = { | 283 | static 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 | } |
764 | static void setglobalgain(struct gspca_dev *gspca_dev) | ||
765 | { | ||
696 | 766 | ||
697 | static 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 */ | ||
774 | static 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); | 795 | static void setwhitebalance(struct gspca_dev *gspca_dev) |
796 | { | ||
797 | setbalance(gspca_dev); | ||
708 | } | 798 | } |
709 | 799 | ||
710 | static void setsharpness(struct gspca_dev *gspca_dev) | 800 | static 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 | |||
1112 | static 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 | |||
1122 | static 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 | |||
1130 | static 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 | |||
1141 | static 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 | |||
1151 | static 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 | |||
1162 | static 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 | |||
1021 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 1171 | static 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; |