diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 05d71b4b9430..c28a2ac88f9d 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -56,30 +56,6 @@ Who: Mauro Carvalho Chehab --------------------------- -What: old tuner-3036 i2c driver -When: 2.6.28 -Why: This driver is for VERY old i2c-over-parallel port teletext receiver - boxes. Rather then spending effort on converting this driver to V4L2, - and since it is extremely unlikely that anyone still uses one of these - devices, it was decided to drop it. -Who: Hans Verkuil - Mauro Carvalho Chehab - - --------------------------- - -What: V4L2 dpc7146 driver -When: 2.6.28 -Why: Old driver for the dpc7146 demonstration board that is no longer - relevant. The last time this was tested on actual hardware was - probably around 2002. Since this is a driver for a demonstration - board the decision was made to remove it rather than spending a - lot of effort continually updating this driver to stay in sync - with the latest internal V4L2 or I2C API. -Who: Hans Verkuil - Mauro Carvalho Chehab - ---------------------------- - What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) When: November 2005 Files: drivers/pcmcia/: pcmcia_ioctl.c diff --git a/Documentation/video4linux/README.cx88 b/Documentation/video4linux/README.cx88 index 06a33a4f52fd..166d5960b1a9 100644 --- a/Documentation/video4linux/README.cx88 +++ b/Documentation/video4linux/README.cx88 @@ -27,8 +27,8 @@ audio sound card) should be possible, but there is no code yet ... vbi - - some code present. Doesn't crash any more, but also doesn't - work yet ... + - Code present. Works for NTSC closed caption. PAL and other + TV norms may or may not work. how to add support for new cards diff --git a/Documentation/video4linux/si470x.txt b/Documentation/video4linux/si470x.txt new file mode 100644 index 000000000000..11c5fd22a332 --- /dev/null +++ b/Documentation/video4linux/si470x.txt @@ -0,0 +1,118 @@ +Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers + +Copyright (c) 2008 Tobias Lorenz + + +Information from Silicon Labs +============================= +Silicon Laboratories is the manufacturer of the radio ICs, that nowadays are the +most often used radio receivers in cell phones. Usually they are connected with +I2C. But SiLabs also provides a reference design, which integrates this IC, +together with a small microcontroller C8051F321, to form a USB radio. +Part of this reference design is also a radio application in binary and source +code. The software also contains an automatic firmware upgrade to the most +current version. Information on these can be downloaded here: +http://www.silabs.com/usbradio + + +Supported ICs +============= +The following ICs have a very similar register set, so that they are or will be +supported somewhen by the driver: +- Si4700: FM radio receiver +- Si4701: FM radio receiver, RDS Support +- Si4702: FM radio receiver +- Si4703: FM radio receiver, RDS Support +- Si4704: FM radio receiver, no external antenna required +- Si4705: FM radio receiver, no external antenna required, RDS support, Dig I/O +- Si4706: Enhanced FM RDS/TMC radio receiver, no external antenna required, RDS + Support +- Si4707: Dedicated weather band radio receiver with SAME decoder, RDS Support +- Si4708: Smallest FM receivers +- Si4709: Smallest FM receivers, RDS Support +More information on these can be downloaded here: +http://www.silabs.com/products/mcu/Pages/USBFMRadioRD.aspx + + +Supported USB devices +===================== +Currently the following USB radios (vendor:product) with the Silicon Labs si470x +chips are known to work: +- 10c4:818a: Silicon Labs USB FM Radio Reference Design +- 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) +- 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700) + + +Software +======== +Testing is usually done with most application under Debian/testing: +- fmtools - Utility for managing FM tuner cards +- gnomeradio - FM-radio tuner for the GNOME desktop +- gradio - GTK FM radio tuner +- kradio - Comfortable Radio Application for KDE +- radio - ncurses-based radio application + +There is also a library libv4l, which can be used. It's going to have a function +for frequency seeking, either by using hardware functionality as in radio-si470x +or by implementing a function as we currently have in every of the mentioned +programs. Somewhen the radio programs should make use of libv4l. + +For processing RDS information, there is a project ongoing at: +http://rdsd.berlios.de/ + +There is currently no project for making TMC sentences human readable. + + +Audio Listing +============= +USB Audio is provided by the ALSA snd_usb_audio module. It is recommended to +also select SND_USB_AUDIO, as this is required to get sound from the radio. For +listing you have to redirect the sound, for example using one of the following +commands. + +If you just want to test audio (very poor quality): +cat /dev/dsp1 > /dev/dsp + +If you use OSS try: +sox -2 --endian little -r 96000 -t oss /dev/dsp1 -t oss /dev/dsp + +If you use arts try: +arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B - + + +Module Parameters +================= +After loading the module, you still have access to some of them in the sysfs +mount under /sys/module/radio_si470x/parameters. The contents of read-only files +(0444) are not updated, even if space, band and de are changed using private +video controls. The others are runtime changeable. + + +Errors +====== +Increase tune_timeout, if you often get -EIO errors. + +When timed out or band limit is reached, hw_freq_seek returns -EAGAIN. + +If you get any errors from snd_usb_audio, please report them to the ALSA people. + + +Open Issues +=========== +V4L minor device allocation and parameter setting is not perfect. A solution is +currently under discussion. + +There is an USB interface for downloading/uploading new firmware images. Support +for it can be implemented using the request_firmware interface. + +There is a RDS interrupt mode. The driver is already using the same interface +for polling RDS information, but is currently not using the interrupt mode. + +There is a LED interface, which can be used to override the LED control +programmed in the firmware. This can be made available using the LED support +functions in the kernel. + + +Other useful information and links +================================== +http://www.silabs.com/usbradio diff --git a/MAINTAINERS b/MAINTAINERS index 7e6a17e1de09..53e78c83cc7a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1879,6 +1879,37 @@ M: linux-kernel@vger.kernel.org W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/ S: Maintained +GSPCA FINEPIX SUBDRIVER +P: Frank Zago +M: frank@zago.net +L: video4linux-list@redhat.com +S: Maintained + +GSPCA M5602 SUBDRIVER +P: Erik Andren +M: erik.andren@gmail.com +L: video4linux-list@redhat.com +S: Maintained + +GSPCA PAC207 SONIXB SUBDRIVER +P: Hans de Goede +M: hdegoede@redhat.com +L: video4linux-list@redhat.com +S: Maintained + +GSPCA T613 SUBDRIVER +P: Leandro Costantino +M: lcostantino@gmail.com +L: video4linux-list@redhat.com +S: Maintained + +GSPCA USB WEBCAM DRIVER +P: Jean-Francois Moine +M: moinejf@free.fr +W: http://moinejf.free.fr +L: video4linux-list@redhat.com +S: Maintained + HARDWARE MONITORING L: lm-sensors@lm-sensors.org W: http://www.lm-sensors.org/ diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1903e7515650..d3671b4049c0 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1265,6 +1265,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5cc404291736..f05bcbbbb0d5 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -253,6 +253,9 @@ #define USB_VENDOR_ID_KBGEAR 0x084e #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 +#define USB_VENDOR_ID_KWORLD 0x1b80 +#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 + #define USB_VENDOR_ID_LABTEC 0x1020 #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 5689d1f1d444..8557bf12cfb4 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -223,6 +223,8 @@ static void dvb_frontend_init(struct dvb_frontend *fe) if (fe->ops.init) fe->ops.init(fe); if (fe->ops.tuner_ops.init) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); fe->ops.tuner_ops.init(fe); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 3c13bcfa6385..62b68c291d99 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -261,7 +261,7 @@ config DVB_USB_DW2102 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers and the TeVii S650. -config DVB_USB_CINERGY_T2 +config DVB_USB_CINERGY_T2 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" depends on DVB_USB help @@ -283,6 +283,7 @@ config DVB_USB_ANYSEE config DVB_USB_DTV5100 tristate "AME DTV-5100 USB2.0 DVB-T support" depends on DVB_USB + select DVB_ZL10353 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE help Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index cb0829c038ce..847d8fdd9ec4 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -31,13 +31,13 @@ #include "mc44s80x.h" #endif -int dvb_usb_af9015_debug; +static int dvb_usb_af9015_debug; module_param_named(debug, dvb_usb_af9015_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -int dvb_usb_af9015_remote; +static int dvb_usb_af9015_remote; module_param_named(remote, dvb_usb_af9015_remote, int, 0644); MODULE_PARM_DESC(remote, "select remote"); -int dvb_usb_af9015_dual_mode; +static int dvb_usb_af9015_dual_mode; module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); MODULE_PARM_DESC(dual_mode, "enable dual mode"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -46,7 +46,7 @@ static DEFINE_MUTEX(af9015_usb_mutex); static struct af9015_config af9015_config; static struct dvb_usb_device_properties af9015_properties[2]; -int af9015_properties_count = ARRAY_SIZE(af9015_properties); +static int af9015_properties_count = ARRAY_SIZE(af9015_properties); static struct af9013_config af9015_af9013_config[] = { { @@ -549,7 +549,7 @@ static int af9015_eeprom_dump(struct dvb_usb_device *d) return 0; } -int af9015_download_ir_table(struct dvb_usb_device *d) +static int af9015_download_ir_table(struct dvb_usb_device *d) { int i, packets = 0, ret; u16 addr = 0x9a56; /* ir-table start address */ @@ -999,7 +999,7 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) } /* init 2nd I2C adapter */ -int af9015_i2c_init(struct dvb_usb_device *d) +static int af9015_i2c_init(struct dvb_usb_device *d) { int ret; struct af9015_state *state = d->priv; @@ -1419,7 +1419,7 @@ static int af9015_usb_probe(struct usb_interface *intf, return ret; } -void af9015_i2c_exit(struct dvb_usb_device *d) +static void af9015_i2c_exit(struct dvb_usb_device *d) { struct af9015_state *state = d->priv; deb_info("%s: \n", __func__); diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 882e8a4b3681..6c3c97293316 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -27,7 +27,6 @@ #define DVB_USB_LOG_PREFIX "af9015" #include "dvb-usb.h" -extern int dvb_usb_af9015_debug; #define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args) #define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args) #define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args) diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index c786359fba03..cd2edbcaa097 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -46,7 +46,7 @@ module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644); MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static struct mutex anysee_usb_mutex; +static DEFINE_MUTEX(anysee_usb_mutex); static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen) @@ -456,8 +456,6 @@ static int anysee_probe(struct usb_interface *intf, struct usb_host_interface *alt; int ret; - mutex_init(&anysee_usb_mutex); - /* There is one interface with two alternate settings. Alternate setting 0 is for bulk transfer. Alternate setting 1 is for isochronous transfer. diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index 5cef12a07f72..6fe71c6745eb 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c @@ -13,14 +13,14 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, { int actlen,ret = -ENOMEM; + if (!d || wbuf == NULL || wlen == 0) + return -EINVAL; + if (d->props.generic_bulk_ctrl_endpoint == 0) { err("endpoint for generic control not specified."); return -EINVAL; } - if (wbuf == NULL || wlen == 0) - return -EINVAL; - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) return ret; diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 21c1060cf10e..692b68a9e73b 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c @@ -1187,7 +1187,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) if (tmp) *status |= FE_HAS_SYNC | FE_HAS_LOCK; - if (!*status & FE_HAS_SIGNAL) { + if (!(*status & FE_HAS_SIGNAL)) { /* AGC lock */ ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); if (ret) @@ -1196,7 +1196,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) *status |= FE_HAS_SIGNAL; } - if (!*status & FE_HAS_CARRIER) { + if (!(*status & FE_HAS_CARRIER)) { /* CFO lock */ ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); if (ret) @@ -1205,7 +1205,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) *status |= FE_HAS_CARRIER; } - if (!*status & FE_HAS_CARRIER) { + if (!(*status & FE_HAS_CARRIER)) { /* SFOE lock */ ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); if (ret) diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 04cd7c04bdde..5189c4eb439f 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -355,6 +355,20 @@ config USB_SI470X tristate "Silicon Labs Si470x FM Radio Receiver support" depends on USB && VIDEO_V4L2 ---help--- + This is a driver for USB devices with the Silicon Labs SI470x + chip. Currently these devices are known to work: + - 10c4:818a: Silicon Labs USB FM Radio Reference Design + - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) + - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700) + + Sound is provided by the ALSA USB Audio/MIDI driver. Therefore + if you don't want to use the device solely for RDS receiving, + it is recommended to also select SND_USB_AUDIO. + + Please have a look at the documentation, especially on how + to redirect the audio stream from the radio to your sound device: + Documentation/video4linux/si470x.txt + Say Y here if you want to connect this type of radio to your computer's USB port. diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 5920cd306975..3e1830293de5 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -4,6 +4,7 @@ * Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers: * - Silicon Labs USB FM Radio Reference Design * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) + * - KWorld USB FM Radio SnapMusic Mobile 700 (FM700) * * Copyright (c) 2008 Tobias Lorenz * @@ -23,19 +24,6 @@ */ -/* - * User Notes: - * - USB Audio is provided by the alsa snd_usb_audio module. - * For listing you have to redirect the sound, for example using: - * arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B - - * - regarding module parameters in /sys/module/radio_si470x/parameters: - * the contents of read-only files (0444) are not updated, even if - * space, band and de are changed using private video controls - * - increase tune_timeout, if you often get -EIO errors - * - hw_freq_seek returns -EAGAIN, when timed out or band limit is reached - */ - - /* * History: * 2008-01-12 Tobias Lorenz @@ -105,6 +93,9 @@ * - afc indication * - more safety checks, let si470x_get_freq return errno * - vidioc behavior corrected according to v4l2 spec + * 2008-10-20 Alexey Klimov + * - add support for KWorld USB FM Radio FM700 + * - blacklisted KWorld radio in hid-core.c and hid-ids.h * * ToDo: * - add firmware download/update support @@ -145,6 +136,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, + /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index a8c068e1de1c..1740b9ebdcef 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -1476,12 +1476,9 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) { struct cafe_camera *cam; - lock_kernel(); cam = cafe_find_dev(iminor(inode)); - if (cam == NULL) { - unlock_kernel(); + if (cam == NULL) return -ENODEV; - } filp->private_data = cam; mutex_lock(&cam->s_mutex); @@ -1493,7 +1490,6 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) } (cam->users)++; mutex_unlock(&cam->s_mutex); - unlock_kernel(); return 0; } diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index bd5d9de5a008..e6ca4012b5f0 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c @@ -867,6 +867,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_STREAMON32: case VIDIOC_STREAMOFF32: case VIDIOC_G_PARM: + case VIDIOC_S_PARM: case VIDIOC_G_STD: case VIDIOC_S_STD: case VIDIOC_G_TUNER: @@ -885,6 +886,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_S_INPUT32: case VIDIOC_TRY_FMT32: case VIDIOC_S_HW_FREQ_SEEK: + case VIDIOC_ENUM_FRAMESIZES: + case VIDIOC_ENUM_FRAMEINTERVALS: ret = do_video_ioctl(file, cmd, arg); break; diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 7a1a7830a6b3..7874d9790a51 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -448,7 +448,14 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) mutex_init(&cx->gpio_lock); spin_lock_init(&cx->lock); - spin_lock_init(&cx->dma_reg_lock); + + cx->work_queue = create_singlethread_workqueue(cx->name); + if (cx->work_queue == NULL) { + CX18_ERR("Could not create work queue\n"); + return -1; + } + + INIT_WORK(&cx->work, cx18_work_handler); /* start counting open_id at 1 */ cx->open_id = 1; @@ -581,10 +588,10 @@ static void cx18_load_and_init_modules(struct cx18 *cx) #ifdef MODULE /* load modules */ -#ifndef CONFIG_MEDIA_TUNER +#ifdef CONFIG_MEDIA_TUNER_MODULE hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); #endif -#ifndef CONFIG_VIDEO_CS5345 +#ifdef CONFIG_VIDEO_CS5345_MODULE hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); #endif #endif @@ -832,6 +839,7 @@ free_map: free_mem: release_mem_region(cx->base_addr, CX18_MEM_SIZE); free_workqueue: + destroy_workqueue(cx->work_queue); err: if (retval == 0) retval = -ENODEV; @@ -932,6 +940,9 @@ static void cx18_remove(struct pci_dev *pci_dev) cx18_halt_firmware(cx); + flush_workqueue(cx->work_queue); + destroy_workqueue(cx->work_queue); + cx18_streams_cleanup(cx, 1); exit_cx18_i2c(cx); diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index a4b1708fafe7..bbdd5f25041d 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -199,12 +199,15 @@ struct cx18_options { #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ /* per-cx18, i_flags */ -#define CX18_F_I_LOADED_FW 0 /* Loaded the firmware the first time */ -#define CX18_F_I_EOS 4 /* End of encoder stream reached */ -#define CX18_F_I_RADIO_USER 5 /* The radio tuner is selected */ -#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ -#define CX18_F_I_INITED 21 /* set after first open */ -#define CX18_F_I_FAILED 22 /* set if first open failed */ +#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ +#define CX18_F_I_EOS 4 /* End of encoder stream */ +#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */ +#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ +#define CX18_F_I_HAVE_WORK 15 /* there is work to be done */ +#define CX18_F_I_WORK_HANDLER_DVB 18 /* work to be done for DVB */ +#define CX18_F_I_INITED 21 /* set after first open */ +#define CX18_F_I_FAILED 22 /* set if first open failed */ +#define CX18_F_I_WORK_INITED 23 /* worker thread initialized */ /* These are the VBI types as they appear in the embedded VBI private packets. */ #define CX18_SLICED_TYPE_TELETEXT_B (1) @@ -402,8 +405,6 @@ struct cx18 { spinlock_t lock; /* lock access to this struct */ int search_pack_header; - spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ - int open_id; /* incremented each time an open occurs, used as unique ID. Starts at 1, so 0 can be used as uninitialized value in the stream->id. */ @@ -433,6 +434,9 @@ struct cx18 { /* when the current DMA is finished this queue is woken up */ wait_queue_head_t dma_waitq; + struct workqueue_struct *work_queue; + struct work_struct work; + /* i2c */ struct i2c_adapter i2c_adap[2]; struct i2c_algo_bit_data i2c_algo[2]; diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index afc694e7bdb2..4542e2e5e3d7 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -23,6 +23,8 @@ #include "cx18-dvb.h" #include "cx18-io.h" #include "cx18-streams.h" +#include "cx18-queue.h" +#include "cx18-scb.h" #include "cx18-cards.h" #include "s5h1409.h" #include "mxl5005s.h" @@ -300,3 +302,24 @@ static int dvb_register(struct cx18_stream *stream) return ret; } + +void cx18_dvb_work_handler(struct cx18 *cx) +{ + struct cx18_buffer *buf; + struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_TS]; + + while ((buf = cx18_dequeue(s, &s->q_full)) != NULL) { + if (s->dvb.enabled) + dvb_dmx_swfilter(&s->dvb.demux, buf->buf, + buf->bytesused); + + cx18_enqueue(s, buf, &s->q_free); + cx18_buf_sync_for_device(s, buf); + if (s->handle == CX18_INVALID_TASK_HANDLE) /* FIXME: improve */ + continue; + + cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, + (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, + 1, buf->id, s->buf_size); + } +} diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h index bf8d8f6f5455..bbdcefc87f28 100644 --- a/drivers/media/video/cx18/cx18-dvb.h +++ b/drivers/media/video/cx18/cx18-dvb.h @@ -23,3 +23,4 @@ int cx18_dvb_register(struct cx18_stream *stream); void cx18_dvb_unregister(struct cx18_stream *stream); +void cx18_dvb_work_handler(struct cx18 *cx); diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c index 700ab9439c16..220fae8d4ad7 100644 --- a/drivers/media/video/cx18/cx18-io.c +++ b/drivers/media/video/cx18/cx18-io.c @@ -88,6 +88,19 @@ void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr) cx18_log_write_retries(cx, i, addr); } +void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, + u32 eval, u32 mask) +{ + int i; + eval &= mask; + for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { + cx18_writel_noretry(cx, val, addr); + if (eval == (cx18_readl_noretry(cx, addr) & mask)) + break; + } + cx18_log_write_retries(cx, i, addr); +} + void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr) { int i; @@ -218,7 +231,7 @@ void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) { u32 r; - cx18_write_reg(cx, val, SW1_INT_STATUS); + cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val); r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); } @@ -233,7 +246,7 @@ void cx18_sw1_irq_disable(struct cx18 *cx, u32 val) void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) { u32 r; - cx18_write_reg(cx, val, SW2_INT_STATUS); + cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val); r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); } diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h index 287a5e8bf67b..425244453ea7 100644 --- a/drivers/media/video/cx18/cx18-io.h +++ b/drivers/media/video/cx18/cx18-io.h @@ -133,6 +133,8 @@ static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr) cx18_writel_noretry(cx, val, addr); } +void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, + u32 eval, u32 mask); static inline void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) @@ -271,6 +273,21 @@ static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) cx18_write_reg_noretry(cx, val, reg); } +static inline void _cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, + u32 eval, u32 mask) +{ + _cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask); +} + +static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, + u32 eval, u32 mask) +{ + if (cx18_retry_mmio) + _cx18_write_reg_expect(cx, val, reg, eval, mask); + else + cx18_write_reg_noretry(cx, val, reg); +} + static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg) { diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c index 360330f5463f..5fbfbd0f1493 100644 --- a/drivers/media/video/cx18/cx18-irq.c +++ b/drivers/media/video/cx18/cx18-irq.c @@ -29,8 +29,20 @@ #include "cx18-mailbox.h" #include "cx18-vbi.h" #include "cx18-scb.h" +#include "cx18-dvb.h" -#define DMA_MAGIC_COOKIE 0x000001fe +void cx18_work_handler(struct work_struct *work) +{ + struct cx18 *cx = container_of(work, struct cx18, work); + if (test_and_clear_bit(CX18_F_I_WORK_INITED, &cx->i_flags)) { + struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; + /* This thread must use the FIFO scheduler as it + * is realtime sensitive. */ + sched_setscheduler(current, SCHED_FIFO, ¶m); + } + if (test_and_clear_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags)) + cx18_dvb_work_handler(cx); +} static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) { @@ -67,17 +79,11 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) if (buf) { cx18_buf_sync_for_cpu(s, buf); if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { - /* process the buffer here */ - CX18_DEBUG_HI_DMA("TS recv and sent bytesused=%d\n", + CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", buf->bytesused); - dvb_dmx_swfilter(&s->dvb.demux, buf->buf, - buf->bytesused); - - cx18_buf_sync_for_device(s, buf); - cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, - (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, - 1, buf->id, s->buf_size); + set_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags); + set_bit(CX18_F_I_HAVE_WORK, &cx->i_flags); } else set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); } else { @@ -109,7 +115,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb) CX18_INFO("FW version: %s\n", p - 1); } -static void hpu_cmd(struct cx18 *cx, u32 sw1) +static void epu_cmd(struct cx18 *cx, u32 sw1) { struct cx18_mailbox mb; @@ -125,12 +131,31 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1) epu_debug(cx, &mb); break; default: - CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd); + CX18_WARN("Unknown CPU_TO_EPU mailbox command %#08x\n", + mb.cmd); break; } } - if (sw1 & (IRQ_APU_TO_EPU | IRQ_HPU_TO_EPU)) - CX18_WARN("Unexpected interrupt %08x\n", sw1); + + if (sw1 & IRQ_APU_TO_EPU) { + cx18_memcpy_fromio(cx, &mb, &cx->scb->apu2epu_mb, sizeof(mb)); + CX18_WARN("Unknown APU_TO_EPU mailbox command %#08x\n", mb.cmd); + } + + if (sw1 & IRQ_HPU_TO_EPU) { + cx18_memcpy_fromio(cx, &mb, &cx->scb->hpu2epu_mb, sizeof(mb)); + CX18_WARN("Unknown HPU_TO_EPU mailbox command %#08x\n", mb.cmd); + } +} + +static void xpu_ack(struct cx18 *cx, u32 sw2) +{ + if (sw2 & IRQ_CPU_TO_EPU_ACK) + wake_up(&cx->mb_cpu_waitq); + if (sw2 & IRQ_APU_TO_EPU_ACK) + wake_up(&cx->mb_apu_waitq); + if (sw2 & IRQ_HPU_TO_EPU_ACK) + wake_up(&cx->mb_hpu_waitq); } irqreturn_t cx18_irq_handler(int irq, void *dev_id) @@ -140,43 +165,36 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) u32 sw2, sw2_mask; u32 hw2, hw2_mask; - spin_lock(&cx->dma_reg_lock); - + sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); + sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; + sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); + sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask; hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI); hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask; - sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK; - sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask; - sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU; - sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; - cx18_write_reg(cx, sw2&sw2_mask, SW2_INT_STATUS); - cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS); - cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS); + if (sw1) + cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1); + if (sw2) + cx18_write_reg_expect(cx, sw2, SW2_INT_STATUS, ~sw2, sw2); + if (hw2) + cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2); if (sw1 || sw2 || hw2) CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); /* To do: interrupt-based I2C handling - if (hw2 & 0x00c00000) { + if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) { } */ - if (sw2) { - if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) | - cx18_readl(cx, &cx->scb->cpu2epu_irq_ack))) - wake_up(&cx->mb_cpu_waitq); - if (sw2 & (cx18_readl(cx, &cx->scb->apu2hpu_irq_ack) | - cx18_readl(cx, &cx->scb->apu2epu_irq_ack))) - wake_up(&cx->mb_apu_waitq); - if (sw2 & cx18_readl(cx, &cx->scb->epu2hpu_irq_ack)) - wake_up(&cx->mb_epu_waitq); - if (sw2 & cx18_readl(cx, &cx->scb->hpu2epu_irq_ack)) - wake_up(&cx->mb_hpu_waitq); - } + if (sw2) + xpu_ack(cx, sw2); if (sw1) - hpu_cmd(cx, sw1); - spin_unlock(&cx->dma_reg_lock); + epu_cmd(cx, sw1); - return (hw2 | sw1 | sw2) ? IRQ_HANDLED : IRQ_NONE; + if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags)) + queue_work(cx->work_queue, &cx->work); + + return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE; } diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h index 379f704f5cba..6173ca3bc9e4 100644 --- a/drivers/media/video/cx18/cx18-irq.h +++ b/drivers/media/video/cx18/cx18-irq.h @@ -32,6 +32,4 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id); -void cx18_irq_work_handler(struct work_struct *work); -void cx18_dma_stream_dec_prepare(struct cx18_stream *s, u32 offset, int lock); -void cx18_unfinished_dma(unsigned long arg); +void cx18_work_handler(struct work_struct *work); diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 9d18dd22de76..acff7dfb60df 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c @@ -83,7 +83,7 @@ static const struct cx18_api_info api_info[] = { API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), - API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, 0), + API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), API_ENTRY(0, 0, 0), }; @@ -176,7 +176,7 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) cx18_setup_page(cx, SCB_OFFSET); cx18_write_sync(cx, mb->request, &ack_mb->ack); - cx18_write_reg(cx, ack_irq, SW2_INT_SET); + cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq); return 0; } @@ -225,7 +225,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) } if (info->flags & API_FAST) timeout /= 2; - cx18_write_reg(cx, irq, SW1_INT_SET); + cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request) && cnt < 660) { diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index a33ba04a2686..174682c2582f 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -88,15 +88,13 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, if (buf->id != id) continue; + buf->bytesused = bytesused; - /* the transport buffers are handled differently, - they are not moved to the full queue */ - if (s->type != CX18_ENC_STREAM_TYPE_TS) { - atomic_dec(&s->q_free.buffers); - atomic_inc(&s->q_full.buffers); - s->q_full.bytesused += buf->bytesused; - list_move_tail(&buf->list, &s->q_full.list); - } + atomic_dec(&s->q_free.buffers); + atomic_inc(&s->q_full.buffers); + s->q_full.bytesused += buf->bytesused; + list_move_tail(&buf->list, &s->q_full.list); + spin_unlock(&s->qlock); return buf; } diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h index 86b4cb15d163..594713bbed68 100644 --- a/drivers/media/video/cx18/cx18-scb.h +++ b/drivers/media/video/cx18/cx18-scb.h @@ -128,22 +128,22 @@ struct cx18_scb { u32 apu2cpu_irq; /* Value to write to register SW2 register set (0xC7003140) after the command is cleared */ - u32 apu2cpu_irq_ack; + u32 cpu2apu_irq_ack; u32 reserved2[13]; u32 hpu2cpu_mb_offset; u32 hpu2cpu_irq; - u32 hpu2cpu_irq_ack; + u32 cpu2hpu_irq_ack; u32 reserved3[13]; u32 ppu2cpu_mb_offset; u32 ppu2cpu_irq; - u32 ppu2cpu_irq_ack; + u32 cpu2ppu_irq_ack; u32 reserved4[13]; u32 epu2cpu_mb_offset; u32 epu2cpu_irq; - u32 epu2cpu_irq_ack; + u32 cpu2epu_irq_ack; u32 reserved5[13]; u32 reserved6[8]; @@ -153,22 +153,22 @@ struct cx18_scb { u32 reserved11[7]; u32 cpu2apu_mb_offset; u32 cpu2apu_irq; - u32 cpu2apu_irq_ack; + u32 apu2cpu_irq_ack; u32 reserved12[13]; u32 hpu2apu_mb_offset; u32 hpu2apu_irq; - u32 hpu2apu_irq_ack; + u32 apu2hpu_irq_ack; u32 reserved13[13]; u32 ppu2apu_mb_offset; u32 ppu2apu_irq; - u32 ppu2apu_irq_ack; + u32 apu2ppu_irq_ack; u32 reserved14[13]; u32 epu2apu_mb_offset; u32 epu2apu_irq; - u32 epu2apu_irq_ack; + u32 apu2epu_irq_ack; u32 reserved15[13]; u32 reserved16[8]; @@ -178,22 +178,22 @@ struct cx18_scb { u32 reserved21[7]; u32 cpu2hpu_mb_offset; u32 cpu2hpu_irq; - u32 cpu2hpu_irq_ack; + u32 hpu2cpu_irq_ack; u32 reserved22[13]; u32 apu2hpu_mb_offset; u32 apu2hpu_irq; - u32 apu2hpu_irq_ack; + u32 hpu2apu_irq_ack; u32 reserved23[13]; u32 ppu2hpu_mb_offset; u32 ppu2hpu_irq; - u32 ppu2hpu_irq_ack; + u32 hpu2ppu_irq_ack; u32 reserved24[13]; u32 epu2hpu_mb_offset; u32 epu2hpu_irq; - u32 epu2hpu_irq_ack; + u32 hpu2epu_irq_ack; u32 reserved25[13]; u32 reserved26[8]; @@ -203,22 +203,22 @@ struct cx18_scb { u32 reserved31[7]; u32 cpu2ppu_mb_offset; u32 cpu2ppu_irq; - u32 cpu2ppu_irq_ack; + u32 ppu2cpu_irq_ack; u32 reserved32[13]; u32 apu2ppu_mb_offset; u32 apu2ppu_irq; - u32 apu2ppu_irq_ack; + u32 ppu2apu_irq_ack; u32 reserved33[13]; u32 hpu2ppu_mb_offset; u32 hpu2ppu_irq; - u32 hpu2ppu_irq_ack; + u32 ppu2hpu_irq_ack; u32 reserved34[13]; u32 epu2ppu_mb_offset; u32 epu2ppu_irq; - u32 epu2ppu_irq_ack; + u32 ppu2epu_irq_ack; u32 reserved35[13]; u32 reserved36[8]; @@ -228,22 +228,22 @@ struct cx18_scb { u32 reserved41[7]; u32 cpu2epu_mb_offset; u32 cpu2epu_irq; - u32 cpu2epu_irq_ack; + u32 epu2cpu_irq_ack; u32 reserved42[13]; u32 apu2epu_mb_offset; u32 apu2epu_irq; - u32 apu2epu_irq_ack; + u32 epu2apu_irq_ack; u32 reserved43[13]; u32 hpu2epu_mb_offset; u32 hpu2epu_irq; - u32 hpu2epu_irq_ack; + u32 epu2hpu_irq_ack; u32 reserved44[13]; u32 ppu2epu_mb_offset; u32 ppu2epu_irq; - u32 ppu2epu_irq_ack; + u32 epu2ppu_irq_ack; u32 reserved45[13]; u32 reserved46[8]; diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 078be6319556..d3ae5b4dfca7 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1078,7 +1078,7 @@ static int mpeg_open(struct inode *inode, struct file *file) } } - if (blackbird_initialize_codec(dev) < 0) { + if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) { if (drv) drv->request_release(drv); unlock_kernel(); @@ -1109,6 +1109,8 @@ static int mpeg_open(struct inode *inode, struct file *file) fh->mpegq.field); unlock_kernel(); + atomic_inc(&dev->core->mpeg_users); + return 0; } @@ -1118,7 +1120,7 @@ static int mpeg_release(struct inode *inode, struct file *file) struct cx8802_dev *dev = fh->dev; struct cx8802_driver *drv = NULL; - if (dev->mpeg_active) + if (dev->mpeg_active && atomic_read(&dev->core->mpeg_users) == 1) blackbird_stop_codec(dev); cx8802_cancel_buffers(fh->dev); @@ -1138,6 +1140,8 @@ static int mpeg_release(struct inode *inode, struct file *file) if (drv) drv->request_release(drv); + atomic_dec(&dev->core->mpeg_users); + return 0; } @@ -1158,6 +1162,10 @@ static unsigned int mpeg_poll(struct file *file, struct poll_table_struct *wait) { struct cx8802_fh *fh = file->private_data; + struct cx8802_dev *dev = fh->dev; + + if (!dev->mpeg_active) + blackbird_start_codec(file, fh); return videobuf_poll_stream(file, &fh->mpegq, wait); } diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index cf6c30d4e545..309ca5e68063 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c @@ -598,6 +598,11 @@ static int dvb_register(struct cx8802_dev *dev) struct videobuf_dvb_frontend *fe0, *fe1 = NULL; int mfe_shared = 0; /* bus not shared by default */ + if (0 != core->i2c_rc) { + printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); + goto frontend_detach; + } + /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); if (!fe0) diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a1c435b4b1cd..3ebdcd1d83f8 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -769,10 +769,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, struct cx8802_dev *dev; struct cx88_core *core; int err; -#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) - struct videobuf_dvb_frontend *demod; - int i; -#endif /* general setup */ core = cx88_core_get(pci_dev); @@ -803,15 +799,21 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, mutex_init(&dev->frontends.lock); INIT_LIST_HEAD(&dev->frontends.felist); - if (core->board.num_frontends) - printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); + if (core->board.num_frontends) { + struct videobuf_dvb_frontend *fe; + int i; - for (i = 1; i <= core->board.num_frontends; i++) { - demod = videobuf_dvb_alloc_frontend(&dev->frontends, i); - if(demod == NULL) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); - err = -ENOMEM; - goto fail_free; + printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, + core->board.num_frontends); + for (i = 1; i <= core->board.num_frontends; i++) { + fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); + if(fe == NULL) { + printk(KERN_ERR "%s() failed to alloc\n", + __func__); + videobuf_dvb_dealloc_frontends(&dev->frontends); + err = -ENOMEM; + goto fail_free; + } } } #endif diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 61265fd04d56..b96ce991d968 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1216,8 +1216,12 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) struct cx8800_fh *fh = priv; struct cx8800_dev *dev = fh->dev; - if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) + /* We should remember that this driver also supports teletext, */ + /* so we have to test if the v4l2_buf_type is VBI capture data. */ + if (unlikely((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && + (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))) return -EINVAL; + if (unlikely(i != fh->type)) return -EINVAL; @@ -1232,8 +1236,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) struct cx8800_dev *dev = fh->dev; int err, res; - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && + (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) return -EINVAL; + if (i != fh->type) return -EINVAL; diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 76207c2856b7..f4240965be32 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -352,6 +352,7 @@ struct cx88_core { /* various v4l controls */ u32 freq; atomic_t users; + atomic_t mpeg_users; /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ struct cx8802_dev *dvbdev; diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 4d0817471c9f..6b557c057fac 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig @@ -3,16 +3,16 @@ menuconfig USB_GSPCA depends on VIDEO_V4L2 default m ---help--- - Say Y here if you want to enable selecting webcams based - on the GSPCA framework. + Say Y here if you want to enable selecting webcams based + on the GSPCA framework. - See for more info. + See for more info. - This driver uses the Video For Linux API. You must say Y or M to - "Video For Linux" to use this driver. + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" to use this driver. - To compile this driver as modules, choose M here: the - modules will be called gspca_main. + To compile this driver as modules, choose M here: the + modules will be called gspca_main. if USB_GSPCA && VIDEO_V4L2 @@ -23,190 +23,190 @@ config USB_GSPCA_CONEX tristate "Conexant Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the Conexant chip. + Say Y here if you want support for cameras based on the Conexant chip. - To compile this driver as a module, choose M here: the - module will be called gspca_conex. + To compile this driver as a module, choose M here: the + module will be called gspca_conex. config USB_GSPCA_ETOMS tristate "Etoms USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the Etoms chip. + Say Y here if you want support for cameras based on the Etoms chip. - To compile this driver as a module, choose M here: the - module will be called gspca_etoms. + To compile this driver as a module, choose M here: the + module will be called gspca_etoms. config USB_GSPCA_FINEPIX tristate "Fujifilm FinePix USB V4L2 driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the FinePix chip. + Say Y here if you want support for cameras based on the FinePix chip. - To compile this driver as a module, choose M here: the - module will be called gspca_finepix. + To compile this driver as a module, choose M here: the + module will be called gspca_finepix. config USB_GSPCA_MARS tristate "Mars USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the Mars chip. + Say Y here if you want support for cameras based on the Mars chip. - To compile this driver as a module, choose M here: the - module will be called gspca_mars. + To compile this driver as a module, choose M here: the + module will be called gspca_mars. config USB_GSPCA_OV519 tristate "OV519 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the OV519 chip. + Say Y here if you want support for cameras based on the OV519 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_ov519. + To compile this driver as a module, choose M here: the + module will be called gspca_ov519. config USB_GSPCA_PAC207 tristate "Pixart PAC207 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the PAC207 chip. + Say Y here if you want support for cameras based on the PAC207 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_pac207. + To compile this driver as a module, choose M here: the + module will be called gspca_pac207. config USB_GSPCA_PAC7311 tristate "Pixart PAC7311 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the PAC7311 chip. + Say Y here if you want support for cameras based on the PAC7311 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_pac7311. + To compile this driver as a module, choose M here: the + module will be called gspca_pac7311. config USB_GSPCA_SONIXB tristate "SN9C102 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the SONIXB chip. + Say Y here if you want support for cameras based on the SONIXB chip. - To compile this driver as a module, choose M here: the - module will be called gspca_sonixb. + To compile this driver as a module, choose M here: the + module will be called gspca_sonixb. config USB_GSPCA_SONIXJ tristate "SONIX JPEG USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the SONIXJ chip. + Say Y here if you want support for cameras based on the SONIXJ chip. - To compile this driver as a module, choose M here: the - module will be called gspca_sonixj + To compile this driver as a module, choose M here: the + module will be called gspca_sonixj config USB_GSPCA_SPCA500 tristate "SPCA500 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the SPCA500 chip. + Say Y here if you want support for cameras based on the SPCA500 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_spca500. + To compile this driver as a module, choose M here: the + module will be called gspca_spca500. config USB_GSPCA_SPCA501 tristate "SPCA501 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the SPCA501 chip. + Say Y here if you want support for cameras based on the SPCA501 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_spca501. + To compile this driver as a module, choose M here: the + module will be called gspca_spca501. config USB_GSPCA_SPCA505 tristate "SPCA505 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the SPCA505 chip. + Say Y here if you want support for cameras based on the SPCA505 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_spca505. + To compile this driver as a module, choose M here: the + module will be called gspca_spca505. config USB_GSPCA_SPCA506 tristate "SPCA506 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the SPCA506 chip. + Say Y here if you want support for cameras based on the SPCA506 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_spca506. + To compile this driver as a module, choose M here: the + module will be called gspca_spca506. config USB_GSPCA_SPCA508 tristate "SPCA508 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the SPCA508 chip. + Say Y here if you want support for cameras based on the SPCA508 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_spca508. + To compile this driver as a module, choose M here: the + module will be called gspca_spca508. config USB_GSPCA_SPCA561 tristate "SPCA561 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the SPCA561 chip. + Say Y here if you want support for cameras based on the SPCA561 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_spca561. + To compile this driver as a module, choose M here: the + module will be called gspca_spca561. config USB_GSPCA_STK014 tristate "Syntek DV4000 (STK014) USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the STK014 chip. + Say Y here if you want support for cameras based on the STK014 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_stk014. + To compile this driver as a module, choose M here: the + module will be called gspca_stk014. config USB_GSPCA_SUNPLUS tristate "SUNPLUS USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the Sunplus - SPCA504(abc) SPCA533 SPCA536 chips. + Say Y here if you want support for cameras based on the Sunplus + SPCA504(abc) SPCA533 SPCA536 chips. - To compile this driver as a module, choose M here: the - module will be called gspca_spca5xx. + To compile this driver as a module, choose M here: the + module will be called gspca_spca5xx. config USB_GSPCA_T613 tristate "T613 (JPEG Compliance) USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the T613 chip. + Say Y here if you want support for cameras based on the T613 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_t613. + To compile this driver as a module, choose M here: the + module will be called gspca_t613. config USB_GSPCA_TV8532 tristate "TV8532 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the TV8531 chip. + Say Y here if you want support for cameras based on the TV8531 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_tv8532. + To compile this driver as a module, choose M here: the + module will be called gspca_tv8532. config USB_GSPCA_VC032X tristate "VC032X USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the VC032X chip. + Say Y here if you want support for cameras based on the VC032X chip. - To compile this driver as a module, choose M here: the - module will be called gspca_vc032x. + To compile this driver as a module, choose M here: the + module will be called gspca_vc032x. config USB_GSPCA_ZC3XX - tristate "VC3xx USB Camera Driver" + tristate "ZC3XX USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the ZC3XX chip. + Say Y here if you want support for cameras based on the ZC3XX chip. - To compile this driver as a module, choose M here: the - module will be called gspca_zc3xx. + To compile this driver as a module, choose M here: the + module will be called gspca_zc3xx. endif diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index d0a4451dc46f..8b3101d347c3 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -2266,7 +2266,7 @@ static const struct usb_action hdcs2020b_NoFliker[] = { {} }; -static const struct usb_action hv7131bxx_Initial[] = { +static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, @@ -2290,7 +2290,7 @@ static const struct usb_action hv7131bxx_Initial[] = { {0xaa, 0x14, 0x0001}, {0xaa, 0x15, 0x00e8}, {0xaa, 0x16, 0x0002}, - {0xaa, 0x17, 0x0086}, + {0xaa, 0x17, 0x0086}, /* 00,17,88,aa */ {0xaa, 0x31, 0x0038}, {0xaa, 0x32, 0x0038}, {0xaa, 0x33, 0x0038}, @@ -2309,7 +2309,7 @@ static const struct usb_action hv7131bxx_Initial[] = { {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, - {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */ + {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */ {0xa1, 0x01, 0x0002}, {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, @@ -2374,7 +2374,7 @@ static const struct usb_action hv7131bxx_Initial[] = { {} }; -static const struct usb_action hv7131bxx_InitialScale[] = { +static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, @@ -6388,6 +6388,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) /*fixme: is it really write to 011d and 018d for all other sensors? */ brightness = sd->brightness; reg_w(gspca_dev->dev, brightness, 0x011d); + if (sd->sensor == SENSOR_HV7131B) + return; if (brightness < 0x70) brightness += 0x10; else @@ -6529,6 +6531,7 @@ static void setquality(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_GC0305: + case SENSOR_HV7131B: case SENSOR_OV7620: case SENSOR_PO2030: return; @@ -7209,7 +7212,6 @@ static int sd_start(struct gspca_dev *gspca_dev) mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; zc3_init = init_tb[(int) sd->sensor][mode]; switch (sd->sensor) { - case SENSOR_HV7131B: case SENSOR_HV7131C: zcxx_probeSensor(gspca_dev); break; diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index 0069898bddab..c46bfb1569e3 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig @@ -1,6 +1,6 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" - depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL + depends on VIDEO_V4L2 && PCI && I2C depends on INPUT # due to VIDEO_IR select I2C_ALGOBIT select VIDEO_IR @@ -12,7 +12,6 @@ config VIDEO_IVTV select VIDEO_SAA711X select VIDEO_SAA717X select VIDEO_SAA7127 - select VIDEO_TVAUDIO select VIDEO_CS53L32A select VIDEO_M52790 select VIDEO_WM8775 @@ -32,7 +31,7 @@ config VIDEO_IVTV config VIDEO_FB_IVTV tristate "Conexant cx23415 framebuffer support" - depends on VIDEO_IVTV && FB && EXPERIMENTAL + depends on VIDEO_IVTV && FB select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index d36485023b68..b69cc1d55e5b 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -875,43 +875,43 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) #ifdef MODULE /* load modules */ -#ifndef CONFIG_MEDIA_TUNER +#ifdef CONFIG_MEDIA_TUNER_MODULE hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); #endif -#ifndef CONFIG_VIDEO_CX25840 +#ifdef CONFIG_VIDEO_CX25840_MODULE hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840); #endif -#ifndef CONFIG_VIDEO_SAA711X +#ifdef CONFIG_VIDEO_SAA711X_MODULE hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X); #endif -#ifndef CONFIG_VIDEO_SAA7127 +#ifdef CONFIG_VIDEO_SAA7127_MODULE hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); #endif -#ifndef CONFIG_VIDEO_SAA717X +#ifdef CONFIG_VIDEO_SAA717X_MODULE hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); #endif -#ifndef CONFIG_VIDEO_UPD64031A +#ifdef CONFIG_VIDEO_UPD64031A_MODULE hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); #endif -#ifndef CONFIG_VIDEO_UPD64083 +#ifdef CONFIG_VIDEO_UPD64083_MODULE hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X); #endif -#ifndef CONFIG_VIDEO_MSP3400 +#ifdef CONFIG_VIDEO_MSP3400_MODULE hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX); #endif -#ifndef CONFIG_VIDEO_VP27SMPX +#ifdef CONFIG_VIDEO_VP27SMPX_MODULE hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX); #endif -#ifndef CONFIG_VIDEO_WM8775 +#ifdef CONFIG_VIDEO_WM8775_MODULE hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775); #endif -#ifndef CONFIG_VIDEO_WM8739 +#ifdef CONFIG_VIDEO_WM8739_MODULE hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739); #endif -#ifndef CONFIG_VIDEO_CS53L32A +#ifdef CONFIG_VIDEO_CS53L32A_MODULE hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A); #endif -#ifndef CONFIG_VIDEO_M52790 +#ifdef CONFIG_VIDEO_M52790_MODULE hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790); #endif #endif diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index adf2ba79496a..37860698f782 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c @@ -47,7 +47,7 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ -#define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ +#define SAA7110_MAX_OUTPUT 1 /* 1 YUV */ #define SAA7110_NR_REG 0x35 @@ -327,7 +327,7 @@ saa7110_command (struct i2c_client *client, case DECODER_SET_INPUT: v = *(int *) arg; - if (v < 0 || v > SAA7110_MAX_INPUT) { + if (v < 0 || v >= SAA7110_MAX_INPUT) { v4l_dbg(1, debug, client, "input=%d not available\n", v); return -EINVAL; } diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 249184452949..dfbe08a9ad9b 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -941,7 +941,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); goto fail1; } - dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); + dev->lmmio = ioremap(pci_resource_start(pci_dev, 0), + pci_resource_len(pci_dev, 0)); dev->bmmio = (__u8 __iomem *)dev->lmmio; if (NULL == dev->lmmio) { err = -EIO; diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c index 28421d386f1e..c710bcd1df48 100644 --- a/drivers/media/video/usbvideo/ibmcam.c +++ b/drivers/media/video/usbvideo/ibmcam.c @@ -3695,7 +3695,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * unsigned char video_ep = 0; if (debug >= 1) - dev_info(&uvd->dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); + dev_info(&dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) @@ -3746,7 +3746,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ break; } - dev_info(&uvd->dev->dev, + dev_info(&dev->dev, "%s USB camera found (model %d, rev. 0x%04x)\n", brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); } while (0); @@ -3754,7 +3754,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * /* Validate found interface: must have one ISO endpoint */ nas = intf->num_altsetting; if (debug > 0) - dev_info(&uvd->dev->dev, "Number of alternate settings=%d.\n", + dev_info(&dev->dev, "Number of alternate settings=%d.\n", nas); if (nas < 2) { err("Too few alternate settings for this camera!"); @@ -3799,7 +3799,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * actInterface = i; maxPS = le16_to_cpu(endpoint->wMaxPacketSize); if (debug > 0) - dev_info(&uvd->dev->dev, + dev_info(&dev->dev, "Active setting=%d. " "maxPS=%d.\n", i, maxPS); } else @@ -3840,7 +3840,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * RESTRICT_TO_RANGE(framerate, 0, 5); break; default: - dev_info(&uvd->dev->dev, "IBM camera: using 320x240\n"); + dev_info(&dev->dev, "IBM camera: using 320x240\n"); size = SIZE_320x240; /* No break here */ case SIZE_320x240: @@ -3869,7 +3869,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * canvasY = 120; break; default: - dev_info(&uvd->dev->dev, "IBM NetCamera: using 176x144\n"); + dev_info(&dev->dev, "IBM NetCamera: using 176x144\n"); size = SIZE_176x144; /* No break here */ case SIZE_176x144: