aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2010-06-05 06:07:56 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-02 13:44:18 -0400
commite9b156532ec4d3c0a248ec958a8378f769297fcd (patch)
treea8090a33105ce396c1fa66aba6bf495b48803e72 /drivers
parentebb78c5a81e0f4c85f6d9e1b0d11ede7adb530b3 (diff)
V4L/DVB: gspca - t613: Change the gain mechanism
- variable / function rename - set the gains in one exchange - don't alter the register 80 which contains the AWB flag and other sensor specific values - the global gain is now the average of the R, G and B gains. Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/t613.c159
1 files changed, 97 insertions, 62 deletions
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index d9618341ce84..4e8df337bc83 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -46,9 +46,9 @@ struct sd {
46 u8 gamma; 46 u8 gamma;
47 u8 sharpness; 47 u8 sharpness;
48 u8 freq; 48 u8 freq;
49 u8 red_balance; /* split balance */ 49 u8 red_gain;
50 u8 blue_balance; 50 u8 blue_gain;
51 u8 global_gain; /* aka gain */ 51 u8 green_gain;
52 u8 awb; /* set default r/g/b and activate */ 52 u8 awb; /* set default r/g/b and activate */
53 u8 mirror; 53 u8 mirror;
54 u8 effect; 54 u8 effect;
@@ -80,12 +80,12 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
80 80
81static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); 81static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); 82static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); 83static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); 84static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); 85static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); 86static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val); 87static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val); 88static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
89 89
90static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val); 90static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val); 91static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val);
@@ -246,11 +246,11 @@ static const struct ctrl sd_ctrls[] = {
246 .minimum = 0x10, 246 .minimum = 0x10,
247 .maximum = 0x40, 247 .maximum = 0x40,
248 .step = 1, 248 .step = 1,
249#define BLUE_BALANCE_DEF 0x20 249#define BLUE_GAIN_DEF 0x20
250 .default_value = BLUE_BALANCE_DEF, 250 .default_value = BLUE_GAIN_DEF,
251 }, 251 },
252 .set = sd_setblue_balance, 252 .set = sd_setblue_gain,
253 .get = sd_getblue_balance, 253 .get = sd_getblue_gain,
254 }, 254 },
255 { 255 {
256 { 256 {
@@ -260,11 +260,11 @@ static const struct ctrl sd_ctrls[] = {
260 .minimum = 0x10, 260 .minimum = 0x10,
261 .maximum = 0x40, 261 .maximum = 0x40,
262 .step = 1, 262 .step = 1,
263#define RED_BALANCE_DEF 0x20 263#define RED_GAIN_DEF 0x20
264 .default_value = RED_BALANCE_DEF, 264 .default_value = RED_GAIN_DEF,
265 }, 265 },
266 .set = sd_setred_balance, 266 .set = sd_setred_gain,
267 .get = sd_getred_balance, 267 .get = sd_getred_gain,
268 }, 268 },
269 { 269 {
270 { 270 {
@@ -274,11 +274,11 @@ static const struct ctrl sd_ctrls[] = {
274 .minimum = 0x10, 274 .minimum = 0x10,
275 .maximum = 0x40, 275 .maximum = 0x40,
276 .step = 1, 276 .step = 1,
277#define global_gain_DEF 0x20 277#define GAIN_DEF 0x20
278 .default_value = global_gain_DEF, 278 .default_value = GAIN_DEF,
279 }, 279 },
280 .set = sd_setglobal_gain, 280 .set = sd_setgain,
281 .get = sd_getglobal_gain, 281 .get = sd_getgain,
282 }, 282 },
283}; 283};
284 284
@@ -699,9 +699,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
699 sd->awb = AWB_DEF; 699 sd->awb = AWB_DEF;
700 sd->sharpness = SHARPNESS_DEF; 700 sd->sharpness = SHARPNESS_DEF;
701 sd->effect = EFFECTS_DEF; 701 sd->effect = EFFECTS_DEF;
702 sd->red_balance = RED_BALANCE_DEF; 702 sd->red_gain = RED_GAIN_DEF;
703 sd->blue_balance = BLUE_BALANCE_DEF; 703 sd->blue_gain = BLUE_GAIN_DEF;
704 sd->global_gain = global_gain_DEF; 704 sd->green_gain = GAIN_DEF * 3 - RED_GAIN_DEF - BLUE_GAIN_DEF;
705 705
706 return 0; 706 return 0;
707} 707}
@@ -754,33 +754,59 @@ static void setgamma(struct gspca_dev *gspca_dev)
754 reg_w_ixbuf(gspca_dev, 0x90, 754 reg_w_ixbuf(gspca_dev, 0x90,
755 gamma_table[sd->gamma], sizeof gamma_table[0]); 755 gamma_table[sd->gamma], sizeof gamma_table[0]);
756} 756}
757static void setglobalgain(struct gspca_dev *gspca_dev)
758{
759 757
758static void setRGB(struct gspca_dev *gspca_dev)
759{
760 struct sd *sd = (struct sd *) gspca_dev; 760 struct sd *sd = (struct sd *) gspca_dev;
761 reg_w(gspca_dev, (sd->red_balance << 8) + 0x87); 761 u8 all_gain_reg[6] =
762 reg_w(gspca_dev, (sd->blue_balance << 8) + 0x88); 762 {0x87, 0x00, 0x88, 0x00, 0x89, 0x00};
763 reg_w(gspca_dev, (sd->global_gain << 8) + 0x89); 763
764 all_gain_reg[1] = sd->red_gain;
765 all_gain_reg[3] = sd->blue_gain;
766 all_gain_reg[5] = sd->green_gain;
767 reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
764} 768}
765 769
766/* Generic fnc for r/b balance, exposure and whitebalance */ 770/* Generic fnc for r/b balance, exposure and awb */
767static void setawb(struct gspca_dev *gspca_dev) 771static void setawb(struct gspca_dev *gspca_dev)
768{ 772{
769 struct sd *sd = (struct sd *) gspca_dev; 773 struct sd *sd = (struct sd *) gspca_dev;
774 u16 reg80;
775
776 reg80 = (sensor_data[sd->sensor].reg80 << 8) | 0x80;
770 777
771 /* on awb leave defaults values */ 778 /* on awb leave defaults values */
772 if (sd->awb) { 779 if (!sd->awb) {
773 reg_w(gspca_dev, 0x3c80);
774 } else {
775 reg_w(gspca_dev, 0x3880);
776 /* shoud we wait here.. */ 780 /* shoud we wait here.. */
777 /* update and reset 'global gain' with webcam parameters */ 781 /* update and reset RGB gains with webcam values */
778 sd->red_balance = reg_r(gspca_dev, 0x0087); 782 sd->red_gain = reg_r(gspca_dev, 0x0087);
779 sd->blue_balance = reg_r(gspca_dev, 0x0088); 783 sd->blue_gain = reg_r(gspca_dev, 0x0088);
780 sd->global_gain = reg_r(gspca_dev, 0x0089); 784 sd->green_gain = reg_r(gspca_dev, 0x0089);
781 setglobalgain(gspca_dev); 785 reg80 &= ~0x0400; /* AWB off */
782 } 786 }
787 reg_w(gspca_dev, reg80);
788 reg_w(gspca_dev, reg80);
789}
783 790
791static void init_gains(struct gspca_dev *gspca_dev)
792{
793 struct sd *sd = (struct sd *) gspca_dev;
794 u16 reg80;
795 u8 all_gain_reg[8] =
796 {0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00};
797
798 all_gain_reg[1] = sd->red_gain;
799 all_gain_reg[3] = sd->blue_gain;
800 all_gain_reg[5] = sd->green_gain;
801 reg80 = sensor_data[sd->sensor].reg80;
802 if (!sd->awb)
803 reg80 &= ~0x04;
804 all_gain_reg[7] = reg80;
805 reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
806
807 reg_w(gspca_dev, (sd->red_gain << 8) + 0x87);
808 reg_w(gspca_dev, (sd->blue_gain << 8) + 0x88);
809 reg_w(gspca_dev, (sd->green_gain << 8) + 0x89);
784} 810}
785 811
786static void setsharpness(struct gspca_dev *gspca_dev) 812static void setsharpness(struct gspca_dev *gspca_dev)
@@ -919,14 +945,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
919 setgamma(gspca_dev); 945 setgamma(gspca_dev);
920 setcolors(gspca_dev); 946 setcolors(gspca_dev);
921 setsharpness(gspca_dev); 947 setsharpness(gspca_dev);
922 setawb(gspca_dev); 948 init_gains(gspca_dev);
923 setfreq(gspca_dev); 949 setfreq(gspca_dev);
924 950
925 reg_w(gspca_dev, 0x2087); /* tied to white balance? */
926 reg_w(gspca_dev, 0x2088);
927 reg_w(gspca_dev, 0x2089);
928
929 reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
930 reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5); 951 reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
931 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); 952 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
932 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); 953 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
@@ -1099,62 +1120,76 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1099 gspca_frame_add(gspca_dev, pkt_type, data, len); 1120 gspca_frame_add(gspca_dev, pkt_type, data, len);
1100} 1121}
1101 1122
1102 1123static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val)
1103static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1104{ 1124{
1105 struct sd *sd = (struct sd *) gspca_dev; 1125 struct sd *sd = (struct sd *) gspca_dev;
1106 1126
1107 sd->blue_balance = val; 1127 sd->blue_gain = val;
1108 if (gspca_dev->streaming) 1128 if (gspca_dev->streaming)
1109 reg_w(gspca_dev, (val << 8) + 0x88); 1129 reg_w(gspca_dev, (val << 8) + 0x88);
1110 return 0; 1130 return 0;
1111} 1131}
1112 1132
1113static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val) 1133static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val)
1114{ 1134{
1115 struct sd *sd = (struct sd *) gspca_dev; 1135 struct sd *sd = (struct sd *) gspca_dev;
1116 1136
1117 *val = sd->blue_balance; 1137 *val = sd->blue_gain;
1118 return 0; 1138 return 0;
1119} 1139}
1120 1140
1121static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val) 1141static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val)
1122{ 1142{
1123 struct sd *sd = (struct sd *) gspca_dev; 1143 struct sd *sd = (struct sd *) gspca_dev;
1124 1144
1125 sd->red_balance = val; 1145 sd->red_gain = val;
1126 if (gspca_dev->streaming) 1146 if (gspca_dev->streaming)
1127 reg_w(gspca_dev, (val << 8) + 0x87); 1147 reg_w(gspca_dev, (val << 8) + 0x87);
1128 1148
1129 return 0; 1149 return 0;
1130} 1150}
1131 1151
1132static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) 1152static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val)
1133{ 1153{
1134 struct sd *sd = (struct sd *) gspca_dev; 1154 struct sd *sd = (struct sd *) gspca_dev;
1135 1155
1136 *val = sd->red_balance; 1156 *val = sd->red_gain;
1137 return 0; 1157 return 0;
1138} 1158}
1139 1159
1140 1160static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1141
1142static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val)
1143{ 1161{
1144 struct sd *sd = (struct sd *) gspca_dev; 1162 struct sd *sd = (struct sd *) gspca_dev;
1163 u16 psg, nsg;
1164
1165 psg = sd->red_gain + sd->blue_gain + sd->green_gain;
1166 nsg = val * 3;
1167 sd->red_gain = sd->red_gain * nsg / psg;
1168 if (sd->red_gain > 0x40)
1169 sd->red_gain = 0x40;
1170 else if (sd->red_gain < 0x10)
1171 sd->red_gain = 0x10;
1172 sd->blue_gain = sd->blue_gain * nsg / psg;
1173 if (sd->blue_gain > 0x40)
1174 sd->blue_gain = 0x40;
1175 else if (sd->blue_gain < 0x10)
1176 sd->blue_gain = 0x10;
1177 sd->green_gain = sd->green_gain * nsg / psg;
1178 if (sd->green_gain > 0x40)
1179 sd->green_gain = 0x40;
1180 else if (sd->green_gain < 0x10)
1181 sd->green_gain = 0x10;
1145 1182
1146 sd->global_gain = val;
1147 if (gspca_dev->streaming) 1183 if (gspca_dev->streaming)
1148 setglobalgain(gspca_dev); 1184 setRGB(gspca_dev);
1149
1150 return 0; 1185 return 0;
1151} 1186}
1152 1187
1153static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val) 1188static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1154{ 1189{
1155 struct sd *sd = (struct sd *) gspca_dev; 1190 struct sd *sd = (struct sd *) gspca_dev;
1156 1191
1157 *val = sd->global_gain; 1192 *val = (sd->red_gain + sd->blue_gain + sd->green_gain) / 3;
1158 return 0; 1193 return 0;
1159} 1194}
1160 1195