diff options
Diffstat (limited to 'drivers/media/video/usbvision/usbvision-core.c')
-rw-r--r-- | drivers/media/video/usbvision/usbvision-core.c | 165 |
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; | |||
49 | module_param(core_debug, int, 0644); | 49 | module_param(core_debug, int, 0644); |
50 | MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); | 50 | MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); |
51 | 51 | ||
52 | static unsigned int force_testpattern; | ||
53 | module_param(force_testpattern, int, 0644); | ||
54 | MODULE_PARM_DESC(force_testpattern, "enable test pattern display [core]"); | ||
55 | |||
56 | static int adjust_compression = 1; /* Set the compression to be adaptive */ | 52 | static int adjust_compression = 1; /* Set the compression to be adaptive */ |
57 | module_param(adjust_compression, int, 0444); | 53 | module_param(adjust_compression, int, 0444); |
58 | MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)"); | 54 | MODULE_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 | */ | ||
402 | static 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 */ | ||
1591 | static 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 | ||
2311 | int usbvision_setup(struct usb_usbvision *usbvision, int format) | 2288 | int 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); |