diff options
author | Jean-François Moine <moinejf@free.fr> | 2010-06-05 06:07:56 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-02 13:44:18 -0400 |
commit | e9b156532ec4d3c0a248ec958a8378f769297fcd (patch) | |
tree | a8090a33105ce396c1fa66aba6bf495b48803e72 /drivers | |
parent | ebb78c5a81e0f4c85f6d9e1b0d11ede7adb530b3 (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.c | 159 |
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 | ||
81 | static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); | 81 | static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); |
82 | static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); | 82 | static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); |
83 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); | 83 | static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val); |
84 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); | 84 | static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val); |
85 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); | 85 | static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val); |
86 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); | 86 | static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val); |
87 | static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val); | 87 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); |
88 | static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val); | 88 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); |
89 | 89 | ||
90 | static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val); | 90 | static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val); |
91 | static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val); | 91 | static 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 | } |
757 | static void setglobalgain(struct gspca_dev *gspca_dev) | ||
758 | { | ||
759 | 757 | ||
758 | static 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 */ |
767 | static void setawb(struct gspca_dev *gspca_dev) | 771 | static 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 | ||
791 | static 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 | ||
786 | static void setsharpness(struct gspca_dev *gspca_dev) | 812 | static 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 | 1123 | static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val) | |
1103 | static 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 | ||
1113 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 1133 | static 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 | ||
1121 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val) | 1141 | static 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 | ||
1132 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) | 1152 | static 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 | 1160 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | |
1141 | |||
1142 | static 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 | ||
1153 | static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val) | 1188 | static 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 | ||