aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/spca561.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-01-16 14:24:28 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:32 -0400
commit0dbc2c1674b346ff22f729af14efa4822f81325c (patch)
tree9ea29bd7e009616914fc07e280de1a5ac7121627 /drivers/media/video/gspca/spca561.c
parent576ed7b5696b9435e8e6a6ec0c57da1f19c7e469 (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.c168
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
148static const __u16 rev72a_init_data1[][2] = { 148static 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};
154static 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};
161static const __u16 rev72a_init_sensor1[][2] = { 163static 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};
177static const __u16 rev72a_init_data2[][2] = { 178static 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};
220static const __u16 rev72a_init_sensor2[][2] = { 216static 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};
231static 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)
570static int sd_init_72a(struct gspca_dev *gspca_dev) 479static 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