diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_core.c | 4 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.c | 118 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.h | 82 |
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 | ||
296 | int ov9650_start(struct sd *sd) | 296 | int 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 | ||
338 | static 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 | |||
358 | static 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 | |||
378 | static 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 | |||
398 | static 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 |