diff options
38 files changed, 761 insertions, 432 deletions
diff --git a/linux/Documentation/video4linux/CARDLIST.ivtv b/linux/Documentation/video4linux/CARDLIST.ivtv new file mode 100644 index 000000000..ddd76a0eb --- /dev/null +++ b/linux/Documentation/video4linux/CARDLIST.ivtv @@ -0,0 +1,18 @@ + 1 -> Hauppauge WinTV PVR-250 + 2 -> Hauppauge WinTV PVR-350 + 3 -> Hauppauge WinTV PVR-150 or PVR-500 + 4 -> AVerMedia M179 [1461:a3ce,1461:a3cf] + 5 -> Yuan MPG600/Kuroutoshikou iTVC16-STVLP [12ab:fff3,12ab:ffff] + 6 -> Yuan MPG160/Kuroutoshikou iTVC15-STVLP [12ab:0000,10fc:40a0] + 7 -> Yuan PG600/DiamondMM PVR-550 [ff92:0070,ffab:0600] + 8 -> Adaptec AVC-2410 [9005:0093] + 9 -> Adaptec AVC-2010 [9005:0092] +10 -> NAGASE TRANSGEAR 5000TV [1461:bfff] +11 -> AOpen VA2000MAX-STN6 [0000:ff5f] +12 -> YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP [12ab:0600,fbab:0600,1154:0523] +13 -> I/O Data GV-MVP/RX [10fc:d01e,10fc:d038,10fc:d039] +14 -> I/O Data GV-MVP/RX2E [10fc:d025] +15 -> GOTVIEW PCI DVD (partial support only) [12ab:0600] +16 -> GOTVIEW PCI DVD2 Deluxe [ffac:0600] +17 -> Yuan MPC622 [ff01:d998] +18 -> Digital Cowboy DCT-MTVP1 [1461:bfff] diff --git a/linux/Documentation/video4linux/CARDLIST.tuner b/linux/Documentation/video4linux/CARDLIST.tuner index 44134f04b..9b02dbb2a 100644 --- a/linux/Documentation/video4linux/CARDLIST.tuner +++ b/linux/Documentation/video4linux/CARDLIST.tuner @@ -72,3 +72,4 @@ tuner=70 - Samsung TCPN 2121P30A tuner=71 - Xceive xc3028 tuner=72 - Thomson FE6600 tuner=73 - Samsung TCPG 6121P30A +tuner=75 - Philips TEA5761 FM Radio diff --git a/linux/Documentation/video4linux/README.ivtv b/linux/Documentation/video4linux/README.ivtv new file mode 100644 index 000000000..73df22c40 --- /dev/null +++ b/linux/Documentation/video4linux/README.ivtv @@ -0,0 +1,187 @@ + +ivtv release notes +================== + +This is a v4l2 device driver for the Conexant cx23415/6 MPEG encoder/decoder. +The cx23415 can do both encoding and decoding, the cx23416 can only do MPEG +encoding. Currently the only card featuring full decoding support is the +Hauppauge PVR-350. + +NOTE: this driver requires the latest encoder firmware (version 2.06.039, size +376836 bytes). Get the firmware from here: + +http://dl.ivtvdriver.org/ivtv/firmware/firmware.tar.gz + +NOTE: 'normal' TV applications do not work with this driver, you need +an application that can handle MPEG input such as mplayer, xine, MythTV, +etc. + +The primary goal of the IVTV project is to provide a "clean room" Linux +Open Source driver implementation for video capture cards based on the +iCompression iTVC15 or Conexant CX23415/CX23416 MPEG Codec. + +Features: + * Hardware mpeg2 capture of broadcast video (and sound) via the tuner or + S-Video/Composite and audio line-in. + * Hardware mpeg2 capture of FM radio where hardware support exists + * Supports NTSC, PAL, SECAM with stereo sound + * Supports SAP and bilingual transmissions. + * Supports raw VBI (closed captions and teletext). + * Supports sliced VBI (closed captions and teletext) and is able to insert + this into the captured MPEG stream. + * Supports raw YUV and PCM input. + +Additional features for the PVR-350 (CX23415 based): + * Provides hardware mpeg2 playback + * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the + video signal) + * Provides a framebuffer (allowing X applications to appear on the video + device) (this framebuffer is not yet part of the kernel. In the meantime it + is available from www.ivtvdriver.org). + * Supports raw YUV output. + +IMPORTANT: In case of problems first read this page: + http://www.ivtvdriver.org/index.php/Troubleshooting + +See also: + +Homepage + Wiki +http://www.ivtvdriver.org + +IRC +irc://irc.freenode.net/ivtv-dev + +---------------------------------------------------------- + +Devices +======= + +A maximum of 12 ivtv boards are allowed at the moment. + +Cards that don't have a video output capability (i.e. non PVR350 cards) +lack the vbi8, vbi16, video16 and video48 devices. They also do not +support the framebuffer device /dev/fbx for OSD. + +The radio0 device may or may not be present, depending on whether the +card has a radio tuner or not. + +Here is a list of the base v4l devices: +crw-rw---- 1 root video 81, 0 Jun 19 22:22 /dev/video0 +crw-rw---- 1 root video 81, 16 Jun 19 22:22 /dev/video16 +crw-rw---- 1 root video 81, 24 Jun 19 22:22 /dev/video24 +crw-rw---- 1 root video 81, 32 Jun 19 22:22 /dev/video32 +crw-rw---- 1 root video 81, 48 Jun 19 22:22 /dev/video48 +crw-rw---- 1 root video 81, 64 Jun 19 22:22 /dev/radio0 +crw-rw---- 1 root video 81, 224 Jun 19 22:22 /dev/vbi0 +crw-rw---- 1 root video 81, 228 Jun 19 22:22 /dev/vbi8 +crw-rw---- 1 root video 81, 232 Jun 19 22:22 /dev/vbi16 + +Base devices +============ + +For every extra card you have the numbers increased by one. For example, +/dev/video0 is listed as the 'base' encoding capture device so we have: + + /dev/video0 is the encoding capture device for the first card (card 0) + /dev/video1 is the encoding capture device for the second card (card 1) + /dev/video2 is the encoding capture device for the third card (card 2) + +Note that if the first card doesn't have a feature (eg no decoder, so no +video16, the second card will still use video17. The simple rule is 'add +the card number to the base device number'. If you have other capture +cards (e.g. WinTV PCI) that are detected first, then you have to tell +the ivtv module about it so that it will start counting at 1 (or 2, or +whatever). Otherwise the device numbers can get confusing. The ivtv +'ivtv_first_minor' module option can be used for that. + + +/dev/video0 +The encoding capture device(s). +Read-only. + +Reading from this device gets you the MPEG1/2 program stream. +Example: + +cat /dev/video0 > my.mpg (you need to hit ctrl-c to exit) + + +/dev/video16 +The decoder output device(s) +Write-only. Only present if the MPEG decoder (i.e. CX23415) exists. + +An mpeg2 stream sent to this device will appear on the selected video +display, audio will appear on the line-out/audio out. It is only +available for cards that support video out. Example: + +cat my.mpg >/dev/video16 + + +/dev/video24 +The raw audio capture device(s). +Read-only + +The raw audio PCM stereo stream from the currently selected +tuner or audio line-in. Reading from this device results in a raw +(signed 16 bit Little Endian, 48000 Hz, stereo pcm) capture. +This device only captures audio. This should be replaced by an ALSA +device in the future. +Note that there is no corresponding raw audio output device, this is +not supported in the decoder firmware. + + +/dev/video32 +The raw video capture device(s) +Read-only + +The raw YUV video output from the current video input. The YUV format +is non-standard (V4L2_PIX_FMT_HM12). + +Note that the YUV and PCM streams are not synchronized, so they are of +limited use. + + +/dev/video48 +The raw video display device(s) +Write-only. Only present if the MPEG decoder (i.e. CX23415) exists. + +Writes a YUV stream to the decoder of the card. + + +/dev/radio0 +The radio tuner device(s) +Cannot be read or written. + +Used to enable the radio tuner and tune to a frequency. You cannot +read or write audio streams with this device. Once you use this +device to tune the radio, use /dev/video24 to read the raw pcm stream +or /dev/video0 to get an mpeg2 stream with black video. + + +/dev/vbi0 +The 'vertical blank interval' (Teletext, CC, WSS etc) capture device(s) +Read-only + +Captures the raw (or sliced) video data sent during the Vertical Blank +Interval. This data is used to encode teletext, closed captions, VPS, +widescreen signalling, electronic program guide information, and other +services. + + +/dev/vbi8 +Processed vbi feedback device(s) +Read-only. Only present if the MPEG decoder (i.e. CX23415) exists. + +The sliced VBI data embedded in an MPEG stream is reproduced on this +device. So while playing back a recording on /dev/video16, you can +read the embedded VBI data from /dev/vbi8. + + +/dev/vbi16 +The vbi 'display' device(s) +Write-only. Only present if the MPEG decoder (i.e. CX23415) exists. + +Can be used to send sliced VBI data to the video-out connector. + +--------------------------------- + +Hans Verkuil <hverkuil@xs4all.nl> diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index fc77de45c..a5c0e1a3e 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -180,8 +180,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; + mutex_lock(&dmxdev->mutex); if ((file->f_flags & O_ACCMODE) == O_WRONLY) { dmxdev->demux->disconnect_frontend(dmxdev->demux); @@ -673,13 +672,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file) static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter) { - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; - - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); - return -ERESTARTSYS; - } + mutex_lock(&dmxdev->mutex); + mutex_lock(&dmxdevfilter->mutex); dvb_dmxdev_filter_stop(dmxdevfilter); dvb_dmxdev_filter_reset(dmxdevfilter); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index fcff5eab2..6d8d1c3df 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -673,8 +673,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) struct dvb_demux *demux = feed->demux; int ret; - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; + mutex_lock(&demux->mutex); if (feed->state < DMX_STATE_GO) { mutex_unlock(&demux->mutex); @@ -748,8 +747,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dvb_demux *demux = (struct dvb_demux *)dmx; struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; + mutex_lock(&demux->mutex); if (feed->state == DMX_STATE_FREE) { mutex_unlock(&demux->mutex); @@ -916,8 +914,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) struct dvb_demux *dvbdmx = dvbdmxfeed->demux; int ret; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (!dvbdmx->stop_feed) { mutex_unlock(&dvbdmx->mutex); @@ -942,8 +939,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (dvbdmxfilter->feed != dvbdmxfeed) { mutex_unlock(&dvbdmx->mutex); @@ -1016,8 +1012,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (dvbdmxfeed->state == DMX_STATE_FREE) { mutex_unlock(&dvbdmx->mutex); @@ -1126,8 +1121,7 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, if (demux->frontend) return -EINVAL; - if (mutex_lock_interruptible(&dvbdemux->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdemux->mutex); demux->frontend = frontend; mutex_unlock(&dvbdemux->mutex); @@ -1138,8 +1132,7 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) { struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - if (mutex_lock_interruptible(&dvbdemux->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdemux->mutex); demux->frontend = NULL; mutex_unlock(&dvbdemux->mutex); diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 5c7512a84..9c8e9c3f4 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -214,8 +214,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, int id; - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); if ((id = dvbdev_get_free_id (adap, type)) < 0){ mutex_unlock(&dvbdev_register_lock); @@ -305,8 +304,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu { int num; - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); if ((num = dvbdev_get_free_adapter_num ()) < 0) { mutex_unlock(&dvbdev_register_lock); @@ -334,8 +332,7 @@ EXPORT_SYMBOL(dvb_register_adapter); int dvb_unregister_adapter(struct dvb_adapter *adap) { - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); list_del (&adap->list_head); mutex_unlock(&dvbdev_register_lock); return 0; diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig index 6d96b17a7..4ab38a851 100644 --- a/linux/drivers/media/radio/Kconfig +++ b/linux/drivers/media/radio/Kconfig @@ -3,7 +3,7 @@ # menu "Radio Adapters" - depends on VIDEO_DEV!=n + depends on VIDEO_DEV config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 639e8b6c3..ac65aaf20 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -484,6 +484,14 @@ config TUNER_3036 Say Y here to include support for Philips SAB3036 compatible tuners. If in doubt, say N. +config TUNER_TEA5761 + tristate "TEA 5761 radio tuner (EXPERIMENTAL)" + depends on VIDEO_DEV && I2C + select VIDEO_TUNER + help + Say Y here to include support for Philips TEA5761 radio tuner. + If in doubt, say N. + config VIDEO_VINO tristate "SGI Vino Video For Linux (EXPERIMENTAL)" depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 9c2de5016..3202e8729 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -7,6 +7,10 @@ zr36067-objs := zoran_procfs.o zoran_device.o \ tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ mt20xx.o tda8290.o tea5767.o tda9887.o +ifneq ($(CONFIG_TUNER_TEA5761),n) + tuner-objs += tea5761.o +endif + msp3400-objs := msp3400-driver.o msp3400-kthreads.o obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o diff --git a/linux/drivers/media/video/cpia_pp.c b/linux/drivers/media/video/cpia_pp.c index 26e7e6d5b..337675e96 100644 --- a/linux/drivers/media/video/cpia_pp.c +++ b/linux/drivers/media/video/cpia_pp.c @@ -144,7 +144,6 @@ static void cpia_pp_run_callback(struct work_struct *work) cam = container_of(work, struct pp_cam_entry, cb_task); cb_func = cam->cb_func; cb_data = cam->cb_data; - work_release(work); cb_func(cb_data); } @@ -689,7 +688,7 @@ static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), vo #else cam->cb_func = cb; cam->cb_data = cbdata; - INIT_WORK_NAR(&cam->cb_task, cpia_pp_run_callback); + INIT_WORK(&cam->cb_task, cpia_pp_run_callback); #endif } else { retval = -1; diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index 1cf820fb0..2fcf3e7c3 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -625,28 +625,19 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) mutex_init(&itv->i2c_bus_lock); mutex_init(&itv->udma.lock); - itv->lock = SPIN_LOCK_UNLOCKED; - itv->dma_reg_lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&itv->lock); + spin_lock_init(&itv->dma_reg_lock); - itv->vbi.work_queues = create_workqueue("ivtv_vbi"); - if (itv->vbi.work_queues == NULL) { - IVTV_ERR("Could not create VBI workqueue\n"); - return -1; - } - - itv->yuv_info.work_queues = create_workqueue("ivtv_yuv"); - if (itv->yuv_info.work_queues == NULL) { - IVTV_ERR("Could not create YUV workqueue\n"); - destroy_workqueue(itv->vbi.work_queues); + itv->irq_work_queues = create_workqueue(itv->name); + if (itv->irq_work_queues == NULL) { + IVTV_ERR("Could not create ivtv workqueue\n"); return -1; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) - INIT_WORK(&itv->vbi.work_queue, vbi_work_handler); - INIT_WORK(&itv->yuv_info.work_queue, ivtv_yuv_work_handler); + INIT_WORK(&itv->irq_work_queue, ivtv_irq_work_handler); #else - INIT_WORK(&itv->vbi.work_queue, vbi_work_handler, itv); - INIT_WORK(&itv->yuv_info.work_queue, ivtv_yuv_work_handler, itv); + INIT_WORK(&itv->irq_work_queue, ivtv_irq_work_handler, itv); #endif /* start counting open_id at 1 */ @@ -1147,46 +1138,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev, if (itv->options.radio > 0) itv->v4l2_cap |= V4L2_CAP_RADIO; - retval = ivtv_streams_setup(itv); - if (retval) { - IVTV_ERR("Error %d setting up streams\n", retval); - goto free_i2c; - } - - /* Start Threads */ - IVTV_DEBUG_INFO("Starting Threads\n"); - - /* Decoder Thread */ - if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { - ivtv_init_mpeg_decoder(itv); - } - - IVTV_DEBUG_IRQ("Masking interrupts\n"); - /* clear interrupt mask, effectively disabling interrupts */ - ivtv_set_irq_mask(itv, 0xffffffff); - - /* Register IRQ */ - retval = request_irq(itv->dev->irq, ivtv_irq_handler, - IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv); - if (retval) { - IVTV_ERR("Failed to register irq %d\n", retval); - goto free_streams; - } - - /* On a cx23416 this seems to be able to enable DMA to the chip? */ - if (!itv->has_cx23415) - write_reg_sync(0x03, IVTV_REG_DMACONTROL); - - /* Default interrupts enabled. For the PVR350 this includes the - decoder VSYNC interrupt, which is always on. It is not only used - during decoding but also by the OSD. - Some old PVR250 cards had a cx23415, so testing for that is too - general. Instead test if the card has video output capability. */ - if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) - ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC); - else - ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); - if (itv->options.tuner > -1) { struct tuner_setup setup; @@ -1225,6 +1176,43 @@ static int __devinit ivtv_probe(struct pci_dev *dev, itv->std_out = itv->std; ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std); ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf); + + retval = ivtv_streams_setup(itv); + if (retval) { + IVTV_ERR("Error %d setting up streams\n", retval); + goto free_i2c; + } + + if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { + ivtv_init_mpeg_decoder(itv); + } + + IVTV_DEBUG_IRQ("Masking interrupts\n"); + /* clear interrupt mask, effectively disabling interrupts */ + ivtv_set_irq_mask(itv, 0xffffffff); + + /* Register IRQ */ + retval = request_irq(itv->dev->irq, ivtv_irq_handler, + IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv); + if (retval) { + IVTV_ERR("Failed to register irq %d\n", retval); + goto free_streams; + } + + /* On a cx23416 this seems to be able to enable DMA to the chip? */ + if (!itv->has_cx23415) + write_reg_sync(0x03, IVTV_REG_DMACONTROL); + + /* Default interrupts enabled. For the PVR350 this includes the + decoder VSYNC interrupt, which is always on. It is not only used + during decoding but also by the OSD. + Some old PVR250 cards had a cx23415, so testing for that is too + general. Instead test if the card has video output capability. */ + if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) + ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC); + else + ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); + if (itv->has_cx23415) ivtv_set_osd_alpha(itv); @@ -1246,8 +1234,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, if (itv->has_cx23415) release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); free_workqueue: - destroy_workqueue(itv->vbi.work_queues); - destroy_workqueue(itv->yuv_info.work_queues); + destroy_workqueue(itv->irq_work_queues); err: if (retval == 0) retval = -ENODEV; @@ -1289,10 +1276,8 @@ static void ivtv_remove(struct pci_dev *pci_dev) /* Stop all Work Queues */ IVTV_DEBUG_INFO(" Stop Work Queues.\n"); - flush_workqueue(itv->vbi.work_queues); - flush_workqueue(itv->yuv_info.work_queues); - destroy_workqueue(itv->vbi.work_queues); - destroy_workqueue(itv->yuv_info.work_queues); + flush_workqueue(itv->irq_work_queues); + destroy_workqueue(itv->irq_work_queues); IVTV_DEBUG_INFO(" Stopping Firmware.\n"); ivtv_halt_firmware(itv); @@ -1349,7 +1334,7 @@ static int module_start(void) printk(KERN_INFO "ivtv: debug value must be >= 0 and <= 511!\n"); } - if (pci_module_init(&ivtv_pci_driver)) { + if (pci_register_driver(&ivtv_pci_driver)) { printk(KERN_ERR "ivtv: Error detecting PCI card\n"); return -ENODEV; } @@ -1361,6 +1346,8 @@ static void module_cleanup(void) { int i, j; + pci_unregister_driver(&ivtv_pci_driver); + for (i = 0; i < ivtv_cards_active; i++) { if (ivtv_cards[i] == NULL) continue; @@ -1369,9 +1356,10 @@ static void module_cleanup(void) } kfree(ivtv_cards[i]); } - pci_unregister_driver(&ivtv_pci_driver); } +/* Note: These symbols are exported because they are used by the ivtv-fb + framebuffer module and an infrared module for the IR-blaster. */ EXPORT_SYMBOL(ivtv_set_irq_mask); EXPORT_SYMBOL(ivtv_cards_active); EXPORT_SYMBOL(ivtv_cards); diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h index e62734dd0..e84caa59b 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.h +++ b/linux/drivers/media/video/ivtv/ivtv-driver.h @@ -386,28 +386,29 @@ struct ivtv_mailbox_data { #define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */ /* per-ivtv, i_flags */ -#define IVTV_F_I_DMA 0 /* DMA in progress */ -#define IVTV_F_I_UDMA 1 /* UDMA in progress */ -#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */ - -#define IVTV_F_I_SPEED_CHANGE 3 /* A speed change is in progress */ -#define IVTV_F_I_EOS 4 /* End of encoder stream reached */ -#define IVTV_F_I_RADIO_USER 5 /* The radio tuner is selected */ -#define IVTV_F_I_DIG_RST 6 /* Reset digitizer */ -#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */ -#define IVTV_F_I_ENC_VBI 8 /* VBI DMA */ -#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */ -#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */ -#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */ -#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */ -#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */ +#define IVTV_F_I_DMA 0 /* DMA in progress */ +#define IVTV_F_I_UDMA 1 /* UDMA in progress */ +#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */ +#define IVTV_F_I_SPEED_CHANGE 3 /* A speed change is in progress */ +#define IVTV_F_I_EOS 4 /* End of encoder stream reached */ +#define IVTV_F_I_RADIO_USER 5 /* The radio tuner is selected */ +#define IVTV_F_I_DIG_RST 6 /* Reset digitizer */ +#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */ +#define IVTV_F_I_ENC_VBI 8 /* VBI DMA */ +#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */ +#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */ +#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */ +#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */ +#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */ #define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */ +#define IVTV_F_I_WORK_HANDLER_VBI 15 /* there is work to be done for VBI */ +#define IVTV_F_I_WORK_HANDLER_YUV 16 /* there is work to be done for YUV */ /* Event notifications */ -#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ -#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */ -#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */ -#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */ +#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ +#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */ +#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */ +#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */ /* Scatter-Gather array element, used in DMA transfers */ struct ivtv_SG_element { @@ -508,6 +509,7 @@ struct ivtv_stream { struct ivtv_open_id { u32 open_id; int type; + enum v4l2_priority prio; struct ivtv *itv; }; @@ -619,8 +621,6 @@ struct yuv_playback_info u32 yuv_forced_update; int update_frame; - struct workqueue_struct *work_queues; - struct work_struct work_queue; struct yuv_frame_info new_frame_info[4]; struct yuv_frame_info old_frame_info; struct yuv_frame_info old_frame_info_args; @@ -683,8 +683,6 @@ struct vbi_info { struct ivtv_buffer sliced_mpeg_buf; u32 inserted_frame; - struct workqueue_struct *work_queues; - struct work_struct work_queue; u32 start[2], count; u32 raw_size; u32 sliced_size; @@ -741,6 +739,10 @@ struct ivtv { u32 base_addr; u32 irqmask; + + struct v4l2_prio_state prio; + struct workqueue_struct *irq_work_queues; + struct work_struct irq_work_queue; struct timer_list dma_timer; /* Timer used to catch unfinished DMAs */ struct vbi_info vbi; diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c index 2f38bb14a..1637097dd 100644 --- a/linux/drivers/media/video/ivtv/ivtv-fileops.c +++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c @@ -766,6 +766,8 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp) IVTV_DEBUG_IOCTL("close() of %s\n", s->name); + v4l2_prio_close(&itv->prio, &id->prio); + /* Easy case first: this stream was never claimed by us */ if (s->id != id->open_id) { kfree(id); @@ -849,6 +851,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) } item->itv = itv; item->type = y; + v4l2_prio_open(&itv->prio, &item->prio); item->open_id = itv->open_id++; filp->private_data = item; diff --git a/linux/drivers/media/video/ivtv/ivtv-i2c.c b/linux/drivers/media/video/ivtv/ivtv-i2c.c index d6cb9e7e6..ef88c83a3 100644 --- a/linux/drivers/media/video/ivtv/ivtv-i2c.c +++ b/linux/drivers/media/video/ivtv/ivtv-i2c.c @@ -62,6 +62,7 @@ #include "ivtv-driver.h" #include "ivtv-cards.h" #include "ivtv-gpio.h" +#include "ivtv-i2c.h" #include <media/ir-kbd-i2c.h> @@ -547,7 +548,7 @@ static struct i2c_algo_bit_data ivtv_i2c_algo_template = { }; static struct i2c_client ivtv_i2c_client_template = { - .name = "ivtv internal use only", + .name = "ivtv internal", }; int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg) diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index f8107e337..d6f0b0235 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -277,6 +277,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, switch (vc->cmd) { case VIDEO_CMD_PLAY: { + vc->flags = 0; vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed); if (vc->play.speed < 0) vc->play.format = VIDEO_PLAY_FMT_GOP; @@ -288,6 +289,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, } case VIDEO_CMD_STOP: + vc->flags &= ~(VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK); if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY) vc->stop.pts = 0; if (try) break; @@ -300,6 +302,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts); case VIDEO_CMD_FREEZE: + vc->flags &= ~VIDEO_CMD_FREEZE_TO_BLACK; if (try) break; if (itv->output_mode != OUT_MPG) return -EBUSY; @@ -310,6 +313,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, break; case VIDEO_CMD_CONTINUE: + vc->flags = 0; if (try) break; if (itv->output_mode != OUT_MPG) return -EBUSY; @@ -638,7 +642,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, return 0; } -static int ivtv_internal_ioctls(struct file *filp, unsigned int cmd, void *arg) +static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg) { struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; struct ivtv *itv = id->itv; @@ -647,7 +651,6 @@ static int ivtv_internal_ioctls(struct file *filp, unsigned int cmd, void *arg) switch (cmd) { /* ioctls to allow direct access to the encoder registers for testing */ case VIDIOC_DBG_G_REGISTER: - IVTV_DEBUG_IOCTL("VIDIOC_DBG_G_REGISTER\n"); if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) return ivtv_itvc(itv, cmd, arg); if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) @@ -655,7 +658,6 @@ static int ivtv_internal_ioctls(struct file *filp, unsigned int cmd, void *arg) return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg); case VIDIOC_DBG_S_REGISTER: - IVTV_DEBUG_IOCTL("VIDIOC_DBG_S_REGISTER\n"); if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) return ivtv_itvc(itv, cmd, arg); if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) @@ -665,7 +667,6 @@ static int ivtv_internal_ioctls(struct file *filp, unsigned int cmd, void *arg) case VIDIOC_G_CHIP_IDENT: { struct v4l2_chip_ident *chip = arg; - IVTV_DEBUG_IOCTL("VIDIOC_G_CHIP_IDENT\n"); chip->ident = V4L2_IDENT_NONE; chip->revision = 0; if (reg->match_type == V4L2_CHIP_MATCH_HOST) { @@ -686,13 +687,11 @@ static int ivtv_internal_ioctls(struct file *filp, unsigned int cmd, void *arg) case VIDIOC_INT_S_AUDIO_ROUTING: { struct v4l2_routing *route = arg; - IVTV_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING\n"); ivtv_audio_set_route(itv, route); break; } case VIDIOC_INT_RESET: - IVTV_DEBUG_IOCTL("VIDIOC_INT_RESET\n"); ivtv_reset_ir_gpio(itv); break; @@ -709,11 +708,24 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void if (filp) id = (struct ivtv_open_id *)filp->private_data; switch (cmd) { + case VIDIOC_G_PRIORITY: + { + enum v4l2_priority *p = arg; + + *p = v4l2_prio_max(&itv->prio); + break; + } + + case VIDIOC_S_PRIORITY: + { + enum v4l2_priority *prio = arg; + + return v4l2_prio_change(&itv->prio, &id->prio, *prio); + } + case VIDIOC_QUERYCAP:{ struct v4l2_capability *vcap = arg; - IVTV_DEBUG_IOCTL("VIDIOC_QUERYCAP\n"); - memset(vcap, 0, sizeof(*vcap)); strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */ strcpy(vcap->card, itv->card_name); /* card type */ @@ -730,15 +742,12 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_ENUMAUDIO:{ struct v4l2_audio *vin = arg; - IVTV_DEBUG_IOCTL("VIDIOC_ENUMAUDIO\n"); - return ivtv_get_audio_input(itv, vin->index, vin); } case VIDIOC_G_AUDIO:{ struct v4l2_audio *vin = arg; - IVTV_DEBUG_IOCTL("VIDIOC_G_AUDIO\n"); vin->index = itv->audio_input; return ivtv_get_audio_input(itv, vin->index, vin); } @@ -746,8 +755,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_S_AUDIO:{ struct v4l2_audio *vout = arg; - IVTV_DEBUG_IOCTL("VIDIOC_S_AUDIO\n"); - if (vout->index >= itv->nof_audio_inputs) return -EINVAL; itv->audio_input = vout->index; @@ -758,8 +765,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_ENUMAUDOUT:{ struct v4l2_audioout *vin = arg; - IVTV_DEBUG_IOCTL("VIDIOC_ENUMAUDOUT\n"); - /* set it to defaults from our table */ return ivtv_get_audio_output(itv, vin->index, vin); } @@ -767,7 +772,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_G_AUDOUT:{ struct v4l2_audioout *vin = arg; - IVTV_DEBUG_IOCTL("VIDIOC_G_AUDOUT\n"); vin->index = 0; return ivtv_get_audio_output(itv, vin->index, vin); } @@ -775,16 +779,12 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_S_AUDOUT:{ struct v4l2_audioout *vout = arg; - IVTV_DEBUG_IOCTL("VIDIOC_S_AUDOUT\n"); - return ivtv_get_audio_output(itv, vout->index, vout); } case VIDIOC_ENUMINPUT:{ struct v4l2_input *vin = arg; - IVTV_DEBUG_IOCTL("VIDIOC_ENUMINPUT\n"); - /* set it to defaults from our table */ return ivtv_get_input(itv, vin->index, vin); } @@ -792,8 +792,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_ENUMOUTPUT:{ struct v4l2_output *vout = arg; - IVTV_DEBUG_IOCTL("VIDIOC_ENUMOUTPUT\n"); - return ivtv_get_output(itv, vout->index, vout); } @@ -801,11 +799,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_S_FMT: { struct v4l2_format *fmt = arg; - if (cmd == VIDIOC_S_FMT) { - IVTV_DEBUG_IOCTL("VIDIOC_S_FMT\n"); - } else { - IVTV_DEBUG_IOCTL("VIDIOC_TRY_FMT\n"); - } return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT); } @@ -813,7 +806,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void struct v4l2_format *fmt = arg; int type = fmt->type; - IVTV_DEBUG_IOCTL("VIDIOC_G_FMT\n"); memset(fmt, 0, sizeof(*fmt)); fmt->type = type; return ivtv_get_fmt(itv, id->type, fmt); @@ -822,7 +814,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_S_CROP: { struct v4l2_crop *crop = arg; - IVTV_DEBUG_IOCTL("VIDIOC_S_CROP\n"); if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; return itv->video_dec_func(itv, VIDIOC_S_CROP, arg); @@ -831,7 +822,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_G_CROP: { struct v4l2_crop *crop = arg; - IVTV_DEBUG_IOCTL("VIDIOC_G_CROP\n"); if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; return itv->video_dec_func(itv, VIDIOC_G_CROP, arg); @@ -869,8 +859,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void } case VIDIOC_G_INPUT:{ - IVTV_DEBUG_IOCTL("VIDIOC_G_INPUT\n"); - *(int *)arg = itv->active_input; break; } @@ -878,8 +866,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_S_INPUT:{ int inp = *(int *)arg; - IVTV_DEBUG_IOCTL("VIDIOC_S_INPUT\n"); - if (inp < 0 || inp >= itv->nof_inputs) return -EINVAL; @@ -905,8 +891,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void } case VIDIOC_G_OUTPUT:{ - IVTV_DEBUG_IOCTL("VIDIOC_G_OUTPUT\n"); - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; *(int *)arg = itv->active_output; @@ -917,8 +901,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void int outp = *(int *)arg; struct v4l2_routing route; - IVTV_DEBUG_IOCTL("VIDIOC_S_OUTPUT\n"); - if (outp >= itv->card->nof_outputs) return -EINVAL; @@ -939,8 +921,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_G_FREQUENCY:{ struct v4l2_frequency *vf = arg; - IVTV_DEBUG_IOCTL("VIDIOC_G_FREQUENCY\n"); - if (vf->tuner != 0) return -EINVAL; ivtv_call_i2c_clients(itv, cmd, arg); @@ -950,8 +930,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_S_FREQUENCY:{ struct v4l2_frequency vf = *(struct v4l2_frequency *)arg; - IVTV_DEBUG_IOCTL("VIDIOC_S_FREQUENCY\n"); - if (vf.tuner != 0) return -EINVAL; @@ -966,8 +944,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void struct v4l2_standard *vs = arg; int idx = vs->index; - IVTV_DEBUG_IOCTL("VIDIOC_ENUMSTD\n"); - if (idx < 0 || idx >= ARRAY_SIZE(enum_stds)) return -EINVAL; @@ -980,7 +956,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void } case VIDIOC_G_STD:{ - IVTV_DEBUG_IOCTL("VIDIOC_G_STD\n"); *(v4l2_std_id *) arg = itv->std; break; } @@ -988,8 +963,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_S_STD: { v4l2_std_id std = *(v4l2_std_id *) arg; - IVTV_DEBUG_IOCTL("VIDIOC_S_STD\n"); - if ((std & V4L2_STD_ALL) == 0) return -EINVAL; @@ -1040,8 +1013,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */ struct v4l2_tuner *vt = arg; - IVTV_DEBUG_IOCTL("VIDIOC_S_TUNER\n"); - if (vt->index != 0) return -EINVAL; @@ -1052,8 +1023,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void case VIDIOC_G_TUNER: { struct v4l2_tuner *vt = arg; - IVTV_DEBUG_IOCTL("VIDIOC_G_TUNER\n"); - if (vt->index != 0) return -EINVAL; @@ -1080,7 +1049,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void enum v4l2_buf_type type = VIDIOC_G_SLICED_VBI_CAP; #endif - IVTV_DEBUG_IOCTL("VIDIOC_G_SLICED_VBI_CAP\n"); memset(cap, 0, sizeof(*cap)); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) cap->type = type; @@ -1110,6 +1078,104 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void return -EINVAL; } + case VIDIOC_G_ENC_INDEX: { + struct v4l2_enc_idx *idx = arg; + int i; + + idx->entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) % + IVTV_MAX_PGM_INDEX; + if (idx->entries > V4L2_ENC_IDX_ENTRIES) + idx->entries = V4L2_ENC_IDX_ENTRIES; + for (i = 0; i < idx->entries; i++) { + idx->entry[i] = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX]; + } + itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX; + break; + } + + case VIDIOC_ENCODER_CMD: + case VIDIOC_TRY_ENCODER_CMD: { + struct v4l2_encoder_cmd *enc = arg; + int try = cmd == VIDIOC_TRY_ENCODER_CMD; + + memset(&enc->raw, 0, sizeof(enc->raw)); + switch (enc->cmd) { + case V4L2_ENC_CMD_START: + enc->flags = 0; + if (try) + return 0; + return ivtv_start_capture(id); + + case V4L2_ENC_CMD_STOP: + enc->flags &= ~V4L2_ENC_CMD_STOP_AT_GOP_END; + if (try) + return 0; + ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); + return 0; + + case V4L2_ENC_CMD_PAUSE: + enc->flags = 0; + if (try) + return 0; + if (!atomic_read(&itv->capturing)) + return -EPERM; + if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) + return 0; + ivtv_mute(itv); + ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0); + break; + + case V4L2_ENC_CMD_RESUME: + enc->flags = 0; + if (try) + return 0; + if (!atomic_read(&itv->capturing)) + return -EPERM; + if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) + return 0; + ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); + ivtv_unmute(itv); + break; + default: + return -EINVAL; + } + break; + } + + case VIDIOC_G_FBUF: { + struct v4l2_framebuffer *fb = arg; + + memset(fb, 0, sizeof(*fb)); + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + break; + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | + V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA; + fb->fmt.pixelformat = itv->osd_pixelformat; + fb->fmt.width = itv->osd_rect.width; + fb->fmt.height = itv->osd_rect.height; + fb->fmt.left = itv->osd_rect.left; + fb->fmt.top = itv->osd_rect.top; + fb->base = (void *)itv->osd_video_pbase; + if (itv->osd_global_alpha_state) + fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; + if (itv->osd_local_alpha_state) + fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; + if (itv->osd_color_key_state) + fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; + break; + } + + case VIDIOC_S_FBUF: { + struct v4l2_framebuffer *fb = arg; + + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + break; + itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; + itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; + itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; + break; + } + case VIDIOC_LOG_STATUS: { int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; @@ -1172,7 +1238,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void return 0; } -static int ivtv_ivtv_ioctls(struct file *filp, unsigned int cmd, void *arg) +static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) { struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; struct ivtv *itv = id->itv; @@ -1326,9 +1392,13 @@ static int ivtv_ivtv_ioctls(struct file *filp, unsigned int cmd, void *arg) ev->type = VIDEO_EVENT_DECODER_STOPPED; else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) { ev->type = VIDEO_EVENT_VSYNC; - ev->timestamp = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ? - 1 : 0; - clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); + ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ? + VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN; + if (itv->output_mode == OUT_UDMA_YUV && + (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) == + IVTV_YUV_MODE_PROGRESSIVE) { + ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE; + } } if (ev->type) return 0; @@ -1348,96 +1418,6 @@ static int ivtv_ivtv_ioctls(struct file *filp, unsigned int cmd, void *arg) break; } - case VIDIOC_G_ENC_INDEX: { - struct v4l2_enc_idx *idx = arg; - int i; - - IVTV_DEBUG_IOCTL("VIDIOC_G_ENC_INDEX\n"); - idx->entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) % - IVTV_MAX_PGM_INDEX; - if (idx->entries > V4L2_ENC_IDX_ENTRIES) - idx->entries = V4L2_ENC_IDX_ENTRIES; - for (i = 0; i < idx->entries; i++) { - idx->entry[i] = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX]; - } - itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX; - break; - } - - case VIDIOC_ENCODER_CMD: - case VIDIOC_TRY_ENCODER_CMD: { - struct v4l2_encoder_cmd *enc = arg; - int try = cmd == VIDIOC_TRY_ENCODER_CMD; - - if (try) - IVTV_DEBUG_IOCTL("VIDIOC_TRY_ENCODER_CMD\n"); - else - IVTV_DEBUG_IOCTL("VIDIOC_ENCODER_CMD\n"); - switch (enc->cmd) { - case V4L2_ENC_CMD_START: - return ivtv_start_capture(id); - - case V4L2_ENC_CMD_STOP: - ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); - return 0; - - case V4L2_ENC_CMD_PAUSE: - if (!atomic_read(&itv->capturing)) - return -EPERM; - if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) - return 0; - ivtv_mute(itv); - ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0); - break; - - case V4L2_ENC_CMD_RESUME: - if (!atomic_read(&itv->capturing)) - return -EPERM; - if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) - return 0; - ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); - ivtv_unmute(itv); - break; - } - break; - } - - case VIDIOC_G_FBUF: { - struct v4l2_framebuffer *fb = arg; - - IVTV_DEBUG_IOCTL("VIDIOC_G_FBUF\n"); - memset(fb, 0, sizeof(*fb)); - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - break; - fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | - V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA; - fb->fmt.pixelformat = itv->osd_pixelformat; - fb->fmt.width = itv->osd_rect.width; - fb->fmt.height = itv->osd_rect.height; - fb->fmt.left = itv->osd_rect.left; - fb->fmt.top = itv->osd_rect.top; - fb->base = (void *)itv->osd_video_pbase; - if (itv->osd_global_alpha_state) - fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; - if (itv->osd_local_alpha_state) - fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; - if (itv->osd_color_key_state) - fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; - break; - } - - case VIDIOC_S_FBUF: { - struct v4l2_framebuffer *fb = arg; - - IVTV_DEBUG_IOCTL("VIDIOC_S_FBUF\n"); - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - break; - itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; - itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; - itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; - break; - } - default: return -EINVAL; } @@ -1449,8 +1429,26 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, { struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; struct ivtv *itv = id->itv; + int ret; - IVTV_DEBUG_IOCTL("v4l2 ioctl 0x%08x\n", cmd); + /* check priority */ + switch (cmd) { + case VIDIOC_S_CTRL: + case VIDIOC_S_STD: + case VIDIOC_S_INPUT: + case VIDIOC_S_OUTPUT: + case VIDIOC_S_TUNER: + case VIDIOC_S_FREQUENCY: + case VIDIOC_S_FMT: + case VIDIOC_S_CROP: + case VIDIOC_S_AUDIO: + case VIDIOC_S_AUDOUT: + case VIDIOC_S_EXT_CTRLS: + case VIDIOC_S_FBUF: + ret = v4l2_prio_check(&itv->prio, &id->prio); + if (ret) + return ret; + } switch (cmd) { case VIDIOC_DBG_G_REGISTER: @@ -1458,8 +1456,14 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, case VIDIOC_G_CHIP_IDENT: case VIDIOC_INT_S_AUDIO_ROUTING: case VIDIOC_INT_RESET: - return ivtv_internal_ioctls(filp, cmd, arg); + if (ivtv_debug & IVTV_DBGFLG_IOCTL) { + printk(KERN_INFO "ivtv%d ioctl: ", itv->num); + v4l_printk_ioctl(cmd); + } + return ivtv_debug_ioctls(filp, cmd, arg); + case VIDIOC_G_PRIORITY: + case VIDIOC_S_PRIORITY: case VIDIOC_QUERYCAP: case VIDIOC_ENUMINPUT: case VIDIOC_G_INPUT: @@ -1488,6 +1492,15 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, case VIDIOC_G_AUDOUT: case VIDIOC_G_SLICED_VBI_CAP: case VIDIOC_LOG_STATUS: + case VIDIOC_G_ENC_INDEX: + case VIDIOC_ENCODER_CMD: + case VIDIOC_TRY_ENCODER_CMD: + case VIDIOC_G_FBUF: + case VIDIOC_S_FBUF: + if (ivtv_debug & IVTV_DBGFLG_IOCTL) { + printk(KERN_INFO "ivtv%d ioctl: ", itv->num); + v4l_printk_ioctl(cmd); + } return ivtv_v4l2_ioctls(itv, filp, cmd, arg); case VIDIOC_QUERYMENU: @@ -1497,6 +1510,10 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, case VIDIOC_S_EXT_CTRLS: case VIDIOC_G_EXT_CTRLS: case VIDIOC_TRY_EXT_CTRLS: + if (ivtv_debug & IVTV_DBGFLG_IOCTL) { + printk(KERN_INFO "ivtv%d ioctl: ", itv->num); + v4l_printk_ioctl(cmd); + } return ivtv_control_ioctls(itv, cmd, arg); case IVTV_IOC_DMA_FRAME: @@ -1509,12 +1526,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, case VIDEO_CONTINUE: case VIDEO_COMMAND: case VIDEO_TRY_COMMAND: - case VIDIOC_G_ENC_INDEX: - case VIDIOC_ENCODER_CMD: - case VIDIOC_TRY_ENCODER_CMD: - case VIDIOC_G_FBUF: - case VIDIOC_S_FBUF: - return ivtv_ivtv_ioctls(filp, cmd, arg); + return ivtv_decoder_ioctls(filp, cmd, arg); case 0x00005401: /* Handle isatty() calls */ return -EINVAL; diff --git a/linux/drivers/media/video/ivtv/ivtv-irq.c b/linux/drivers/media/video/ivtv/ivtv-irq.c index da00d7c9a..e87a4dc37 100644 --- a/linux/drivers/media/video/ivtv/ivtv-irq.c +++ b/linux/drivers/media/video/ivtv/ivtv-irq.c @@ -27,6 +27,7 @@ #include "ivtv-ioctl.h" #include "ivtv-mailbox.h" #include "ivtv-vbi.h" +#include "ivtv-yuv.h" #define DMA_MAGIC_COOKIE 0x000001fe @@ -49,6 +50,25 @@ static inline int ivtv_use_pio(struct ivtv_stream *s) (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) +void ivtv_irq_work_handler(struct work_struct *work) +{ + struct ivtv *itv = container_of(work, struct ivtv, irq_work_queue); +#else +void ivtv_irq_work_handler(void *arg) +{ + struct ivtv *itv = arg; +#endif + + DEFINE_WAIT(wait); + + if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags)) + vbi_work_handler(itv); + + if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags)) + ivtv_yuv_work_handler(itv); +} + /* Determine the required DMA size, setup enough buffers in the predma queue and actually copy the data from the card to the buffers in case a PIO transfer is required for this stream. @@ -643,6 +663,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) } if (frame != (itv->lastVsyncFrame & 1)) { struct ivtv_stream *s = ivtv_get_output_stream(itv); + int work = 0; itv->lastVsyncFrame += 1; if (frame == 0) { @@ -661,8 +682,10 @@ static void ivtv_irq_vsync(struct ivtv *itv) wake_up(&s->waitq); /* Send VBI to saa7127 */ - if (frame) - vbi_schedule_work(itv); + if (frame) { + set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags); + work = 1; + } /* Check if we need to update the yuv registers */ if ((itv->yuv_info.yuv_forced_update || itv->yuv_info.new_frame_info[last_dma_frame].update) && last_dma_frame != -1) { @@ -673,9 +696,12 @@ static void ivtv_irq_vsync(struct ivtv *itv) itv->yuv_info.update_frame = last_dma_frame; itv->yuv_info.new_frame_info[last_dma_frame].update = 0; itv->yuv_info.yuv_forced_update = 0; - queue_work(itv->yuv_info.work_queues, &itv->yuv_info.work_queue); + set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags); + work = 1; } } + if (work) + queue_work(itv->irq_work_queues, &itv->irq_work_queue); } } diff --git a/linux/drivers/media/video/ivtv/ivtv-irq.h b/linux/drivers/media/video/ivtv/ivtv-irq.h index 7345a9660..77fca605f 100644 --- a/linux/drivers/media/video/ivtv/ivtv-irq.h +++ b/linux/drivers/media/video/ivtv/ivtv-irq.h @@ -24,5 +24,11 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id, struct pt_regs *regs); #else irqreturn_t ivtv_irq_handler(int irq, void *dev_id); #endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) +void ivtv_irq_work_handler(struct work_struct *work); +#else +void ivtv_irq_work_handler(void *arg); +#endif void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock); void ivtv_unfinished_dma(unsigned long arg); diff --git a/linux/drivers/media/video/ivtv/ivtv-vbi.c b/linux/drivers/media/video/ivtv/ivtv-vbi.c index 71acc97b1..5efa5a867 100644 --- a/linux/drivers/media/video/ivtv/ivtv-vbi.c +++ b/linux/drivers/media/video/ivtv/ivtv-vbi.c @@ -32,11 +32,6 @@ static int odd_parity(u8 c) return c & 1; } -void vbi_schedule_work(struct ivtv *itv) -{ - queue_work(itv->vbi.work_queues, &itv->vbi.work_queue); -} - static void passthrough_vbi_data(struct ivtv *itv, int cnt) { int wss = 0; @@ -454,18 +449,10 @@ void ivtv_disable_vbi(struct ivtv *itv) itv->vbi.cc_pos = 0; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -void vbi_work_handler(struct work_struct *work) -{ - struct vbi_info *info = container_of(work, struct vbi_info, work_queue); - struct ivtv *itv = container_of(info, struct ivtv, vbi); -#else -void vbi_work_handler(void *arg) + +void vbi_work_handler(struct ivtv *itv) { - struct ivtv *itv = arg; -#endif struct v4l2_sliced_vbi_data data; - DEFINE_WAIT(wait); /* Lock */ if (itv->output_mode == OUT_PASSTHROUGH) { diff --git a/linux/drivers/media/video/ivtv/ivtv-vbi.h b/linux/drivers/media/video/ivtv/ivtv-vbi.h index b30e5dff7..cdaea697b 100644 --- a/linux/drivers/media/video/ivtv/ivtv-vbi.h +++ b/linux/drivers/media/video/ivtv/ivtv-vbi.h @@ -23,9 +23,4 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, int ivtv_used_line(struct ivtv *itv, int line, int field); void ivtv_disable_vbi(struct ivtv *itv); void ivtv_set_vbi(unsigned long arg); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -void vbi_work_handler(struct work_struct *work); -#else -void vbi_work_handler(void *arg); -#endif -void vbi_schedule_work(struct ivtv *itv); +void vbi_work_handler(struct ivtv *itv); diff --git a/linux/drivers/media/video/ivtv/ivtv-yuv.c b/linux/drivers/media/video/ivtv/ivtv-yuv.c index 04d93a753..286a0d7e7 100644 --- a/linux/drivers/media/video/ivtv/ivtv-yuv.c +++ b/linux/drivers/media/video/ivtv/ivtv-yuv.c @@ -22,6 +22,7 @@ #include "ivtv-queue.h" #include "ivtv-udma.h" #include "ivtv-irq.h" +#include "ivtv-yuv.h" static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, struct ivtv_dma_frame *args) @@ -804,18 +805,8 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo } /* Update the scaling register to the requested value */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -void ivtv_yuv_work_handler (struct work_struct *work) +void ivtv_yuv_work_handler (struct ivtv *itv) { - struct yuv_playback_info *info = container_of(work, struct yuv_playback_info, work_queue); - struct ivtv *itv = container_of(info, struct ivtv, yuv_info); -#else -void ivtv_yuv_work_handler (void *arg) -{ - struct ivtv *itv = arg; -#endif - DEFINE_WAIT(wait); - struct yuv_frame_info window; u32 yuv_update; diff --git a/linux/drivers/media/video/ivtv/ivtv-yuv.h b/linux/drivers/media/video/ivtv/ivtv-yuv.h index 74c56da6d..88972d3f7 100644 --- a/linux/drivers/media/video/ivtv/ivtv-yuv.h +++ b/linux/drivers/media/video/ivtv/ivtv-yuv.h @@ -21,8 +21,4 @@ int ivtv_yuv_filter_check(struct ivtv *itv); int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args); void ivtv_yuv_close(struct ivtv *itv); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -void ivtv_yuv_work_handler (struct work_struct *work); -#else -void ivtv_yuv_work_handler (void *arg); -#endif +void ivtv_yuv_work_handler (struct ivtv *itv); diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c index 0e21a5b57..d6364b01f 100644 --- a/linux/drivers/media/video/msp3400-driver.c +++ b/linux/drivers/media/video/msp3400-driver.c @@ -829,7 +829,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) +static int msp_suspend(struct i2c_client *client, pm_message_t state) +#else static int msp_suspend(struct device * dev, pm_message_t state) +#endif #else #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) static int msp_suspend(struct device * dev, pm_message_t state, u32 level) @@ -838,7 +842,9 @@ static int msp_suspend(struct device * dev, u32 state, u32 level) #endif #endif { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20) struct i2c_client *client = container_of(dev, struct i2c_client, dev); +#endif v4l_dbg(1, msp_debug, client, "suspend\n"); msp_reset(client); @@ -846,12 +852,18 @@ static int msp_suspend(struct device * dev, u32 state, u32 level) } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) +static int msp_resume(struct i2c_client *client) +#else static int msp_resume(struct device * dev) +#endif #else static int msp_resume(struct device * dev, u32 level) #endif { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20) struct i2c_client *client = container_of(dev, struct i2c_client, dev); +#endif v4l_dbg(1, msp_debug, client, "resume\n"); msp_wake_thread(client); @@ -894,7 +906,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) if (msp_reset(client) == -1) { v4l_dbg(1, msp_debug, client, "msp3400 not found\n"); kfree(client); - return -1; + return 0; } state = kmalloc(sizeof(*state), GFP_KERNEL); @@ -928,7 +940,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) v4l_dbg(1, msp_debug, client, "not an msp3400 (cannot read chip version)\n"); kfree(state); kfree(client); - return -1; + return 0; } #if 0 @@ -1110,14 +1122,20 @@ static struct i2c_driver i2c_driver = { .id = I2C_DRIVERID_MSP3400, .attach_adapter = msp_probe, .detach_client = msp_detach, +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) + .suspend = msp_suspend, + .resume = msp_resume, +#endif .command = msp_command, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .driver = { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) .name = "msp3400", #endif +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20) .suspend = msp_suspend, .resume = msp_resume, +#endif }, #endif }; diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 064a81334..74c89b458 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -973,7 +973,7 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) reg |= 0x10; } else if (std == V4L2_STD_NTSC_M_JP) { reg |= 0x40; - } else if (std == V4L2_STD_SECAM) { + } else if (std & V4L2_STD_SECAM) { reg |= 0x50; } saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); @@ -1505,6 +1505,7 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind) if (memcmp(name, "1f711", 5)) { v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n", address << 1, name); + kfree(client); return 0; } diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 9d0afdfe1..ce0ed4095 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -286,7 +286,7 @@ static void request_submodules(struct saa7134_dev *dev) #endif #else -#define request_submodules() +#define request_submodules(dev) #endif /* CONFIG_MODULES */ /* ------------------------------------------------------------------ */ diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c index ddee1ae81..4de46b2d7 100644 --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -61,8 +61,12 @@ static int debug = 0; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off module debugging (default:off)."); -#define dprintk(fmt, arg...) if (debug) \ - printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg) +#define dprintk(fmt, arg...) do { if (debug) \ + printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg); } while(0) + +/* Print a warning */ +#define wprintk(fmt, arg...) \ + printk(KERN_WARNING "%s/dvb: " fmt, dev->name, ## arg) /* ------------------------------------------------------------------ * mt352 based DVB-T cards @@ -88,8 +92,7 @@ static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on) saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28)); udelay(10); ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27); - printk("%s: %s %s\n", dev->name, __FUNCTION__, - ok ? "on" : "off"); + dprintk("%s %s\n", __FUNCTION__, ok ? "on" : "off"); if (!ok) saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26)); @@ -109,7 +112,7 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe) static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 }; struct saa7134_dev *dev= fe->dvb->priv; - printk("%s: %s called\n",dev->name,__FUNCTION__); + dprintk("%s called\n", __FUNCTION__); mt352_write(fe, clock_config, sizeof(clock_config)); udelay(200); @@ -293,7 +296,8 @@ static int philips_tda6651_pll_set(struct dvb_frontend *fe, struct dvb_frontend_ if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) { - printk("%s/dvb: could not write to tuner at addr: 0x%02x\n",dev->name, addr << 1); + wprintk("could not write to tuner at addr: 0x%02x\n", + addr << 1); return -EIO; } msleep(1); @@ -563,7 +567,8 @@ static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_ if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) { - printk("%s/dvb: could not write to tuner at addr: 0x%02x\n",dev->name, addr << 1); + wprintk("could not write to tuner at addr: 0x%02x\n", + addr << 1); return -EIO; } return 0; @@ -610,7 +615,8 @@ static void philips_tda827x_lna_gain(struct dvb_frontend *fe, int high) saa7134_set_gpio(dev, 22, 0); GP00_LEV[1] = high ? 0 : 1; if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { - printk("%s/dvb: could not access tda8290 at addr: 0x%02x\n",dev->name, addr << 1); + wprintk("could not access tda8290 at addr: 0x%02x\n", + addr << 1); return; } msg.buf = GP00_LEV; @@ -638,7 +644,8 @@ static int tda8290_i2c_gate_ctrl( struct dvb_frontend* fe, int enable) tda8290_msg.buf = tda8290_open; } if (i2c_transfer(state->i2c, &tda8290_msg, 1) != 1) { - printk("saa7134/dvb: could not access tda8290 I2C gate\n"); + struct saa7134_dev *dev = fe->dvb->priv; + wprintk("could not access tda8290 I2C gate\n"); return -EIO; } msleep(20); @@ -695,7 +702,7 @@ static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; if (dvb_attach(tda827x_attach, dev->dvb.frontend, tda_conf->tuner_address, &dev->i2c_adap,&tda827x_cfg) == NULL) { - printk ("saa7134/dvb: no tda827x tuner found at addr: %02x\n", + wprintk("no tda827x tuner found at addr: %02x\n", tda_conf->tuner_address); } } @@ -943,7 +950,7 @@ static int dvb_init(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: - printk("%s: pinnacle 300i dvb setup\n",dev->name); + dprintk("pinnacle 300i dvb setup\n"); dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i, &dev->i2c_adap); if (dev->dvb.frontend) { @@ -952,7 +959,7 @@ static int dvb_init(struct saa7134_dev *dev) break; case SAA7134_BOARD_AVERMEDIA_777: case SAA7134_BOARD_AVERMEDIA_A16AR: - printk("%s: avertv 777 dvb setup\n",dev->name); + dprintk("avertv 777 dvb setup\n"); dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, &dev->i2c_adap); if (dev->dvb.frontend) { @@ -1027,11 +1034,11 @@ static int dvb_init(struct saa7134_dev *dev) if (dev->dvb.frontend) { if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, &dev->i2c_adap, 0) == NULL) { - printk("%s: Lifeview Trio, No tda826x found!\n", __FUNCTION__); + wprintk("%s: Lifeview Trio, No tda826x found!\n", __FUNCTION__); } if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { - printk("%s: Lifeview Trio, No ISL6421 found!\n", __FUNCTION__); + wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __FUNCTION__); } } } @@ -1045,7 +1052,7 @@ static int dvb_init(struct saa7134_dev *dev) if (dvb_attach(tda827x_attach,dev->dvb.frontend, ads_tech_duo_config.tuner_address, &dev->i2c_adap,&ads_duo_cfg) == NULL) { - printk ("saa7134/dvb: no tda827x tuner found at addr: %02x\n", + wprintk("no tda827x tuner found at addr: %02x\n", ads_tech_duo_config.tuner_address); } } @@ -1078,11 +1085,11 @@ static int dvb_init(struct saa7134_dev *dev) if (dev->dvb.frontend) { if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { - printk("%s: No tda826x found!\n", __FUNCTION__); + wprintk("%s: No tda826x found!\n", __FUNCTION__); } if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { - printk("%s: No ISL6421 found!\n", __FUNCTION__); + wprintk("%s: No ISL6421 found!\n", __FUNCTION__); } } break; @@ -1116,12 +1123,12 @@ static int dvb_init(struct saa7134_dev *dev) configure_tda827x_fe(dev, &philips_tiger_s_config); break; default: - printk("%s: Huh? unknown DVB card?\n",dev->name); + wprintk("Huh? unknown DVB card?\n"); break; } if (NULL == dev->dvb.frontend) { - printk("%s: frontend initialization failed\n",dev->name); + printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); return -1; } diff --git a/linux/drivers/media/video/tea5761.c b/linux/drivers/media/video/tea5761.c index a0f075ed7..fc800f656 100644 --- a/linux/drivers/media/video/tea5761.c +++ b/linux/drivers/media/video/tea5761.c @@ -2,10 +2,8 @@ * For Philips TEA5761 FM Chip * I2C address is allways 0x20 (0x10 at 7-bit mode). * - * $Id: tea5761.c,v 1.5 2006/01/11 21:01:01 hverkuil Exp $ - * - * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) - * This code is placed under the terms of the GNU General Public License + * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org) + * This code is placed under the terms of the GNUv2 General Public License * */ @@ -233,8 +231,8 @@ int tea5761_tuner_init(struct i2c_client *c) tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5761HN FM Radio"); strlcpy(c->name, "tea5761", sizeof(c->name)); - t->tv_freq = set_tv_freq; - t->radio_freq = set_radio_freq; + t->set_tv_freq = set_tv_freq; + t->set_radio_freq = set_radio_freq; t->has_signal = tea5761_signal; t->is_stereo = tea5761_stereo; diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 1aac94868..e7bc60a5e 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -29,6 +29,9 @@ /* standard i2c insmod options */ static unsigned short normal_i2c[] = { +#ifdef CONFIG_TUNER_5761 + 0x10, +#endif 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, @@ -216,6 +219,16 @@ static void set_type(struct i2c_client *c, unsigned int type, } t->mode_mask = T_RADIO; break; +#ifdef CONFIG_TUNER_5761 + case TUNER_TEA5761: + if (tea5761_tuner_init(c) == EINVAL) { + t->type = TUNER_ABSENT; + t->mode_mask = T_UNINITIALIZED; + return -ENODEV; + } + t->mode_mask = T_RADIO; + break; +#endif case TUNER_PHILIPS_FMD1216ME_MK3: buffer[0] = 0x0b; buffer[1] = 0xdc; @@ -506,6 +519,19 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, /* autodetection code based on the i2c addr */ if (!no_autodetect) { switch (addr) { +#ifdef CONFIG_TUNER_5761 + case 0x10: + if (tea5761_autodetection(&t->i2c) != EINVAL) { + t->type = TUNER_TEA5761; + t->mode_mask = T_RADIO; + t->mode = T_STANDBY; + t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ + default_mode_mask &= ~T_RADIO; + + goto register_client; + } + break; +#endif case 0x42: case 0x43: case 0x4a: @@ -877,7 +903,11 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) +static int tuner_suspend(struct i2c_client *c, pm_message_t state) +#else static int tuner_suspend(struct device *dev, pm_message_t state) +#endif #else #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) static int tuner_suspend(struct device *dev, pm_message_t state, u32 level) @@ -886,7 +916,9 @@ static int tuner_suspend(struct device *dev, u32 state, u32 level) #endif #endif { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20) struct i2c_client *c = container_of (dev, struct i2c_client, dev); +#endif struct tuner *t = i2c_get_clientdata (c); tuner_dbg ("suspend\n"); @@ -895,12 +927,18 @@ static int tuner_suspend(struct device *dev, u32 state, u32 level) } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) +static int tuner_resume(struct i2c_client *c) +#else static int tuner_resume(struct device *dev) +#endif #else static int tuner_resume(struct device *dev, u32 level) #endif { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20) struct i2c_client *c = container_of (dev, struct i2c_client, dev); +#endif struct tuner *t = i2c_get_clientdata (c); tuner_dbg ("resume\n"); @@ -929,13 +967,19 @@ static struct i2c_driver driver = { .attach_adapter = tuner_probe, .detach_client = tuner_detach, .command = tuner_command, +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20) + .suspend = tuner_suspend, + .resume = tuner_resume, +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) .driver = { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) .name = "tuner", #endif +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20) .suspend = tuner_suspend, .resume = tuner_resume, +#endif }, #endif }; diff --git a/linux/drivers/media/video/tuner-types.c b/linux/drivers/media/video/tuner-types.c index 22b159d44..c644397b1 100644 --- a/linux/drivers/media/video/tuner-types.c +++ b/linux/drivers/media/video/tuner-types.c @@ -1511,6 +1511,10 @@ struct tunertype tuners[] = { .name = "Philips TDA988[5,6,7] IF PLL Demodulator", /* see tda9887.c for details */ }, + [TUNER_TEA5761] = { /* Philips RADIO */ + .name = "Philips TEA5761 FM Radio", + /* see tea5767.c for details */ + }, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c index 43017a006..61b99971e 100644 --- a/linux/drivers/media/video/tveeprom.c +++ b/linux/drivers/media/video/tveeprom.c @@ -167,7 +167,7 @@ hauppauge_tuner[] = /* 60-69 */ { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"}, { TUNER_ABSENT, "LG M001D MK3"}, - { TUNER_ABSENT, "LG S701D MK3"}, + { TUNER_PHILIPS_FM1216ME_MK3, "LG S701D MK3"}, { TUNER_ABSENT, "LG M701D MK3"}, { TUNER_ABSENT, "Temic 4146FM5"}, { TUNER_ABSENT, "Temic 4136FY5"}, diff --git a/linux/drivers/media/video/usbvideo/usbvideo.c b/linux/drivers/media/video/usbvideo/usbvideo.c index bf3482f98..ec47f3244 100644 --- a/linux/drivers/media/video/usbvideo/usbvideo.c +++ b/linux/drivers/media/video/usbvideo/usbvideo.c @@ -628,24 +628,21 @@ EXPORT_SYMBOL(usbvideo_HexDump); /* ******************************************************************** */ /* XXX: this piece of crap really wants some error handling.. */ -static void usbvideo_ClientIncModCount(struct uvd *uvd) +static int usbvideo_ClientIncModCount(struct uvd *uvd) { if (uvd == NULL) { err("%s: uvd == NULL", __FUNCTION__); - return; + return -EINVAL; } if (uvd->handle == NULL) { err("%s: uvd->handle == NULL", __FUNCTION__); - return; - } - if (uvd->handle->md_module == NULL) { - err("%s: uvd->handle->md_module == NULL", __FUNCTION__); - return; + return -EINVAL; } if (!try_module_get(uvd->handle->md_module)) { err("%s: try_module_get() == 0", __FUNCTION__); - return; + return -ENODEV; } + return 0; } static void usbvideo_ClientDecModCount(struct uvd *uvd) @@ -712,8 +709,6 @@ int usbvideo_register( cams->num_cameras = num_cams; cams->cam = (struct uvd *) &cams[1]; cams->md_module = md; - if (cams->md_module == NULL) - warn("%s: module == NULL!", __FUNCTION__); mutex_init(&cams->lock); /* to 1 == available */ for (i = 0; i < num_cams; i++) { @@ -1119,7 +1114,8 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) if (uvd->debug > 1) info("%s($%p)", __FUNCTION__, dev); - usbvideo_ClientIncModCount(uvd); + if (0 < usbvideo_ClientIncModCount(uvd)) + return -ENODEV; mutex_lock(&uvd->lock); if (uvd->user) { diff --git a/linux/drivers/media/video/usbvision/usbvision-cards.c b/linux/drivers/media/video/usbvision/usbvision-cards.c index 86442ccd2..b23672ad9 100644 --- a/linux/drivers/media/video/usbvision/usbvision-cards.c +++ b/linux/drivers/media/video/usbvision/usbvision-cards.c @@ -32,50 +32,59 @@ /* Supported Devices: A table for usbvision.c*/ struct usbvision_device_data_st usbvision_device_data[] = { - {0xFFF0, 0xFFF0, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Custom Dummy USBVision Device"}, - {0x0A6F, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "Xanboo"}, - {0x050D, 0x0208, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Belkin USBView II"}, + {0xfff0, 0xfff0, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Custom Dummy USBVision Device"}, + {0x0a6f, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "Xanboo"}, + {0x050d, 0x0106, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Belkin USB VideoBus II Adapter"}, + {0x050d, 0x0207, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "Belkin Components USB VideoBus"}, + {0x050d, 0x0208, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Belkin USB VideoBus II"}, {0x0571, 0x0002, 0, CODEC_SAA7111, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, -1, -1, 7, "echoFX InterView Lite"}, {0x0573, 0x0003, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "USBGear USBG-V1 resp. HAMA USB"}, {0x0573, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "D-Link V100"}, {0x0573, 0x2000, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "X10 USB Camera"}, - {0x0573, 0x2d00, -1, CODEC_SAA7111, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, -1, 3, 7, "Osprey 50"}, - {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge USB-Live Model 600"}, + {0x0573, 0x2d00, -1, CODEC_SAA7111, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, -1, 3, 7, "Hauppauge WinTV USB Live (PAL B/G)"}, + {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Live Pro (NTSC M/N)"}, {0x0573, 0x2101, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 2, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Zoran Co. PMD (Nogatech) AV-grabber Manhattan"}, {0x0573, 0x4100, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Nogatech USB-TV (NTSC) FM"}, {0x0573, 0x4110, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "PNY USB-TV (NTSC) FM"}, {0x0573, 0x4450, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "PixelView PlayTv-USB PRO (PAL) FM"}, {0x0573, 0x4550, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "ZTV ZT-721 2.4GHz USB A/V Receiver"}, - {0x0573, 0x4d00, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Hauppauge WinTv-USB USA"}, - {0x0573, 0x4d01, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB"}, - {0x0573, 0x4d02, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (NTSC)"}, - {0x0573, 0x4d03, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (SECAM) "}, - {0x0573, 0x4d10, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (NTSC) FM"}, - {0x0573, 0x4d11, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (PAL) FM"}, - {0x0573, 0x4d12, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB (PAL) FM"}, - {0x0573, 0x4d2a, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTv USB (NTSC) FM Model 602 40201 Rev B285"}, - {0x0573, 0x4d2b, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTv USB (NTSC) FM Model 602 40201 Rev B282"}, - {0x0573, 0x4d2c, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTv USB (PAL/SECAM) 40209 Rev E1A5"}, - {0x0573, 0x4d20, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB II (PAL) FM Model 40201 Rev B226"}, - {0x0573, 0x4d21, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB II (PAL)"}, - {0x0573, 0x4d22, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB II (PAL) MODEL 566"}, - {0x0573, 0x4d23, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB (SECAM) 4D23"}, - {0x0573, 0x4d25, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB (SECAM) Model 40209 Rev B234"}, - {0x0573, 0x4d26, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB (SECAM) Model 40209 Rev B243"}, - {0x0573, 0x4d27, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_ALPS_TSBE1_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB Model 40204 Rev B281"}, - {0x0573, 0x4d28, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_ALPS_TSBE1_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB Model 40204 Rev B283"}, - {0x0573, 0x4d29, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB Model 40205 Rev B298"}, - {0x0573, 0x4d30, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB FM Model 40211 Rev B123"}, - {0x0573, 0x4d31, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB III (PAL) FM Model 568"}, - {0x0573, 0x4d32, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB III (PAL) FM Model 573"}, - {0x0573, 0x4d35, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTv-USB III (PAL) FM Model 40219 Rev B252"}, - {0x0573, 0x4d37, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTV USB device Model 40219 Rev E189"}, + {0x0573, 0x4d00, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Hauppauge WinTV USB (NTSC M/N)"}, + {0x0573, 0x4d01, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL B/G)"}, + {0x0573, 0x4d02, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL I)"}, + {0x0573, 0x4d03, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL/SECAM L)"}, + {0x0573, 0x4d04, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL D/K)"}, + {0x0573, 0x4d10, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (NTSC FM)"}, + {0x0573, 0x4d11, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL B/G FM)"}, + {0x0573, 0x4d12, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL I FM)"}, + {0x0573, 0x4d14, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL D/K FM)"}, + {0x0573, 0x4d2a, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"}, + {0x0573, 0x4d2b, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"}, + {0x0573, 0x4d2c, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)"}, + {0x0573, 0x4d20, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"}, + {0x0573, 0x4d21, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G)"}, + {0x0573, 0x4d22, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I)"}, + {0x0573, 0x4d23, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM L)"}, + {0x0573, 0x4d24, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL D/K)"}, + {0x0573, 0x4d25, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)"}, + {0x0573, 0x4d26, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)"}, + {0x0573, 0x4d27, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_ALPS_TSBE1_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G)"}, + {0x0573, 0x4d28, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_ALPS_TSBE1_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G,D/K)"}, + {0x0573, 0x4d29, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I,D/K)"}, + {0x0573, 0x4d30, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N FM)"}, + {0x0573, 0x4d31, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G FM)"}, + {0x0573, 0x4d32, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I FM)"}, + {0x0573, 0x4d34, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL D/K FM)"}, + {0x0573, 0x4d35, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)"}, + {0x0573, 0x4d36, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (Temic PAL B/G FM)"}, + {0x0573, 0x4d37, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)"}, + {0x0573, 0x4d38, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N FM)"}, {0x0768, 0x0006, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 5, 5, -1, "Camtel Technology USB TV Genie Pro FM Model TVB330"}, {0x07d0, 0x0001, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Digital Video Creator I"}, {0x07d0, 0x0002, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 82, 20, 7, "Global Village GV-007 (NTSC)"}, {0x07d0, 0x0003, 0, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)"}, {0x07d0, 0x0004, 0, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-80 Rev 1 (PAL)"}, {0x07d0, 0x0005, 0, CODEC_SAA7113, 2, V4L2_STD_SECAM, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)"}, + {0x07f8, 0x9104, 0, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Eskape Labs MyTV2Go"}, {0x2304, 0x010d, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 0, 1, TUNER_TEMIC_4066FY5_PAL_I, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (PAL)"}, {0x2304, 0x0109, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (SECAM)"}, {0x2304, 0x0110, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1,128, 23, -1, "Pinnacle Studio PCTV USB (PAL) FM"}, @@ -94,50 +103,59 @@ struct usbvision_device_data_st usbvision_device_data[] = { /* Supported Devices */ struct usb_device_id usbvision_table [] = { - { USB_DEVICE(0xFFF0, 0xFFF0) }, /* Custom Dummy USBVision Device */ - { USB_DEVICE(0x0A6F, 0x0400) }, /* Xanboo */ - { USB_DEVICE(0x050d, 0x0208) }, /* Belkin USBView II */ + { USB_DEVICE(0xfff0, 0xfff0) }, /* Custom Dummy USBVision Device */ + { USB_DEVICE(0x0a6f, 0x0400) }, /* Xanboo */ + { USB_DEVICE(0x050d, 0x0106) }, /* Belkin USB VideoBus II Adapter */ + { USB_DEVICE(0x050d, 0x0207) }, /* Belkin Components USB VideoBus */ + { USB_DEVICE(0x050d, 0x0208) }, /* Belkin USB VideoBus II */ { USB_DEVICE(0x0571, 0x0002) }, /* echoFX InterView Lite */ - { USB_DEVICE(0x0573, 0x0003) }, /* USBGear USBG-V1 */ + { USB_DEVICE(0x0573, 0x0003) }, /* USBGear USBG-V1 resp. HAMA USB */ { USB_DEVICE(0x0573, 0x0400) }, /* D-Link V100 */ { USB_DEVICE(0x0573, 0x2000) }, /* X10 USB Camera */ - { USB_DEVICE(0x0573, 0x2d00) }, /* Osprey 50 */ - { USB_DEVICE(0x0573, 0x2d01) }, /* Hauppauge USB-Live Model 600 */ + { USB_DEVICE(0x0573, 0x2d00) }, /* Hauppauge WinTV USB Live (PAL B/G) */ + { USB_DEVICE(0x0573, 0x2d01) }, /* Hauppauge WinTV USB Live Pro (NTSC M/N) */ { USB_DEVICE(0x0573, 0x2101) }, /* Zoran Co. PMD (Nogatech) AV-grabber Manhattan */ { USB_DEVICE(0x0573, 0x4100) }, /* Nogatech USB-TV FM (NTSC) */ { USB_DEVICE(0x0573, 0x4110) }, /* PNY USB-TV (NTSC) FM */ { USB_DEVICE(0x0573, 0x4450) }, /* PixelView PlayTv-USB PRO (PAL) FM */ { USB_DEVICE(0x0573, 0x4550) }, /* ZTV ZT-721 2.4GHz USB A/V Receiver */ - { USB_DEVICE(0x0573, 0x4d00) }, /* Hauppauge WinTv-USB USA */ - { USB_DEVICE(0x0573, 0x4d01) }, /* Hauppauge WinTv-USB */ - { USB_DEVICE(0x0573, 0x4d02) }, /* Hauppauge WinTv-USB UK */ - { USB_DEVICE(0x0573, 0x4d03) }, /* Hauppauge WinTv-USB France */ - { USB_DEVICE(0x0573, 0x4d10) }, /* Hauppauge WinTv-USB with FM USA radio */ - { USB_DEVICE(0x0573, 0x4d11) }, /* Hauppauge WinTv-USB (PAL) with FM radio */ - { USB_DEVICE(0x0573, 0x4d12) }, /* Hauppauge WinTv-USB UK with FM Radio */ - { USB_DEVICE(0x0573, 0x4d2a) }, /* Hauppague WinTv USB Model 602 40201 Rev B285 */ - { USB_DEVICE(0x0573, 0x4d2b) }, /* Hauppague WinTv USB Model 602 40201 Rev B282 */ - { USB_DEVICE(0x0573, 0x4d2c) }, /* Hauppague WinTv USB Model 40209 Rev. E1A5 PAL*/ - { USB_DEVICE(0x0573, 0x4d20) }, /* Hauppauge WinTv-USB II (PAL) FM Model 40201 Rev B226 */ - { USB_DEVICE(0x0573, 0x4d21) }, /* Hauppauge WinTv-USB II (PAL) with FM radio*/ - { USB_DEVICE(0x0573, 0x4d22) }, /* Hauppauge WinTv-USB II (PAL) Model 566 */ - { USB_DEVICE(0x0573, 0x4d23) }, /* Hauppauge WinTv-USB France 4D23*/ - { USB_DEVICE(0x0573, 0x4d25) }, /* Hauppauge WinTv-USB Model 40209 rev B234 */ - { USB_DEVICE(0x0573, 0x4d26) }, /* Hauppauge WinTv-USB Model 40209 Rev B243 */ - { USB_DEVICE(0x0573, 0x4d27) }, /* Hauppauge WinTv-USB Model 40204 Rev B281 */ - { USB_DEVICE(0x0573, 0x4d28) }, /* Hauppauge WinTv-USB Model 40204 Rev B283 */ - { USB_DEVICE(0x0573, 0x4d29) }, /* Hauppauge WinTv-USB Model 40205 Rev B298 */ - { USB_DEVICE(0x0573, 0x4d30) }, /* Hauppauge WinTv-USB FM Model 40211 Rev B123 */ - { USB_DEVICE(0x0573, 0x4d31) }, /* Hauppauge WinTv-USB III (PAL) with FM radio Model 568 */ - { USB_DEVICE(0x0573, 0x4d32) }, /* Hauppauge WinTv-USB III (PAL) FM Model 573 */ - { USB_DEVICE(0x0573, 0x4d35) }, /* Hauppauge WinTv-USB III (SECAM) FM Model 40219 Rev B252 */ - { USB_DEVICE(0x0573, 0x4d37) }, /* Hauppauge WinTv-USB Model 40219 Rev E189 */ + { USB_DEVICE(0x0573, 0x4d00) }, /* Hauppauge WinTV USB (NTSC M/N) */ + { USB_DEVICE(0x0573, 0x4d01) }, /* Hauppauge WinTV USB (PAL B/G) */ + { USB_DEVICE(0x0573, 0x4d02) }, /* Hauppauge WinTV USB (PAL I) */ + { USB_DEVICE(0x0573, 0x4d03) }, /* Hauppauge WinTV USB (PAL/SECAM L) */ + { USB_DEVICE(0x0573, 0x4d04) }, /* Hauppauge WinTV USB (PAL D/K) */ + { USB_DEVICE(0x0573, 0x4d10) }, /* Hauppauge WinTV USB (NTSC FM) */ + { USB_DEVICE(0x0573, 0x4d11) }, /* Hauppauge WinTV USB (PAL B/G FM) */ + { USB_DEVICE(0x0573, 0x4d12) }, /* Hauppauge WinTV USB (PAL I FM) */ + { USB_DEVICE(0x0573, 0x4d14) }, /* Hauppauge WinTV USB (PAL D/K FM) */ + { USB_DEVICE(0x0573, 0x4d2a) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */ + { USB_DEVICE(0x0573, 0x4d2b) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */ + { USB_DEVICE(0x0573, 0x4d2c) }, /* Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) */ + { USB_DEVICE(0x0573, 0x4d20) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */ + { USB_DEVICE(0x0573, 0x4d21) }, /* Hauppauge WinTV USB Pro (PAL B/G) */ + { USB_DEVICE(0x0573, 0x4d22) }, /* Hauppauge WinTV USB Pro (PAL I) */ + { USB_DEVICE(0x0573, 0x4d23) }, /* Hauppauge WinTV USB Pro (PAL/SECAM L) */ + { USB_DEVICE(0x0573, 0x4d24) }, /* Hauppauge WinTV USB Pro (PAL D/K) */ + { USB_DEVICE(0x0573, 0x4d25) }, /* Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) */ + { USB_DEVICE(0x0573, 0x4d26) }, /* Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) */ + { USB_DEVICE(0x0573, 0x4d27) }, /* Hauppauge WinTV USB Pro (PAL B/G) */ + { USB_DEVICE(0x0573, 0x4d28) }, /* Hauppauge WinTV USB Pro (PAL B/G,D/K) */ + { USB_DEVICE(0x0573, 0x4d29) }, /* Hauppauge WinTV USB Pro (PAL I,D/K) */ + { USB_DEVICE(0x0573, 0x4d30) }, /* Hauppauge WinTV USB Pro (NTSC M/N FM) */ + { USB_DEVICE(0x0573, 0x4d31) }, /* Hauppauge WinTV USB Pro (PAL B/G FM) */ + { USB_DEVICE(0x0573, 0x4d32) }, /* Hauppauge WinTV USB Pro (PAL I FM) */ + { USB_DEVICE(0x0573, 0x4d34) }, /* Hauppauge WinTV USB Pro (PAL D/K FM) */ + { USB_DEVICE(0x0573, 0x4d35) }, /* Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) */ + { USB_DEVICE(0x0573, 0x4d36) }, /* Hauppauge WinTV USB Pro (Temic PAL B/G FM) */ + { USB_DEVICE(0x0573, 0x4d37) }, /* Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) */ + { USB_DEVICE(0x0573, 0x4d38) }, /* Hauppauge WinTV USB Pro (NTSC M/N FM) */ { USB_DEVICE(0x0768, 0x0006) }, /* Camtel Technology USB TV Genie Pro FM Model TVB330 */ { USB_DEVICE(0x07d0, 0x0001) }, /* Digital Video Creator I */ { USB_DEVICE(0x07d0, 0x0002) }, /* Global Village GV-007 (NTSC) */ { USB_DEVICE(0x07d0, 0x0003) }, /* Dazzle Fusion Model DVC-50 Rev 1 (NTSC) */ { USB_DEVICE(0x07d0, 0x0004) }, /* Dazzle Fusion Model DVC-80 Rev 1 (PAL) */ { USB_DEVICE(0x07d0, 0x0005) }, /* Dazzle Fusion Model DVC-90 Rev 1 (SECAM) */ + { USB_DEVICE(0x07f8, 0x9104) }, /* Eskape Labs MyTV2Go */ { USB_DEVICE(0x2304, 0x010d) }, /* Pinnacle Studio PCTV USB (PAL) */ { USB_DEVICE(0x2304, 0x0109) }, /* Pinnacle Studio PCTV USB (SECAM) */ { USB_DEVICE(0x2304, 0x0110) }, /* Pinnacle Studio PCTV USB (PAL) */ diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index fcbe085ef..88b1fec85 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -33,6 +33,7 @@ #include <linux/vmalloc.h> #include <linux/slab.h> #include <linux/proc_fs.h> +#include <linux/highmem.h> #include <media/v4l2-common.h> #include "compat.h" @@ -281,7 +282,7 @@ static unsigned char header3; static int read_frame(struct zr364xx_camera *cam, int framenum) { int i, n, temp, head, size, actual_length; - unsigned char *ptr = NULL, *jpeg, swap; + unsigned char *ptr = NULL, *jpeg; redo: /* hardware brightness */ @@ -312,12 +313,11 @@ static int read_frame(struct zr364xx_camera *cam, int framenum) } /* swap bytes if camera needs it */ - if (cam->method == METHOD0) - for (i = 0; i < BUFFER_SIZE; i += 2) { - swap = cam->buffer[i]; - cam->buffer[i] = cam->buffer[i + 1]; - cam->buffer[i + 1] = swap; - } + if (cam->method == METHOD0) { + u16 *buf = (u16*)cam->buffer; + for (i = 0; i < BUFFER_SIZE/2; i++) + swab16s(buf + i); + } /* write the JPEG header */ if (!head) { diff --git a/linux/include/linux/dvb/video.h b/linux/include/linux/dvb/video.h index a96da40c5..93e4c3a6d 100644 --- a/linux/include/linux/dvb/video.h +++ b/linux/include/linux/dvb/video.h @@ -110,7 +110,12 @@ struct video_command { } stop; struct { - __u32 speed; + /* 0 or 1000 specifies normal speed, + 1 specifies forward single stepping, + -1 specifies backward single stepping, + >1: playback at speed/1000 of the normal speed, + <-1: reverse playback at (-speed/1000) of the normal speed. */ + __s32 speed; __u32 format; } play; @@ -120,6 +125,13 @@ struct video_command { }; }; +/* FIELD_UNKNOWN can be used if the hardware does not know whether + the Vsync is for an odd, even or progressive (i.e. non-interlaced) + field. */ +#define VIDEO_VSYNC_FIELD_UNKNOWN (0) +#define VIDEO_VSYNC_FIELD_ODD (1) +#define VIDEO_VSYNC_FIELD_EVEN (2) +#define VIDEO_VSYNC_FIELD_PROGRESSIVE (3) struct video_event { int32_t type; @@ -131,6 +143,7 @@ struct video_event { union { video_size_t size; unsigned int frame_rate; /* in frames per 1000sec */ + unsigned char vsync_field; /* unknown/odd/even/progressive */ } u; }; diff --git a/linux/include/media/tuner.h b/linux/include/media/tuner.h index 40affbd6f..27d2183a4 100644 --- a/linux/include/media/tuner.h +++ b/linux/include/media/tuner.h @@ -123,6 +123,7 @@ extern int tuner_debug; #define TUNER_THOMSON_FE6600 72 /* DViCO FusionHDTV DVB-T Hybrid */ #define TUNER_SAMSUNG_TCPG_6121P30A 73 /* Hauppauge PVR-500 PAL */ #define TUNER_TDA9887 74 /* This tuner should be used only internally */ +#define TUNER_TEA5761 75 /* Only FM Radio Tuner */ /* tv card specific */ #define TDA9887_PRESENT (1<<0) @@ -232,11 +233,16 @@ extern int microtune_init(struct i2c_client *c); extern int xc3028_init(struct i2c_client *c); extern int tda8290_init(struct i2c_client *c); extern int tda8290_probe(struct i2c_client *c); -extern int tea5767_tuner_init(struct i2c_client *c); extern int default_tuner_init(struct i2c_client *c); + extern int tea5767_autodetection(struct i2c_client *c); +extern int tea5767_tuner_init(struct i2c_client *c); + extern int tda9887_tuner_init(struct i2c_client *c); +extern int tea5761_tuner_init(struct i2c_client *c); +extern int tea5761_autodetection(struct i2c_client *c); + #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) #define tuner_warn(fmt, arg...) do {\ printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \ diff --git a/v4l/Makefile b/v4l/Makefile index abc53110c..ad499751d 100644 --- a/v4l/Makefile +++ b/v4l/Makefile @@ -231,8 +231,8 @@ endif links:: @echo creating symbolic links... - @find ../linux/drivers/media -name '*.[ch]' -type f -exec ln -sf '{}' . \; - @find ../linux/sound -name '*.[ch]' -type f -exec ln -sf '{}' . \; + @find ../linux/drivers/media -name '*.[ch]' -type f -print0 | xargs -0n 255 ln -sf --target-directory=. + @find ../linux/sound -name '*.[ch]' -type f -print0 | xargs -0n 255 ln -sf --target-directory=. # This link is so code with #include "oss/*.h" will find its header files oss: diff --git a/v4l/scripts/gentree.pl b/v4l/scripts/gentree.pl index 4d27fd789..f9f56bd7c 100755 --- a/v4l/scripts/gentree.pl +++ b/v4l/scripts/gentree.pl @@ -62,6 +62,7 @@ my %defs = ( 'I2C_PEC' => 1, 'I2C_DF_DUMMY' => 0, 'CONFIG_XC3028' => 0, + 'CONFIG_TUNER_TEA5761' => 0, 'I2C_CLASS_TV_ANALOG' => 1, 'I2C_CLASS_TV_DIGITAL' => 1); diff --git a/v4l/scripts/hghead.pl b/v4l/scripts/hghead.pl index 7a1dbacd2..dd4cedee6 100755 --- a/v4l/scripts/hghead.pl +++ b/v4l/scripts/hghead.pl @@ -111,7 +111,7 @@ while ($line = <IN>) { } - if ($line =~ m/^(Acked-by|acked-by|Thanks-to|cc|CC|Cc):.*/) { + if ($line =~ m/^(Acked-by|Acked-By|acked-by|Thanks-to|cc|CC|Cc):.*/) { $signed="$signed$line"; next; } diff --git a/v4l/scripts/prep_commit_msg.pl b/v4l/scripts/prep_commit_msg.pl index a4594c7f9..f4047c6ba 100755 --- a/v4l/scripts/prep_commit_msg.pl +++ b/v4l/scripts/prep_commit_msg.pl @@ -5,16 +5,31 @@ my $autopatch = shift; # Get Hg username from environment my $user = $ENV{HGUSER}; -# Didn't work? Try the .hgrc file -if ($user eq "") { - open IN, "<$ENV{HOME}/.hgrc"; +sub hgrcuser($) +{ + my $file = shift; + my $ui = 0; + open IN, '<', $file; while (<IN>) { - if(/^\s*username\s*=\s*(\S.*)$/) { - $user = $1; - last; + $ui = 1 if (/^\s*\[ui\]/); + if ($ui && /^\s*username\s*=\s*(\S.*?)\s*$/) { + close IN; + return($1); } } close IN; + return(""); +} + +# Didn't work? Try the repo's .hgrc file +if ($user eq "") { + my $hgroot = `hg root`; + chomp($hgroot); + $user = hgrcuser("$hgroot/.hg/hgrc"); +} +# Ok, try ~/.hgrc next +if ($user eq "") { + $user = hgrcuser("$ENV{HOME}/.hgrc"); } # Still no luck? Try some other environment variables |