diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2009-01-16 14:24:28 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:32 -0400 |
commit | 0dbc2c1674b346ff22f729af14efa4822f81325c (patch) | |
tree | 9ea29bd7e009616914fc07e280de1a5ac7121627 /drivers/media/video/gspca/spca561.c | |
parent | 576ed7b5696b9435e8e6a6ec0c57da1f19c7e469 (diff) |
V4L/DVB (10368): gspca - spca561: Fix bugs and rewrite the init/start of the rev72a.
The bugs were in the first init sequence of the sensor.
The rewrite is adapted from a ms-win trace.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/spca561.c')
-rw-r--r-- | drivers/media/video/gspca/spca561.c | 168 |
1 files changed, 42 insertions, 126 deletions
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 386aaec3e6e1..c99fe0f904fe 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -145,33 +145,34 @@ static const struct v4l2_pix_format sif_072a_mode[] = { | |||
145 | #define SPCA561_SNAPBIT 0x20 | 145 | #define SPCA561_SNAPBIT 0x20 |
146 | #define SPCA561_SNAPCTRL 0x40 | 146 | #define SPCA561_SNAPCTRL 0x40 |
147 | 147 | ||
148 | static const __u16 rev72a_init_data1[][2] = { | 148 | static const u16 rev72a_reset[][2] = { |
149 | {0x0000, 0x8114}, /* Software GPIO output data */ | 149 | {0x0000, 0x8114}, /* Software GPIO output data */ |
150 | {0x0001, 0x8114}, /* Software GPIO output data */ | 150 | {0x0001, 0x8114}, /* Software GPIO output data */ |
151 | {0x0000, 0x8112}, /* Some kind of reset */ | 151 | {0x0000, 0x8112}, /* Some kind of reset */ |
152 | {} | ||
153 | }; | ||
154 | static const __u16 rev72a_init_data1[][2] = { | ||
152 | {0x0003, 0x8701}, /* PCLK clock delay adjustment */ | 155 | {0x0003, 0x8701}, /* PCLK clock delay adjustment */ |
153 | {0x0001, 0x8703}, /* HSYNC from cmos inverted */ | 156 | {0x0001, 0x8703}, /* HSYNC from cmos inverted */ |
154 | {0x0011, 0x8118}, /* Enable and conf sensor */ | 157 | {0x0011, 0x8118}, /* Enable and conf sensor */ |
155 | {0x0001, 0x8118}, /* Conf sensor */ | 158 | {0x0001, 0x8118}, /* Conf sensor */ |
156 | {0x0092, 0x8804}, /* I know nothing about these */ | 159 | {0x0092, 0x8804}, /* I know nothing about these */ |
157 | {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ | 160 | {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ |
158 | {0x000d, 0x8805}, /* sensor default setting */ | ||
159 | {} | 161 | {} |
160 | }; | 162 | }; |
161 | static const __u16 rev72a_init_sensor1[][2] = { | 163 | static const u16 rev72a_init_sensor1[][2] = { |
162 | /* ms-win values */ | 164 | {0x0001, 0x000d}, |
163 | {0x0001, 0x0018}, /* 0x01 <- 0x0d */ | 165 | {0x0002, 0x0018}, |
164 | {0x0002, 0x0065}, /* 0x02 <- 0x18 */ | 166 | {0x0004, 0x0165}, |
165 | {0x0004, 0x0121}, /* 0x04 <- 0x0165 */ | 167 | {0x0005, 0x0021}, |
166 | {0x0005, 0x00aa}, /* 0x05 <- 0x21 */ | 168 | {0x0007, 0x00aa}, |
167 | {0x0007, 0x0004}, /* 0x07 <- 0xaa */ | 169 | {0x0020, 0x1504}, |
168 | {0x0020, 0x1502}, /* 0x20 <- 0x1504 */ | 170 | {0x0039, 0x0002}, |
169 | {0x0039, 0x0010}, /* 0x39 <- 0x02 */ | 171 | {0x0035, 0x0010}, |
170 | {0x0035, 0x0049}, /* 0x35 <- 0x10 */ | 172 | {0x0009, 0x1049}, |
171 | {0x0009, 0x100b}, /* 0x09 <- 0x1049 */ | 173 | {0x0028, 0x000b}, |
172 | {0x0028, 0x000f}, /* 0x28 <- 0x0b */ | 174 | {0x003b, 0x000f}, |
173 | {0x003b, 0x003c}, /* 0x3b <- 0x0f */ | 175 | {0x003c, 0x0000}, |
174 | {0x003c, 0x0000}, /* 0x3c <- 0x00 */ | ||
175 | {} | 176 | {} |
176 | }; | 177 | }; |
177 | static const __u16 rev72a_init_data2[][2] = { | 178 | static const __u16 rev72a_init_data2[][2] = { |
@@ -189,15 +190,10 @@ static const __u16 rev72a_init_data2[][2] = { | |||
189 | {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ | 190 | {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ |
190 | {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ | 191 | {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ |
191 | {0x0001, 0x8200}, /* OprMode to be executed by hardware */ | 192 | {0x0001, 0x8200}, /* OprMode to be executed by hardware */ |
192 | {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */ | 193 | /* from ms-win */ |
193 | {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ | 194 | {0x0000, 0x8611}, /* R offset for white balance */ |
194 | {0x0001, 0x8200}, /* OprMode to be executed by hardware */ | 195 | {0x00fd, 0x8612}, /* Gr offset for white balance */ |
195 | {0x0010, 0x8660}, /* Compensation memory stuff */ | 196 | {0x0003, 0x8613}, /* B offset for white balance */ |
196 | {0x0018, 0x8660}, /* Compensation memory stuff */ | ||
197 | |||
198 | {0x0004, 0x8611}, /* R offset for white balance */ | ||
199 | {0x0004, 0x8612}, /* Gr offset for white balance */ | ||
200 | {0x0007, 0x8613}, /* B offset for white balance */ | ||
201 | {0x0000, 0x8614}, /* Gb offset for white balance */ | 197 | {0x0000, 0x8614}, /* Gb offset for white balance */ |
202 | /* from ms-win */ | 198 | /* from ms-win */ |
203 | {0x0035, 0x8651}, /* R gain for white balance */ | 199 | {0x0035, 0x8651}, /* R gain for white balance */ |
@@ -205,8 +201,8 @@ static const __u16 rev72a_init_data2[][2] = { | |||
205 | {0x005f, 0x8653}, /* B gain for white balance */ | 201 | {0x005f, 0x8653}, /* B gain for white balance */ |
206 | {0x0040, 0x8654}, /* Gb gain for white balance */ | 202 | {0x0040, 0x8654}, /* Gb gain for white balance */ |
207 | {0x0002, 0x8502}, /* Maximum average bit rate stuff */ | 203 | {0x0002, 0x8502}, /* Maximum average bit rate stuff */ |
208 | |||
209 | {0x0011, 0x8802}, | 204 | {0x0011, 0x8802}, |
205 | |||
210 | {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ | 206 | {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ |
211 | {0x0081, 0x8702}, /* Master clock output enable */ | 207 | {0x0081, 0x8702}, /* Master clock output enable */ |
212 | 208 | ||
@@ -217,104 +213,15 @@ static const __u16 rev72a_init_data2[][2] = { | |||
217 | {0x0003, 0x865c}, /* Vertical offset for valid lines */ | 213 | {0x0003, 0x865c}, /* Vertical offset for valid lines */ |
218 | {} | 214 | {} |
219 | }; | 215 | }; |
220 | static const __u16 rev72a_init_sensor2[][2] = { | 216 | static const u16 rev72a_init_sensor2[][2] = { |
221 | /* ms-win values */ | 217 | {0x0003, 0x0121}, |
222 | {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */ | 218 | {0x0004, 0x0165}, |
223 | {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */ | 219 | {0x0005, 0x002f}, /* blanking control column */ |
224 | {0x0005, 0x002f}, /* 0x05 <- 0x2f */ | 220 | {0x0006, 0x0000}, /* blanking mode row*/ |
225 | {0x0006, 0x0000}, /* 0x06 <- 0 */ | 221 | {0x000a, 0x0002}, |
226 | {0x000a, 0x0002}, /* 0x0a <- 2 */ | 222 | {0x0009, 0x1061}, /* setexposure times && pixel clock |
227 | {0x0009, 0x1061}, /* 0x09 <- 0x1061 */ | ||
228 | {0x0035, 0x0014}, /* 0x35 <- 0x14 */ | ||
229 | {} | ||
230 | }; | ||
231 | static const __u16 rev72a_init_data3[][2] = { | ||
232 | {0x0030, 0x8112}, /* ISO and drop packet enable */ | ||
233 | /*fixme: should stop here*/ | ||
234 | {0x0000, 0x8112}, /* Some kind of reset ???? */ | ||
235 | {0x0009, 0x8118}, /* Enable sensor and set standby */ | ||
236 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
237 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
238 | {0x0001, 0x8114}, /* Software GPIO output data */ | ||
239 | {0x0000, 0x8112}, /* Some kind of reset ??? */ | ||
240 | {0x0003, 0x8701}, | ||
241 | {0x0001, 0x8703}, | ||
242 | {0x0011, 0x8118}, | ||
243 | {0x0001, 0x8118}, | ||
244 | /***************/ | ||
245 | {0x0092, 0x8804}, | ||
246 | {0x0010, 0x8802}, | ||
247 | {0x000d, 0x8805}, | ||
248 | {0x0001, 0x8801}, | ||
249 | {0x0000, 0x8800}, | ||
250 | {0x0018, 0x8805}, | ||
251 | {0x0002, 0x8801}, | ||
252 | {0x0000, 0x8800}, | ||
253 | {0x0065, 0x8805}, | ||
254 | {0x0004, 0x8801}, | ||
255 | {0x0001, 0x8800}, | ||
256 | {0x0021, 0x8805}, | ||
257 | {0x0005, 0x8801}, | ||
258 | {0x0000, 0x8800}, | ||
259 | {0x00aa, 0x8805}, | ||
260 | {0x0007, 0x8801}, /* mode 0xaa */ | ||
261 | {0x0000, 0x8800}, | ||
262 | {0x0004, 0x8805}, | ||
263 | {0x0020, 0x8801}, | ||
264 | {0x0015, 0x8800}, /* mode 0x0415 */ | ||
265 | {0x0002, 0x8805}, | ||
266 | {0x0039, 0x8801}, | ||
267 | {0x0000, 0x8800}, | ||
268 | {0x0010, 0x8805}, | ||
269 | {0x0035, 0x8801}, | ||
270 | {0x0000, 0x8800}, | ||
271 | {0x0049, 0x8805}, | ||
272 | {0x0009, 0x8801}, | ||
273 | {0x0010, 0x8800}, | ||
274 | {0x000b, 0x8805}, | ||
275 | {0x0028, 0x8801}, | ||
276 | {0x0000, 0x8800}, | ||
277 | {0x000f, 0x8805}, | ||
278 | {0x003b, 0x8801}, | ||
279 | {0x0000, 0x8800}, | ||
280 | {0x0000, 0x8805}, | ||
281 | {0x003c, 0x8801}, | ||
282 | {0x0000, 0x8800}, | ||
283 | {0x0002, 0x8502}, | ||
284 | {0x0039, 0x8801}, | ||
285 | {0x0000, 0x8805}, | ||
286 | {0x0000, 0x8800}, | ||
287 | |||
288 | {0x0087, 0x8700}, /* overwrite by start */ | ||
289 | {0x0081, 0x8702}, | ||
290 | {0x0000, 0x8500}, | ||
291 | /* {0x0010, 0x8500}, -- Previous line was this */ | ||
292 | {0x0002, 0x865b}, | ||
293 | {0x0003, 0x865c}, | ||
294 | /***************/ | ||
295 | {0x0003, 0x8801}, /* 0x121-> 289 */ | ||
296 | {0x0021, 0x8805}, | ||
297 | {0x0001, 0x8800}, | ||
298 | {0x0004, 0x8801}, /* 0x165 -> 357 */ | ||
299 | {0x0065, 0x8805}, | ||
300 | {0x0001, 0x8800}, | ||
301 | {0x0005, 0x8801}, /* 0x2f //blanking control colonne */ | ||
302 | {0x002f, 0x8805}, | ||
303 | {0x0000, 0x8800}, | ||
304 | {0x0006, 0x8801}, /* 0x00 //blanking mode row */ | ||
305 | {0x0000, 0x8805}, | ||
306 | {0x0000, 0x8800}, | ||
307 | {0x000a, 0x8801}, /* 0x01 //0x02 */ | ||
308 | {0x0001, 0x8805}, | ||
309 | {0x0000, 0x8800}, | ||
310 | {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock | ||
311 | * 0001 0 | 000 0110 0001 */ | 223 | * 0001 0 | 000 0110 0001 */ |
312 | {0x0061, 0x8805}, /* 61 31 */ | 224 | {0x0035, 0x0014}, |
313 | {0x0008, 0x8800}, /* 08 */ | ||
314 | {0x0035, 0x8801}, /* 0x14 - set gain general */ | ||
315 | {0x001f, 0x8805}, /* 0x14 */ | ||
316 | {0x0000, 0x8800}, | ||
317 | {0x000e, 0x8112}, /* white balance - was 30 */ | ||
318 | {} | 225 | {} |
319 | }; | 226 | }; |
320 | 227 | ||
@@ -459,6 +366,7 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg) | |||
459 | reg_r(gspca_dev, 0x8803, 1); | 366 | reg_r(gspca_dev, 0x8803, 1); |
460 | if (!gspca_dev->usb_buf[0]) | 367 | if (!gspca_dev->usb_buf[0]) |
461 | return; | 368 | return; |
369 | msleep(10); | ||
462 | } while (--retry); | 370 | } while (--retry); |
463 | } | 371 | } |
464 | 372 | ||
@@ -478,6 +386,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) | |||
478 | reg_r(gspca_dev, 0x8805, 1); | 386 | reg_r(gspca_dev, 0x8805, 1); |
479 | return ((int) value << 8) | gspca_dev->usb_buf[0]; | 387 | return ((int) value << 8) | gspca_dev->usb_buf[0]; |
480 | } | 388 | } |
389 | msleep(10); | ||
481 | } while (--retry); | 390 | } while (--retry); |
482 | return -1; | 391 | return -1; |
483 | } | 392 | } |
@@ -570,11 +479,13 @@ static int sd_init_12a(struct gspca_dev *gspca_dev) | |||
570 | static int sd_init_72a(struct gspca_dev *gspca_dev) | 479 | static int sd_init_72a(struct gspca_dev *gspca_dev) |
571 | { | 480 | { |
572 | PDEBUG(D_STREAM, "Chip revision: 072a"); | 481 | PDEBUG(D_STREAM, "Chip revision: 072a"); |
482 | write_vector(gspca_dev, rev72a_reset); | ||
483 | msleep(200); | ||
573 | write_vector(gspca_dev, rev72a_init_data1); | 484 | write_vector(gspca_dev, rev72a_init_data1); |
574 | write_sensor_72a(gspca_dev, rev72a_init_sensor1); | 485 | write_sensor_72a(gspca_dev, rev72a_init_sensor1); |
575 | write_vector(gspca_dev, rev72a_init_data2); | 486 | write_vector(gspca_dev, rev72a_init_data2); |
576 | write_sensor_72a(gspca_dev, rev72a_init_sensor2); | 487 | write_sensor_72a(gspca_dev, rev72a_init_sensor2); |
577 | write_vector(gspca_dev, rev72a_init_data3); | 488 | reg_w_val(gspca_dev->dev, 0x8112, 0x30); |
578 | return 0; | 489 | return 0; |
579 | } | 490 | } |
580 | 491 | ||
@@ -729,6 +640,11 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) | |||
729 | int Clck; | 640 | int Clck; |
730 | int mode; | 641 | int mode; |
731 | 642 | ||
643 | write_vector(gspca_dev, rev72a_reset); | ||
644 | msleep(200); | ||
645 | write_vector(gspca_dev, rev72a_init_data1); | ||
646 | write_sensor_72a(gspca_dev, rev72a_init_sensor1); | ||
647 | |||
732 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 648 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; |
733 | switch (mode) { | 649 | switch (mode) { |
734 | default: | 650 | default: |
@@ -745,11 +661,11 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) | |||
745 | } | 661 | } |
746 | reg_w_val(dev, 0x8500, mode); /* mode */ | 662 | reg_w_val(dev, 0x8500, mode); /* mode */ |
747 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ | 663 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ |
748 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | 664 | write_sensor_72a(gspca_dev, rev72a_init_sensor2); |
749 | setcontrast(gspca_dev); | 665 | setcontrast(gspca_dev); |
750 | /* setbrightness(gspca_dev); * fixme: bad values */ | 666 | /* setbrightness(gspca_dev); * fixme: bad values */ |
751 | setwhite(gspca_dev); | ||
752 | setautogain(gspca_dev); | 667 | setautogain(gspca_dev); |
668 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | ||
753 | return 0; | 669 | return 0; |
754 | } | 670 | } |
755 | 671 | ||