aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/usbvision/usbvision-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/usbvision/usbvision-core.c')
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c165
1 files changed, 72 insertions, 93 deletions
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index c8feb0d6fccf..f344411a4578 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -49,10 +49,6 @@ static unsigned int core_debug;
49module_param(core_debug, int, 0644); 49module_param(core_debug, int, 0644);
50MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); 50MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
51 51
52static unsigned int force_testpattern;
53module_param(force_testpattern, int, 0644);
54MODULE_PARM_DESC(force_testpattern, "enable test pattern display [core]");
55
56static int adjust_compression = 1; /* Set the compression to be adaptive */ 52static int adjust_compression = 1; /* Set the compression to be adaptive */
57module_param(adjust_compression, int, 0444); 53module_param(adjust_compression, int, 0444);
58MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)"); 54MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)");
@@ -388,90 +384,6 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision)
388} 384}
389 385
390/* 386/*
391 * usbvision_testpattern()
392 *
393 * Procedure forms a test pattern (yellow grid on blue background).
394 *
395 * Parameters:
396 * fullframe: if TRUE then entire frame is filled, otherwise the procedure
397 * continues from the current scanline.
398 * pmode 0: fill the frame with solid blue color (like on VCR or TV)
399 * 1: Draw a colored grid
400 *
401 */
402static void usbvision_testpattern(struct usb_usbvision *usbvision,
403 int fullframe, int pmode)
404{
405 static const char proc[] = "usbvision_testpattern";
406 struct usbvision_frame *frame;
407 unsigned char *f;
408 int num_cell = 0;
409 int scan_length = 0;
410 static int num_pass;
411
412 if (usbvision == NULL) {
413 printk(KERN_ERR "%s: usbvision == NULL\n", proc);
414 return;
415 }
416 if (usbvision->cur_frame == NULL) {
417 printk(KERN_ERR "%s: usbvision->cur_frame is NULL.\n", proc);
418 return;
419 }
420
421 /* Grab the current frame */
422 frame = usbvision->cur_frame;
423
424 /* Optionally start at the beginning */
425 if (fullframe) {
426 frame->curline = 0;
427 frame->scanlength = 0;
428 }
429
430 /* Form every scan line */
431 for (; frame->curline < frame->frmheight; frame->curline++) {
432 int i;
433
434 f = frame->data + (usbvision->curwidth * 3 * frame->curline);
435 for (i = 0; i < usbvision->curwidth; i++) {
436 unsigned char cb = 0x80;
437 unsigned char cg = 0;
438 unsigned char cr = 0;
439
440 if (pmode == 1) {
441 if (frame->curline % 32 == 0)
442 cb = 0, cg = cr = 0xFF;
443 else if (i % 32 == 0) {
444 if (frame->curline % 32 == 1)
445 num_cell++;
446 cb = 0, cg = cr = 0xFF;
447 } else {
448 cb =
449 ((num_cell * 7) +
450 num_pass) & 0xFF;
451 cg =
452 ((num_cell * 5) +
453 num_pass * 2) & 0xFF;
454 cr =
455 ((num_cell * 3) +
456 num_pass * 3) & 0xFF;
457 }
458 } else {
459 /* Just the blue screen */
460 }
461
462 *f++ = cb;
463 *f++ = cg;
464 *f++ = cr;
465 scan_length += 3;
466 }
467 }
468
469 frame->grabstate = frame_state_done;
470 frame->scanlength += scan_length;
471 ++num_pass;
472}
473
474/*
475 * usbvision_decompress_alloc() 387 * usbvision_decompress_alloc()
476 * 388 *
477 * allocates intermediate buffer for decompression 389 * allocates intermediate buffer for decompression
@@ -571,10 +483,6 @@ static enum parse_state usbvision_find_header(struct usb_usbvision *usbvision)
571 frame->scanstate = scan_state_lines; 483 frame->scanstate = scan_state_lines;
572 frame->curline = 0; 484 frame->curline = 0;
573 485
574 if (force_testpattern) {
575 usbvision_testpattern(usbvision, 1, 1);
576 return parse_state_next_frame;
577 }
578 return parse_state_continue; 486 return parse_state_continue;
579} 487}
580 488
@@ -1679,6 +1587,55 @@ int usbvision_power_off(struct usb_usbvision *usbvision)
1679 return err_code; 1587 return err_code;
1680} 1588}
1681 1589
1590/* configure webcam image sensor using the serial port */
1591static int usbvision_init_webcam(struct usb_usbvision *usbvision)
1592{
1593 int rc;
1594 int i;
1595 static char init_values[38][3] = {
1596 { 0x04, 0x12, 0x08 }, { 0x05, 0xff, 0xc8 }, { 0x06, 0x18, 0x07 }, { 0x07, 0x90, 0x00 },
1597 { 0x09, 0x00, 0x00 }, { 0x0a, 0x00, 0x00 }, { 0x0b, 0x08, 0x00 }, { 0x0d, 0xcc, 0xcc },
1598 { 0x0e, 0x13, 0x14 }, { 0x10, 0x9b, 0x83 }, { 0x11, 0x5a, 0x3f }, { 0x12, 0xe4, 0x73 },
1599 { 0x13, 0x88, 0x84 }, { 0x14, 0x89, 0x80 }, { 0x15, 0x00, 0x20 }, { 0x16, 0x00, 0x00 },
1600 { 0x17, 0xff, 0xa0 }, { 0x18, 0x6b, 0x20 }, { 0x19, 0x22, 0x40 }, { 0x1a, 0x10, 0x07 },
1601 { 0x1b, 0x00, 0x47 }, { 0x1c, 0x03, 0xe0 }, { 0x1d, 0x00, 0x00 }, { 0x1e, 0x00, 0x00 },
1602 { 0x1f, 0x00, 0x00 }, { 0x20, 0x00, 0x00 }, { 0x21, 0x00, 0x00 }, { 0x22, 0x00, 0x00 },
1603 { 0x23, 0x00, 0x00 }, { 0x24, 0x00, 0x00 }, { 0x25, 0x00, 0x00 }, { 0x26, 0x00, 0x00 },
1604 { 0x27, 0x00, 0x00 }, { 0x28, 0x00, 0x00 }, { 0x29, 0x00, 0x00 }, { 0x08, 0x80, 0x60 },
1605 { 0x0f, 0x2d, 0x24 }, { 0x0c, 0x80, 0x80 }
1606 };
1607 char value[3];
1608
1609 /* the only difference between PAL and NTSC init_values */
1610 if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_NTSC)
1611 init_values[4][1] = 0x34;
1612
1613 for (i = 0; i < sizeof(init_values) / 3; i++) {
1614 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
1615 memcpy(value, init_values[i], 3);
1616 rc = usb_control_msg(usbvision->dev,
1617 usb_sndctrlpipe(usbvision->dev, 1),
1618 USBVISION_OP_CODE,
1619 USB_DIR_OUT | USB_TYPE_VENDOR |
1620 USB_RECIP_ENDPOINT, 0,
1621 (__u16) USBVISION_SER_DAT1, value,
1622 3, HZ);
1623 if (rc < 0)
1624 return rc;
1625 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SIO);
1626 /* write 3 bytes to the serial port using SIO mode */
1627 usbvision_write_reg(usbvision, USBVISION_SER_CONT, 3 | 0x10);
1628 usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, 0);
1629 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
1630 usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_IO_2);
1631 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT);
1632 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_DAT_IO);
1633 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT | USBVISION_DAT_IO);
1634 }
1635
1636 return 0;
1637}
1638
1682/* 1639/*
1683 * usbvision_set_video_format() 1640 * usbvision_set_video_format()
1684 * 1641 *
@@ -1797,6 +1754,13 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
1797 1754
1798 frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */ 1755 frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */
1799 1756
1757 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
1758 if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_PAL)
1759 frame_drop = 25;
1760 else
1761 frame_drop = 30;
1762 }
1763
1800 /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ... 1764 /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
1801 => frame_skip = 4; 1765 => frame_skip = 4;
1802 => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25; 1766 => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
@@ -2046,6 +2010,12 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
2046 value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */ 2010 value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */
2047 } 2011 }
2048 2012
2013 /* webcam is only 480 pixels wide, both PAL and NTSC version */
2014 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
2015 value[0] = 0xe0;
2016 value[1] = 0x01; /* 0x01E0 -> 480 Input video line length */
2017 }
2018
2049 if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) { 2019 if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) {
2050 value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff; 2020 value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff;
2051 value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8; 2021 value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8;
@@ -2148,7 +2118,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
2148 (__u16) USBVISION_DRM_PRM1, value, 8, HZ); 2118 (__u16) USBVISION_DRM_PRM1, value, 8, HZ);
2149 2119
2150 if (rc < 0) { 2120 if (rc < 0) {
2151 dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc); 2121 dev_err(&usbvision->dev->dev, "%s: ERROR=%d\n", __func__, rc);
2152 return rc; 2122 return rc;
2153 } 2123 }
2154 2124
@@ -2180,8 +2150,15 @@ int usbvision_power_on(struct usb_usbvision *usbvision)
2180 usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2150 usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2181 USBVISION_SSPND_EN | USBVISION_RES2); 2151 USBVISION_SSPND_EN | USBVISION_RES2);
2182 2152
2153 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
2154 usbvision_write_reg(usbvision, USBVISION_VIN_REG1,
2155 USBVISION_16_422_SYNC | USBVISION_HVALID_PO);
2156 usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
2157 USBVISION_NOHVALID | USBVISION_KEEP_BLANK);
2158 }
2183 usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2159 usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2184 USBVISION_SSPND_EN | USBVISION_PWR_VID); 2160 USBVISION_SSPND_EN | USBVISION_PWR_VID);
2161 mdelay(10);
2185 err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2162 err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2186 USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2); 2163 USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
2187 if (err_code == 1) 2164 if (err_code == 1)
@@ -2310,6 +2287,8 @@ int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel)
2310 2287
2311int usbvision_setup(struct usb_usbvision *usbvision, int format) 2288int usbvision_setup(struct usb_usbvision *usbvision, int format)
2312{ 2289{
2290 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM)
2291 usbvision_init_webcam(usbvision);
2313 usbvision_set_video_format(usbvision, format); 2292 usbvision_set_video_format(usbvision, format);
2314 usbvision_set_dram_settings(usbvision); 2293 usbvision_set_dram_settings(usbvision);
2315 usbvision_set_compress_params(usbvision); 2294 usbvision_set_compress_params(usbvision);