aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c4
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c118
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h82
3 files changed, 76 insertions, 128 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index bae7aa6f0f80..0d84a12d59f0 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -51,7 +51,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
51 address, *i2c_data); 51 address, *i2c_data);
52 52
53 /* usb_control_msg(...) returns the number of bytes sent upon success, 53 /* usb_control_msg(...) returns the number of bytes sent upon success,
54 mask that and return zero upon success instead*/ 54 mask that and return zero instead*/
55 return (err < 0) ? err : 0; 55 return (err < 0) ? err : 0;
56} 56}
57 57
@@ -76,7 +76,7 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
76 4, M5602_URB_MSG_TIMEOUT); 76 4, M5602_URB_MSG_TIMEOUT);
77 77
78 /* usb_control_msg(...) returns the number of bytes sent upon success, 78 /* usb_control_msg(...) returns the number of bytes sent upon success,
79 mask that and return zero upon success instead */ 79 mask that and return zero instead */
80 return (err < 0) ? err : 0; 80 return (err < 0) ? err : 0;
81} 81}
82 82
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 292f2d41fba5..15288a114fe2 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -180,7 +180,7 @@ static struct v4l2_pix_format ov9650_modes[] = {
180 176 * 144, 180 176 * 144,
181 .bytesperline = 176, 181 .bytesperline = 176,
182 .colorspace = V4L2_COLORSPACE_SRGB, 182 .colorspace = V4L2_COLORSPACE_SRGB,
183 .priv = 0 183 .priv = 9
184 }, { 184 }, {
185 320, 185 320,
186 240, 186 240,
@@ -190,7 +190,7 @@ static struct v4l2_pix_format ov9650_modes[] = {
190 320 * 240, 190 320 * 240,
191 .bytesperline = 320, 191 .bytesperline = 320,
192 .colorspace = V4L2_COLORSPACE_SRGB, 192 .colorspace = V4L2_COLORSPACE_SRGB,
193 .priv = 0 193 .priv = 8
194 }, { 194 }, {
195 352, 195 352,
196 288, 196 288,
@@ -200,7 +200,7 @@ static struct v4l2_pix_format ov9650_modes[] = {
200 352 * 288, 200 352 * 288,
201 .bytesperline = 352, 201 .bytesperline = 352,
202 .colorspace = V4L2_COLORSPACE_SRGB, 202 .colorspace = V4L2_COLORSPACE_SRGB,
203 .priv = 0 203 .priv = 9
204 }, { 204 }, {
205 640, 205 640,
206 480, 206 480,
@@ -210,7 +210,7 @@ static struct v4l2_pix_format ov9650_modes[] = {
210 640 * 480, 210 640 * 480,
211 .bytesperline = 640, 211 .bytesperline = 640,
212 .colorspace = V4L2_COLORSPACE_SRGB, 212 .colorspace = V4L2_COLORSPACE_SRGB,
213 .priv = 0 213 .priv = 9
214 } 214 }
215}; 215};
216 216
@@ -295,13 +295,22 @@ int ov9650_init(struct sd *sd)
295 295
296int ov9650_start(struct sd *sd) 296int ov9650_start(struct sd *sd)
297{ 297{
298 u8 data;
298 int i, err = 0; 299 int i, err = 0;
299 struct cam *cam = &sd->gspca_dev.cam; 300 struct cam *cam = &sd->gspca_dev.cam;
301 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
302 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
303 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
304 int hor_offs = OV9650_LEFT_OFFSET;
305
306 if (width <= 320)
307 hor_offs /= 2;
300 308
301 err = ov9650_init(sd); 309 err = ov9650_init(sd);
302 if (err < 0) 310 if (err < 0)
303 return err; 311 return err;
304 312
313 /* Synthesize the vsync/hsync setup */
305 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { 314 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
306 if (res_init_ov9650[i][0] == BRIDGE) 315 if (res_init_ov9650[i][0] == BRIDGE)
307 err = m5602_write_bridge(sd, res_init_ov9650[i][1], 316 err = m5602_write_bridge(sd, res_init_ov9650[i][1],
@@ -315,70 +324,87 @@ int ov9650_start(struct sd *sd)
315 if (err < 0) 324 if (err < 0)
316 return err; 325 return err;
317 326
318 switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) { 327 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, ((ver_offs >> 8) & 0xff));
328 if (err < 0)
329 return err;
330
331 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
332 if (err < 0)
333 return err;
334
335 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
336 if (err < 0)
337 return err;
338
339 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
340 if (err < 0)
341 return err;
342
343 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
344 if (err < 0)
345 return err;
346
347 for (i = 0; i < 2 && !err; i++) {
348 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
349 }
350 if (err < 0)
351 return err;
352
353 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (hor_offs >> 8) & 0xff);
354 if (err < 0)
355 return err;
356
357 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
358 if (err < 0)
359 return err;
360
361 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, ((width + hor_offs) >> 8) & 0xff);
362 if (err < 0)
363 return err;
364
365 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, ((width + hor_offs) & 0xff));
366 if (err < 0)
367 return err;
368
369 switch (width) {
319 case 640: 370 case 640:
320 PDEBUG(D_V4L2, "Configuring camera for VGA mode"); 371 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
321 372
322 for (i = 0; i < ARRAY_SIZE(VGA_ov9650) && !err; i++) { 373 data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
323 if (VGA_ov9650[i][0] == SENSOR) { 374 OV9650_RAW_RGB_SELECT;
324 u8 data = VGA_ov9650[i][2]; 375
376 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
325 377
326 err = m5602_write_sensor(sd,
327 VGA_ov9650[i][1], &data, 1);
328 } else {
329 err = m5602_write_bridge(sd, VGA_ov9650[i][1],
330 VGA_ov9650[i][2]);
331 }
332 }
333 break; 378 break;
334 379
335 case 352: 380 case 352:
336 PDEBUG(D_V4L2, "Configuring camera for CIF mode"); 381 PDEBUG(D_V4L2, "Configuring camera for CIF mode");
337 382
338 for (i = 0; i < ARRAY_SIZE(CIF_ov9650) && !err; i++) { 383 data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
339 if (CIF_ov9650[i][0] == SENSOR) { 384 OV9650_RAW_RGB_SELECT;
340 u8 data = CIF_ov9650[i][2]; 385
386 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
341 387
342 err = m5602_write_sensor(sd,
343 CIF_ov9650[i][1], &data, 1);
344 } else {
345 err = m5602_write_bridge(sd, CIF_ov9650[i][1],
346 CIF_ov9650[i][2]);
347 }
348 }
349 break; 388 break;
350 389
351 case 320: 390 case 320:
352 PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); 391 PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
353 392
354 for (i = 0; i < ARRAY_SIZE(QVGA_ov9650) && !err; i++) { 393 data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
355 if (QVGA_ov9650[i][0] == SENSOR) { 394 OV9650_RAW_RGB_SELECT;
356 u8 data = QVGA_ov9650[i][2]; 395
396 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
357 397
358 err = m5602_write_sensor(sd,
359 QVGA_ov9650[i][1], &data, 1);
360 } else {
361 err = m5602_write_bridge(sd, QVGA_ov9650[i][1],
362 QVGA_ov9650[i][2]);
363 }
364 }
365 break; 398 break;
366 399
367 case 176: 400 case 176:
368 PDEBUG(D_V4L2, "Configuring camera for QCIF mode"); 401 PDEBUG(D_V4L2, "Configuring camera for QCIF mode");
369 402
370 for (i = 0; i < ARRAY_SIZE(QCIF_ov9650) && !err; i++) { 403 data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
371 if (QCIF_ov9650[i][0] == SENSOR) { 404 OV9650_RAW_RGB_SELECT;
372 u8 data = QCIF_ov9650[i][2];
373 err = m5602_write_sensor(sd,
374 QCIF_ov9650[i][1], &data, 1);
375 } else {
376 err = m5602_write_bridge(sd, QCIF_ov9650[i][1],
377 QCIF_ov9650[i][2]);
378 }
379 }
380 break;
381 405
406 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
407 break;
382 } 408 }
383 return err; 409 return err;
384} 410}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index ca0e42ee05ce..cc39d76e5221 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -120,6 +120,8 @@
120#define OV9650_SOFT_SLEEP (1 << 4) 120#define OV9650_SOFT_SLEEP (1 << 4)
121#define OV9650_OUTPUT_DRIVE_2X (1 << 0) 121#define OV9650_OUTPUT_DRIVE_2X (1 << 0)
122 122
123#define OV9650_LEFT_OFFSET 0x62
124
123#define GAIN_DEFAULT 0x14 125#define GAIN_DEFAULT 0x14
124#define RED_GAIN_DEFAULT 0x70 126#define RED_GAIN_DEFAULT 0x70
125#define BLUE_GAIN_DEFAULT 0x20 127#define BLUE_GAIN_DEFAULT 0x20
@@ -335,84 +337,4 @@ static const unsigned char res_init_ov9650[][3] =
335 {BRIDGE, M5602_XB_SIG_INI, 0x01} 337 {BRIDGE, M5602_XB_SIG_INI, 0x01}
336}; 338};
337 339
338static const unsigned char VGA_ov9650[][3] =
339{
340 /* Moves the view window in a vertical orientation */
341 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
342 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
343 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
344 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
345 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
346 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
347 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
348 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
349 {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
350 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, /* 640 + 98 */
351 {BRIDGE, M5602_XB_HSYNC_PARA, 0xe2},
352
353 {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
354 OV9650_RGB_SELECT |
355 OV9650_RAW_RGB_SELECT},
356};
357
358static const unsigned char CIF_ov9650[][3] =
359{
360 /* Moves the view window in a vertical orientation */
361 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
362 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
363 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
364 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
365 {BRIDGE, M5602_XB_VSYNC_PARA, 0x20}, /* 288 */
366 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
367 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
368 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
369 {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
370 {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 352 + 98 */
371 {BRIDGE, M5602_XB_HSYNC_PARA, 0xc2},
372
373 {SENSOR, OV9650_COM7, OV9650_CIF_SELECT |
374 OV9650_RGB_SELECT |
375 OV9650_RAW_RGB_SELECT},
376};
377
378static const unsigned char QVGA_ov9650[][3] =
379{
380 /* Moves the view window in a vertical orientation */
381 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
382 {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
383 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
384 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
385 {BRIDGE, M5602_XB_VSYNC_PARA, 0xf0}, /* 240 */
386 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
387 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
388 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
389 {BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 50 */
390 {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 320 + 50 */
391 {BRIDGE, M5602_XB_HSYNC_PARA, 0x71},
392
393 {SENSOR, OV9650_COM7, OV9650_QVGA_SELECT |
394 OV9650_RGB_SELECT |
395 OV9650_RAW_RGB_SELECT},
396};
397
398static const unsigned char QCIF_ov9650[][3] =
399{
400 /* Moves the view window in a vertical orientation */
401 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
402 {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
403 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
404 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
405 {BRIDGE, M5602_XB_VSYNC_PARA, 0x90}, /* 144 */
406 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
407 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
408 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
409 {BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 48 */
410 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, /* 176 + 49 */
411 {BRIDGE, M5602_XB_HSYNC_PARA, 0xe1},
412
413 {SENSOR, OV9650_COM7, OV9650_QCIF_SELECT |
414 OV9650_RGB_SELECT |
415 OV9650_RAW_RGB_SELECT},
416};
417
418#endif 340#endif