diff options
Diffstat (limited to 'drivers/media/video/gspca/sonixj.c')
-rw-r--r-- | drivers/media/video/gspca/sonixj.c | 287 |
1 files changed, 120 insertions, 167 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 33a3df1f6915..245a30ec5fb1 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | int avg_lum; | 35 | atomic_t avg_lum; |
36 | unsigned int exposure; | 36 | unsigned int exposure; |
37 | 37 | ||
38 | unsigned short brightness; | 38 | unsigned short brightness; |
@@ -148,55 +148,58 @@ static struct v4l2_pix_format vga_mode[] = { | |||
148 | 148 | ||
149 | /*Data from sn9c102p+hv71331r */ | 149 | /*Data from sn9c102p+hv71331r */ |
150 | static const __u8 sn_hv7131[] = { | 150 | static const __u8 sn_hv7131[] = { |
151 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | 151 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
152 | 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, | 152 | 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, |
153 | /* rega regb regc regd rege regf reg10 reg11 */ | 153 | /* reg8 reg9 rega regb regc regd rege regf */ |
154 | 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ | 154 | 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, |
155 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | 155 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
156 | 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, | 156 | 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, |
157 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | 157 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 158 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static const __u8 sn_mi0360[] = { | 161 | static const __u8 sn_mi0360[] = { |
162 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | 162 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
163 | 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, | 163 | 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, |
164 | /* rega regb regc regd rege regf reg10 reg11 */ | 164 | /* reg8 reg9 rega regb regc regd rege regf */ |
165 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, | 165 | 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, |
166 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | 166 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
167 | 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, | 167 | 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, |
168 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | 168 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 169 | 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
170 | }; | 170 | }; |
171 | 171 | ||
172 | static const __u8 sn_mo4000[] = { | 172 | static const __u8 sn_mo4000[] = { |
173 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | 173 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
174 | 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, | 174 | 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, |
175 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | 175 | /* reg8 reg9 rega regb regc regd rege regf */ |
176 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | 176 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
177 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | 177 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
178 | 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, | 178 | 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, |
179 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | 179 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, | 180 | 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
181 | 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7, | ||
182 | 0xd3, 0xdf, 0xea, 0xf5 | ||
183 | }; | 181 | }; |
184 | 182 | ||
185 | static const __u8 sn_ov7648[] = { | 183 | static const __u8 sn_ov7648[] = { |
186 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, | 184 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
187 | 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, | 185 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, |
188 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 | 186 | /* reg8 reg9 rega regb regc regd rege regf */ |
187 | 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10, | ||
188 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
189 | 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82, | ||
190 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ | ||
191 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
189 | }; | 192 | }; |
190 | 193 | ||
191 | static const __u8 sn_ov7660[] = { | 194 | static const __u8 sn_ov7660[] = { |
192 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | 195 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
193 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, | 196 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, |
194 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | 197 | /* reg8 reg9 rega regb regc regd rege regf */ |
195 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | 198 | 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, |
196 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | 199 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
197 | 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00, | 200 | 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, |
198 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | 201 | /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ |
199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 202 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
200 | }; | 203 | }; |
201 | 204 | ||
202 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ | 205 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ |
@@ -212,10 +215,6 @@ static const __u8 regsn20[] = { | |||
212 | 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, | 215 | 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, |
213 | 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff | 216 | 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff |
214 | }; | 217 | }; |
215 | static const __u8 regsn20_sn9c120[] = { | ||
216 | 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90, | ||
217 | 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff | ||
218 | }; | ||
219 | static const __u8 regsn20_sn9c325[] = { | 218 | static const __u8 regsn20_sn9c325[] = { |
220 | 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, | 219 | 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, |
221 | 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 | 220 | 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 |
@@ -227,21 +226,6 @@ static const __u8 reg84[] = { | |||
227 | /* 0x00, 0x00, 0x00, 0x00, 0x00 */ | 226 | /* 0x00, 0x00, 0x00, 0x00, 0x00 */ |
228 | 0xf7, 0x0f, 0x0a, 0x00, 0x00 | 227 | 0xf7, 0x0f, 0x0a, 0x00, 0x00 |
229 | }; | 228 | }; |
230 | static const __u8 reg84_sn9c120_1[] = { | ||
231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
233 | 0x00, 0x00, 0x0c, 0x00, 0x00 | ||
234 | }; | ||
235 | static const __u8 reg84_sn9c120_2[] = { | ||
236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
237 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
238 | 0x00, 0x00, 0x0c, 0x02, 0x3b | ||
239 | }; | ||
240 | static const __u8 reg84_sn9c120_3[] = { | ||
241 | 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f, | ||
242 | 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f, | ||
243 | 0xf5, 0x0f, 0x0c, 0x02, 0x3b | ||
244 | }; | ||
245 | static const __u8 reg84_sn9c325[] = { | 229 | static const __u8 reg84_sn9c325[] = { |
246 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, | 230 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, |
247 | 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, | 231 | 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, |
@@ -360,17 +344,15 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
360 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ | 344 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ |
361 | /* (delay 20ms) */ | 345 | /* (delay 20ms) */ |
362 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, | 346 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, |
363 | /* Outformat ?? rawRGB */ | 347 | /* Outformat = rawRGB */ |
364 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ | 348 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ |
365 | {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, | 349 | {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, |
366 | /* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */ | ||
367 | /* GAIN BLUE RED VREF */ | 350 | /* GAIN BLUE RED VREF */ |
368 | {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, | 351 | {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, |
369 | /* COM 1 BAVE GEAVE AECHH */ | 352 | /* COM 1 BAVE GEAVE AECHH */ |
370 | {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ | 353 | {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ |
371 | {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ | 354 | {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ |
372 | {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, | 355 | {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, |
373 | /* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */ | ||
374 | /* AECH CLKRC COM7 COM8 */ | 356 | /* AECH CLKRC COM7 COM8 */ |
375 | {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ | 357 | {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ |
376 | {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, | 358 | {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, |
@@ -379,8 +361,8 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
379 | {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ | 361 | {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ |
380 | {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, | 362 | {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, |
381 | /* BOS GBOS GROS ROS (BGGR offset) */ | 363 | /* BOS GBOS GROS ROS (BGGR offset) */ |
382 | {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, | 364 | /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */ |
383 | /* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */ | 365 | {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, |
384 | /* AEW AEB VPT BBIAS */ | 366 | /* AEW AEB VPT BBIAS */ |
385 | {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, | 367 | {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, |
386 | /* GbBIAS RSVD EXHCH EXHCL */ | 368 | /* GbBIAS RSVD EXHCH EXHCL */ |
@@ -407,9 +389,9 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
407 | {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, | 389 | {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, |
408 | /* LCC1 LCC2 LCC3 LCC4 */ | 390 | /* LCC1 LCC2 LCC3 LCC4 */ |
409 | {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ | 391 | {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ |
410 | {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, | 392 | {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */ |
411 | {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, | 393 | {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, |
412 | /* band gap reference [0..3] DBLV */ | 394 | /* band gap reference [0:3] DBLV */ |
413 | {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ | 395 | {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ |
414 | {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ | 396 | {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ |
415 | {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ | 397 | {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ |
@@ -419,37 +401,35 @@ static const __u8 ov7660_sensor_init[][8] = { | |||
419 | {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ | 401 | {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ |
420 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ | 402 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ |
421 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ | 403 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ |
422 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, | 404 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ |
423 | /****** (some exchanges in the win trace) ******/ | 405 | /****** (some exchanges in the win trace) ******/ |
424 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | 406 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ |
425 | /* bits[3..0]reserved */ | 407 | /* bits[3..0]reserved */ |
426 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | 408 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, |
427 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | 409 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, |
428 | /* VREF vertical frame ctrl */ | 410 | /* VREF vertical frame ctrl */ |
429 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | 411 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, |
430 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ | 412 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */ |
431 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, | 413 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */ |
432 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, | 414 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */ |
433 | /* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */ | 415 | {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */ |
434 | {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10}, | 416 | /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */ |
435 | {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, | ||
436 | /****** (some exchanges in the win trace) ******/ | 417 | /****** (some exchanges in the win trace) ******/ |
437 | {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ | 418 | {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ |
438 | {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ | 419 | {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */ |
439 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | 420 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */ |
440 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, | 421 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */ |
441 | {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, | 422 | /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */ |
442 | /****** (some exchanges in the win trace) ******/ | 423 | /****** (some exchanges in the win trace) ******/ |
443 | /**********startsensor KO if changed !!****/ | 424 | /******!! startsensor KO if changed !!****/ |
444 | {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, | 425 | {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, |
445 | {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, | 426 | {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, |
446 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | 427 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, |
447 | {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, | 428 | {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, |
448 | /* here may start the isoc exchanges */ | ||
449 | {} | 429 | {} |
450 | }; | 430 | }; |
451 | /* reg0x04 reg0x07 reg 0x10 */ | 431 | /* reg 0x04 reg 0x07 reg 0x10 */ |
452 | /* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ | 432 | /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */ |
453 | 433 | ||
454 | static const __u8 ov7648_sensor_init[][8] = { | 434 | static const __u8 ov7648_sensor_init[][8] = { |
455 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | 435 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, |
@@ -680,13 +660,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
680 | const __u8 *reg9a; | 660 | const __u8 *reg9a; |
681 | static const __u8 reg9a_def[] = | 661 | static const __u8 reg9a_def[] = |
682 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; | 662 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; |
683 | static const __u8 reg9a_sn9c120[] = /* from win trace */ | ||
684 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
685 | static const __u8 reg9a_sn9c325[] = | 663 | static const __u8 reg9a_sn9c325[] = |
686 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; | 664 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; |
665 | static const __u8 regd4[] = {0x60, 0x00, 0x00}; | ||
687 | 666 | ||
688 | reg_w1(gspca_dev, 0xf1, 0x00); | 667 | reg_w1(gspca_dev, 0xf1, 0x00); |
689 | reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/ | 668 | reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ |
690 | 669 | ||
691 | /* configure gpio */ | 670 | /* configure gpio */ |
692 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); | 671 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); |
@@ -696,25 +675,17 @@ static int configure_gpio(struct gspca_dev *gspca_dev, | |||
696 | case BRIDGE_SN9C325: | 675 | case BRIDGE_SN9C325: |
697 | reg9a = reg9a_sn9c325; | 676 | reg9a = reg9a_sn9c325; |
698 | break; | 677 | break; |
699 | case BRIDGE_SN9C120: | ||
700 | reg9a = reg9a_sn9c120; | ||
701 | break; | ||
702 | default: | 678 | default: |
703 | reg9a = reg9a_def; | 679 | reg9a = reg9a_def; |
704 | break; | 680 | break; |
705 | } | 681 | } |
706 | reg_w(gspca_dev, 0x9a, reg9a, 6); | 682 | reg_w(gspca_dev, 0x9a, reg9a, 6); |
707 | 683 | ||
708 | reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */ | 684 | reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/ |
709 | 685 | ||
710 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | 686 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); |
711 | 687 | ||
712 | switch (sd->bridge) { | 688 | switch (sd->bridge) { |
713 | case BRIDGE_SN9C120: /* from win trace */ | ||
714 | reg_w1(gspca_dev, 0x01, 0x61); | ||
715 | reg_w1(gspca_dev, 0x17, 0x20); | ||
716 | reg_w1(gspca_dev, 0x01, 0x60); | ||
717 | break; | ||
718 | case BRIDGE_SN9C325: | 689 | case BRIDGE_SN9C325: |
719 | reg_w1(gspca_dev, 0x01, 0x43); | 690 | reg_w1(gspca_dev, 0x01, 0x43); |
720 | reg_w1(gspca_dev, 0x17, 0xae); | 691 | reg_w1(gspca_dev, 0x17, 0xae); |
@@ -810,6 +781,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
810 | sd->contrast = CONTRAST_DEF; | 781 | sd->contrast = CONTRAST_DEF; |
811 | sd->colors = COLOR_DEF; | 782 | sd->colors = COLOR_DEF; |
812 | sd->autogain = AUTOGAIN_DEF; | 783 | sd->autogain = AUTOGAIN_DEF; |
784 | sd->ag_cnt = -1; | ||
785 | |||
813 | return 0; | 786 | return 0; |
814 | } | 787 | } |
815 | 788 | ||
@@ -823,10 +796,11 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
823 | 796 | ||
824 | /* setup a selector by bridge */ | 797 | /* setup a selector by bridge */ |
825 | reg_w1(gspca_dev, 0xf1, 0x01); | 798 | reg_w1(gspca_dev, 0xf1, 0x01); |
826 | reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */ | ||
827 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | ||
828 | reg_r(gspca_dev, 0x00, 1); | 799 | reg_r(gspca_dev, 0x00, 1); |
800 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | ||
801 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ | ||
829 | regF1 = gspca_dev->usb_buf[0]; | 802 | regF1 = gspca_dev->usb_buf[0]; |
803 | PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); | ||
830 | switch (sd->bridge) { | 804 | switch (sd->bridge) { |
831 | case BRIDGE_SN9C102P: | 805 | case BRIDGE_SN9C102P: |
832 | if (regF1 != 0x11) | 806 | if (regF1 != 0x11) |
@@ -937,15 +911,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
937 | sd->exposure = setexposure(gspca_dev, expo); | 911 | sd->exposure = setexposure(gspca_dev, expo); |
938 | break; | 912 | break; |
939 | case SENSOR_MI0360: | 913 | case SENSOR_MI0360: |
940 | expo = sd->brightness >> 4; | ||
941 | sd->exposure = setexposure(gspca_dev, expo); | ||
942 | break; | ||
943 | case SENSOR_MO4000: | 914 | case SENSOR_MO4000: |
944 | expo = sd->brightness >> 4; | 915 | expo = sd->brightness >> 4; |
945 | sd->exposure = setexposure(gspca_dev, expo); | 916 | sd->exposure = setexposure(gspca_dev, expo); |
946 | break; | 917 | break; |
947 | case SENSOR_OV7660: | ||
948 | return; /*jfm??*/ | ||
949 | } | 918 | } |
950 | 919 | ||
951 | k2 = sd->brightness >> 10; | 920 | k2 = sd->brightness >> 10; |
@@ -958,8 +927,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
958 | __u8 k2; | 927 | __u8 k2; |
959 | __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; | 928 | __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; |
960 | 929 | ||
961 | if (sd->sensor == SENSOR_OV7660) | ||
962 | return; /*jfm??*/ | ||
963 | k2 = sd->contrast; | 930 | k2 = sd->contrast; |
964 | contrast[2] = k2; | 931 | contrast[2] = k2; |
965 | contrast[0] = (k2 + 1) >> 1; | 932 | contrast[0] = (k2 + 1) >> 1; |
@@ -981,20 +948,32 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
981 | reg_w1(gspca_dev, 0x05, data); | 948 | reg_w1(gspca_dev, 0x05, data); |
982 | } | 949 | } |
983 | 950 | ||
951 | static void setautogain(struct gspca_dev *gspca_dev) | ||
952 | { | ||
953 | struct sd *sd = (struct sd *) gspca_dev; | ||
954 | |||
955 | switch (sd->sensor) { | ||
956 | case SENSOR_HV7131R: | ||
957 | case SENSOR_MO4000: | ||
958 | case SENSOR_MI0360: | ||
959 | if (sd->autogain) | ||
960 | sd->ag_cnt = AG_CNT_START; | ||
961 | else | ||
962 | sd->ag_cnt = -1; | ||
963 | break; | ||
964 | } | ||
965 | } | ||
966 | |||
984 | /* -- start the camera -- */ | 967 | /* -- start the camera -- */ |
985 | static void sd_start(struct gspca_dev *gspca_dev) | 968 | static void sd_start(struct gspca_dev *gspca_dev) |
986 | { | 969 | { |
987 | struct sd *sd = (struct sd *) gspca_dev; | 970 | struct sd *sd = (struct sd *) gspca_dev; |
988 | int i; | 971 | int i; |
989 | __u8 data; | 972 | __u8 reg1, reg17, reg18; |
990 | __u8 reg1; | ||
991 | __u8 reg17; | ||
992 | const __u8 *sn9c1xx; | 973 | const __u8 *sn9c1xx; |
993 | int mode; | 974 | int mode; |
994 | static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; | 975 | static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; |
995 | static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | 976 | static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; |
996 | static const __u8 CA_sn9c120[] = | ||
997 | { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ | ||
998 | static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ | 977 | static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ |
999 | static const __u8 CE_sn9c325[] = | 978 | static const __u8 CE_sn9c325[] = |
1000 | { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ | 979 | { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ |
@@ -1002,9 +981,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1002 | sn9c1xx = sn_tb[(int) sd->sensor]; | 981 | sn9c1xx = sn_tb[(int) sd->sensor]; |
1003 | configure_gpio(gspca_dev, sn9c1xx); | 982 | configure_gpio(gspca_dev, sn9c1xx); |
1004 | 983 | ||
1005 | /*fixme:jfm this sequence should appear at end of sd_start */ | 984 | /* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/ |
1006 | /* with | ||
1007 | reg_w1(gspca_dev, 0x01, 0x44); */ | ||
1008 | reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); | 985 | reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); |
1009 | reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); | 986 | reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); |
1010 | reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); | 987 | reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); |
@@ -1016,20 +993,16 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1016 | reg_w1(gspca_dev, 0xc7, 0x00); | 993 | reg_w1(gspca_dev, 0xc7, 0x00); |
1017 | reg_w1(gspca_dev, 0xc8, 0x50); | 994 | reg_w1(gspca_dev, 0xc8, 0x50); |
1018 | reg_w1(gspca_dev, 0xc9, 0x3c); | 995 | reg_w1(gspca_dev, 0xc9, 0x3c); |
1019 | /*fixme:jfm end of ending sequence */ | ||
1020 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); | 996 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); |
1021 | switch (sd->bridge) { | 997 | switch (sd->bridge) { |
1022 | case BRIDGE_SN9C325: | 998 | case BRIDGE_SN9C325: |
1023 | data = 0xae; | 999 | reg17 = 0xae; |
1024 | break; | ||
1025 | case BRIDGE_SN9C120: | ||
1026 | data = 0xa0; | ||
1027 | break; | 1000 | break; |
1028 | default: | 1001 | default: |
1029 | data = 0x60; | 1002 | reg17 = 0x60; |
1030 | break; | 1003 | break; |
1031 | } | 1004 | } |
1032 | reg_w1(gspca_dev, 0x17, data); | 1005 | reg_w1(gspca_dev, 0x17, reg17); |
1033 | reg_w1(gspca_dev, 0x05, sn9c1xx[5]); | 1006 | reg_w1(gspca_dev, 0x05, sn9c1xx[5]); |
1034 | reg_w1(gspca_dev, 0x07, sn9c1xx[7]); | 1007 | reg_w1(gspca_dev, 0x07, sn9c1xx[7]); |
1035 | reg_w1(gspca_dev, 0x06, sn9c1xx[6]); | 1008 | reg_w1(gspca_dev, 0x06, sn9c1xx[6]); |
@@ -1044,20 +1017,6 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1044 | reg_w1(gspca_dev, 0x9a, 0x0a); | 1017 | reg_w1(gspca_dev, 0x9a, 0x0a); |
1045 | reg_w1(gspca_dev, 0x99, 0x60); | 1018 | reg_w1(gspca_dev, 0x99, 0x60); |
1046 | break; | 1019 | break; |
1047 | case BRIDGE_SN9C120: | ||
1048 | reg_w(gspca_dev, 0x20, regsn20_sn9c120, | ||
1049 | sizeof regsn20_sn9c120); | ||
1050 | for (i = 0; i < 2; i++) | ||
1051 | reg_w(gspca_dev, 0x84, reg84_sn9c120_1, | ||
1052 | sizeof reg84_sn9c120_1); | ||
1053 | for (i = 0; i < 6; i++) | ||
1054 | reg_w(gspca_dev, 0x84, reg84_sn9c120_2, | ||
1055 | sizeof reg84_sn9c120_2); | ||
1056 | reg_w(gspca_dev, 0x84, reg84_sn9c120_3, | ||
1057 | sizeof reg84_sn9c120_3); | ||
1058 | reg_w1(gspca_dev, 0x9a, 0x05); | ||
1059 | reg_w1(gspca_dev, 0x99, 0x5b); | ||
1060 | break; | ||
1061 | default: | 1020 | default: |
1062 | reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); | 1021 | reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); |
1063 | for (i = 0; i < 8; i++) | 1022 | for (i = 0; i < 8; i++) |
@@ -1107,22 +1066,14 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1107 | /* reg1 = 0x44; */ | 1066 | /* reg1 = 0x44; */ |
1108 | /* reg1 = 0x46; (done) */ | 1067 | /* reg1 = 0x46; (done) */ |
1109 | } else { | 1068 | } else { |
1110 | reg17 = 0xa2; /* 640 */ | 1069 | reg17 = 0x22; /* 640 MCKSIZE */ |
1111 | reg1 = 0x40; | 1070 | reg1 = 0x06; |
1112 | } | 1071 | } |
1113 | break; | 1072 | break; |
1114 | } | 1073 | } |
1115 | reg_w(gspca_dev, 0xc0, C0, 6); | 1074 | reg_w(gspca_dev, 0xc0, C0, 6); |
1075 | reg_w(gspca_dev, 0xca, CA, 4); | ||
1116 | switch (sd->bridge) { | 1076 | switch (sd->bridge) { |
1117 | case BRIDGE_SN9C120: /*jfm ?? */ | ||
1118 | reg_w(gspca_dev, 0xca, CA_sn9c120, 4); | ||
1119 | break; | ||
1120 | default: | ||
1121 | reg_w(gspca_dev, 0xca, CA, 4); | ||
1122 | break; | ||
1123 | } | ||
1124 | switch (sd->bridge) { | ||
1125 | case BRIDGE_SN9C120: /*jfm ?? */ | ||
1126 | case BRIDGE_SN9C325: | 1077 | case BRIDGE_SN9C325: |
1127 | reg_w(gspca_dev, 0xce, CE_sn9c325, 4); | 1078 | reg_w(gspca_dev, 0xce, CE_sn9c325, 4); |
1128 | break; | 1079 | break; |
@@ -1133,19 +1084,19 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1133 | } | 1084 | } |
1134 | 1085 | ||
1135 | /* here change size mode 0 -> VGA; 1 -> CIF */ | 1086 | /* here change size mode 0 -> VGA; 1 -> CIF */ |
1136 | data = 0x40 | sn9c1xx[0x18] | (mode << 4); | 1087 | reg18 = sn9c1xx[0x18] | (mode << 4); |
1137 | reg_w1(gspca_dev, 0x18, data); | 1088 | reg_w1(gspca_dev, 0x18, reg18 | 0x40); |
1138 | 1089 | ||
1139 | reg_w(gspca_dev, 0x100, qtable4, 0x40); | 1090 | reg_w(gspca_dev, 0x100, qtable4, 0x40); |
1140 | reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); | 1091 | reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); |
1141 | 1092 | ||
1142 | data = sn9c1xx[0x18] | (mode << 4); | 1093 | reg_w1(gspca_dev, 0x18, reg18); |
1143 | reg_w1(gspca_dev, 0x18, data); | ||
1144 | 1094 | ||
1145 | reg_w1(gspca_dev, 0x17, reg17); | 1095 | reg_w1(gspca_dev, 0x17, reg17); |
1146 | reg_w1(gspca_dev, 0x01, reg1); | 1096 | reg_w1(gspca_dev, 0x01, reg1); |
1147 | setbrightness(gspca_dev); | 1097 | setbrightness(gspca_dev); |
1148 | setcontrast(gspca_dev); | 1098 | setcontrast(gspca_dev); |
1099 | setautogain(gspca_dev); | ||
1149 | } | 1100 | } |
1150 | 1101 | ||
1151 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1102 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -1168,12 +1119,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1168 | i2c_w8(gspca_dev, stopmi0360); | 1119 | i2c_w8(gspca_dev, stopmi0360); |
1169 | data = 0x29; | 1120 | data = 0x29; |
1170 | break; | 1121 | break; |
1171 | case SENSOR_MO4000: | ||
1172 | break; | ||
1173 | case SENSOR_OV7648: | 1122 | case SENSOR_OV7648: |
1174 | data = 0x29; | 1123 | data = 0x29; |
1175 | break; | 1124 | break; |
1176 | default: | 1125 | default: |
1126 | /* case SENSOR_MO4000: */ | ||
1177 | /* case SENSOR_OV7660: */ | 1127 | /* case SENSOR_OV7660: */ |
1178 | break; | 1128 | break; |
1179 | } | 1129 | } |
@@ -1193,16 +1143,23 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
1193 | { | 1143 | { |
1194 | } | 1144 | } |
1195 | 1145 | ||
1196 | static void setautogain(struct gspca_dev *gspca_dev) | 1146 | static void do_autogain(struct gspca_dev *gspca_dev) |
1197 | { | 1147 | { |
1198 | struct sd *sd = (struct sd *) gspca_dev; | 1148 | struct sd *sd = (struct sd *) gspca_dev; |
1199 | /* Thanks S., without your advice, autobright should not work :) */ | ||
1200 | int delta; | 1149 | int delta; |
1201 | int expotimes = 0; | 1150 | int expotimes; |
1202 | __u8 luma_mean = 130; | 1151 | __u8 luma_mean = 130; |
1203 | __u8 luma_delta = 20; | 1152 | __u8 luma_delta = 20; |
1204 | 1153 | ||
1205 | delta = sd->avg_lum; | 1154 | /* Thanks S., without your advice, autobright should not work :) */ |
1155 | if (sd->ag_cnt < 0) | ||
1156 | return; | ||
1157 | if (--sd->ag_cnt >= 0) | ||
1158 | return; | ||
1159 | sd->ag_cnt = AG_CNT_START; | ||
1160 | |||
1161 | delta = atomic_read(&sd->avg_lum); | ||
1162 | PDEBUG(D_FRAM, "mean lum %d", delta); | ||
1206 | if (delta < luma_mean - luma_delta || | 1163 | if (delta < luma_mean - luma_delta || |
1207 | delta > luma_mean + luma_delta) { | 1164 | delta > luma_mean + luma_delta) { |
1208 | switch (sd->sensor) { | 1165 | switch (sd->sensor) { |
@@ -1214,8 +1171,9 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
1214 | sd->exposure = setexposure(gspca_dev, | 1171 | sd->exposure = setexposure(gspca_dev, |
1215 | (unsigned int) (expotimes << 8)); | 1172 | (unsigned int) (expotimes << 8)); |
1216 | break; | 1173 | break; |
1217 | case SENSOR_MO4000: | 1174 | default: |
1218 | case SENSOR_MI0360: | 1175 | /* case SENSOR_MO4000: */ |
1176 | /* case SENSOR_MI0360: */ | ||
1219 | expotimes = sd->exposure; | 1177 | expotimes = sd->exposure; |
1220 | expotimes += (luma_mean - delta) >> 6; | 1178 | expotimes += (luma_mean - delta) >> 6; |
1221 | if (expotimes < 0) | 1179 | if (expotimes < 0) |
@@ -1228,6 +1186,8 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
1228 | } | 1186 | } |
1229 | } | 1187 | } |
1230 | 1188 | ||
1189 | /* scan the URB packets */ | ||
1190 | /* This function is run at interrupt level. */ | ||
1231 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1191 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
1232 | struct gspca_frame *frame, /* target */ | 1192 | struct gspca_frame *frame, /* target */ |
1233 | __u8 *data, /* isoc packet */ | 1193 | __u8 *data, /* isoc packet */ |
@@ -1244,9 +1204,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1244 | frame, data, sof + 2); | 1204 | frame, data, sof + 2); |
1245 | if (sd->ag_cnt < 0) | 1205 | if (sd->ag_cnt < 0) |
1246 | return; | 1206 | return; |
1247 | if (--sd->ag_cnt >= 0) | ||
1248 | return; | ||
1249 | sd->ag_cnt = AG_CNT_START; | ||
1250 | /* w1 w2 w3 */ | 1207 | /* w1 w2 w3 */ |
1251 | /* w4 w5 w6 */ | 1208 | /* w4 w5 w6 */ |
1252 | /* w7 w8 */ | 1209 | /* w7 w8 */ |
@@ -1261,9 +1218,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1261 | /* w5 */ | 1218 | /* w5 */ |
1262 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; | 1219 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; |
1263 | avg_lum >>= 4; | 1220 | avg_lum >>= 4; |
1264 | sd->avg_lum = avg_lum; | 1221 | atomic_set(&sd->avg_lum, avg_lum); |
1265 | PDEBUG(D_PACK, "mean lum %d", avg_lum); | ||
1266 | setautogain(gspca_dev); | ||
1267 | return; | 1222 | return; |
1268 | } | 1223 | } |
1269 | if (gspca_dev->last_packet_type == LAST_PACKET) { | 1224 | if (gspca_dev->last_packet_type == LAST_PACKET) { |
@@ -1300,6 +1255,7 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) | |||
1300 | (hexpo << 10) | (mexpo << 2) | lexpo); | 1255 | (hexpo << 10) | (mexpo << 2) | lexpo); |
1301 | return (hexpo << 10) | (mexpo << 2) | lexpo; | 1256 | return (hexpo << 10) | (mexpo << 2) | lexpo; |
1302 | default: | 1257 | default: |
1258 | /* case SENSOR_OV7648: * jfm: is it ok for 7648? */ | ||
1303 | /* case SENSOR_OV7660: */ | 1259 | /* case SENSOR_OV7660: */ |
1304 | /* read sensor exposure */ | 1260 | /* read sensor exposure */ |
1305 | i2c_r5(gspca_dev, 0x04); | 1261 | i2c_r5(gspca_dev, 0x04); |
@@ -1318,14 +1274,12 @@ static void getbrightness(struct gspca_dev *gspca_dev) | |||
1318 | /* hardcoded registers seem not readable */ | 1274 | /* hardcoded registers seem not readable */ |
1319 | switch (sd->sensor) { | 1275 | switch (sd->sensor) { |
1320 | case SENSOR_HV7131R: | 1276 | case SENSOR_HV7131R: |
1321 | /* sd->brightness = 0x7fff; */ | ||
1322 | sd->brightness = getexposure(gspca_dev) >> 4; | 1277 | sd->brightness = getexposure(gspca_dev) >> 4; |
1323 | break; | 1278 | break; |
1324 | case SENSOR_MI0360: | 1279 | case SENSOR_MI0360: |
1325 | sd->brightness = getexposure(gspca_dev) << 4; | 1280 | sd->brightness = getexposure(gspca_dev) << 4; |
1326 | break; | 1281 | break; |
1327 | case SENSOR_MO4000: | 1282 | case SENSOR_MO4000: |
1328 | /* sd->brightness = 0x1fff; */ | ||
1329 | sd->brightness = getexposure(gspca_dev) << 4; | 1283 | sd->brightness = getexposure(gspca_dev) << 4; |
1330 | break; | 1284 | break; |
1331 | } | 1285 | } |
@@ -1391,10 +1345,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
1391 | struct sd *sd = (struct sd *) gspca_dev; | 1345 | struct sd *sd = (struct sd *) gspca_dev; |
1392 | 1346 | ||
1393 | sd->autogain = val; | 1347 | sd->autogain = val; |
1394 | if (val) | 1348 | if (gspca_dev->streaming) |
1395 | sd->ag_cnt = AG_CNT_START; | 1349 | setautogain(gspca_dev); |
1396 | else | ||
1397 | sd->ag_cnt = -1; | ||
1398 | return 0; | 1350 | return 0; |
1399 | } | 1351 | } |
1400 | 1352 | ||
@@ -1418,6 +1370,7 @@ static const struct sd_desc sd_desc = { | |||
1418 | .stop0 = sd_stop0, | 1370 | .stop0 = sd_stop0, |
1419 | .close = sd_close, | 1371 | .close = sd_close, |
1420 | .pkt_scan = sd_pkt_scan, | 1372 | .pkt_scan = sd_pkt_scan, |
1373 | .dq_callback = do_autogain, | ||
1421 | }; | 1374 | }; |
1422 | 1375 | ||
1423 | /* -- module initialisation -- */ | 1376 | /* -- module initialisation -- */ |