Commit 853041f0 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (35 commits)
  V4L/DVB (9516): cx18: Move DVB buffer transfer handling from irq handler to work_queue
  V4L/DVB (9557): gspca: Small changes for the sensor HV7131B in zc3xx.
  V4L/DVB (9556): gspca: Bad init sequence for sensor HV7131B in zc3xx.
  V4L/DVB (9549): gspca: Fix a typo in one of gspca chips name.
  V4L/DVB (9515): cx18: Use correct Mailbox IRQ Ack values and misc IRQ handling cleanup
  V4L/DVB (9493): kconfig patch
  V4L/DVB (9527): af9015: fix compile warnings
  V4L/DVB (9524): af9013: fix bug in status reading
  V4L/DVB (9511): cx18: Mark CX18_CPU_DE_RELEASE_MDL as a slow API call
  V4L/DVB (9510): cx18: Fix write retries for registers that always change - part 2.
  V4L/DVB (9506): ivtv/cx18: fix test whether modules should be loaded or not.
  V4L/DVB (9499): cx88-mpeg: final fix for analogue only compilation + de-alloc fix
  V4L/DVB (9496): cx88-blackbird: bugfix: cx88-blackbird-mpeg-users
  V4L/DVB (9495): cx88-blackbird: bugfix: cx88-blackbird-poll-fix
  V4L/DVB (9494): anysee: initialize anysee_usb_mutex statically
  V4L/DVB (9492): unplug oops from dvb_frontend_init...
  V4L/DVB (9486): ivtv/ivtvfb: no longer experimental
  V4L/DVB (9485): ivtv: remove incorrect V4L1 & tvaudio dependency
  V4L/DVB (9482): Documentation, especially regarding audio and informational links
  V4L/DVB (9475): cx18: Disable write retries for registers that always change - part 1.
  ...
parents e892873c 1d6782bd
...@@ -56,30 +56,6 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org> ...@@ -56,30 +56,6 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org>
--------------------------- ---------------------------
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 <hverkuil@xs4all.nl>
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
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 <hverkuil@xs4all.nl>
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
When: November 2005 When: November 2005
Files: drivers/pcmcia/: pcmcia_ioctl.c Files: drivers/pcmcia/: pcmcia_ioctl.c
......
...@@ -27,8 +27,8 @@ audio ...@@ -27,8 +27,8 @@ audio
sound card) should be possible, but there is no code yet ... sound card) should be possible, but there is no code yet ...
vbi vbi
- some code present. Doesn't crash any more, but also doesn't - Code present. Works for NTSC closed caption. PAL and other
work yet ... TV norms may or may not work.
how to add support for new cards how to add support for new cards
......
Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers
Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
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
...@@ -1879,6 +1879,37 @@ M: linux-kernel@vger.kernel.org ...@@ -1879,6 +1879,37 @@ M: linux-kernel@vger.kernel.org
W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/ W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/
S: Maintained 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 HARDWARE MONITORING
L: lm-sensors@lm-sensors.org L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.org/ W: http://www.lm-sensors.org/
......
...@@ -1265,6 +1265,7 @@ static const struct hid_device_id hid_blacklist[] = { ...@@ -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_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_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_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_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_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
......
...@@ -253,6 +253,9 @@ ...@@ -253,6 +253,9 @@
#define USB_VENDOR_ID_KBGEAR 0x084e #define USB_VENDOR_ID_KBGEAR 0x084e
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 #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_VENDOR_ID_LABTEC 0x1020
#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
......
...@@ -223,6 +223,8 @@ static void dvb_frontend_init(struct dvb_frontend *fe) ...@@ -223,6 +223,8 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
if (fe->ops.init) if (fe->ops.init)
fe->ops.init(fe); fe->ops.init(fe);
if (fe->ops.tuner_ops.init) { 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); fe->ops.tuner_ops.init(fe);
if (fe->ops.i2c_gate_ctrl) if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); fe->ops.i2c_gate_ctrl(fe, 0);
......
...@@ -283,6 +283,7 @@ config DVB_USB_ANYSEE ...@@ -283,6 +283,7 @@ config DVB_USB_ANYSEE
config DVB_USB_DTV5100 config DVB_USB_DTV5100
tristate "AME DTV-5100 USB2.0 DVB-T support" tristate "AME DTV-5100 USB2.0 DVB-T support"
depends on DVB_USB depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
help help
Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
......
...@@ -31,13 +31,13 @@ ...@@ -31,13 +31,13 @@
#include "mc44s80x.h" #include "mc44s80x.h"
#endif #endif
int dvb_usb_af9015_debug; static int dvb_usb_af9015_debug;
module_param_named(debug, dvb_usb_af9015_debug, int, 0644); module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); 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_param_named(remote, dvb_usb_af9015_remote, int, 0644);
MODULE_PARM_DESC(remote, "select remote"); 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_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644);
MODULE_PARM_DESC(dual_mode, "enable dual mode"); MODULE_PARM_DESC(dual_mode, "enable dual mode");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
...@@ -46,7 +46,7 @@ static DEFINE_MUTEX(af9015_usb_mutex); ...@@ -46,7 +46,7 @@ static DEFINE_MUTEX(af9015_usb_mutex);
static struct af9015_config af9015_config; static struct af9015_config af9015_config;
static struct dvb_usb_device_properties af9015_properties[2]; 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[] = { static struct af9013_config af9015_af9013_config[] = {
{ {
...@@ -549,7 +549,7 @@ static int af9015_eeprom_dump(struct dvb_usb_device *d) ...@@ -549,7 +549,7 @@ static int af9015_eeprom_dump(struct dvb_usb_device *d)
return 0; 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; int i, packets = 0, ret;
u16 addr = 0x9a56; /* ir-table start address */ 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) ...@@ -999,7 +999,7 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
} }
/* init 2nd I2C adapter */ /* 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; int ret;
struct af9015_state *state = d->priv; struct af9015_state *state = d->priv;
...@@ -1419,7 +1419,7 @@ static int af9015_usb_probe(struct usb_interface *intf, ...@@ -1419,7 +1419,7 @@ static int af9015_usb_probe(struct usb_interface *intf,
return ret; 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; struct af9015_state *state = d->priv;
deb_info("%s: \n", __func__); deb_info("%s: \n", __func__);
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#define DVB_USB_LOG_PREFIX "af9015" #define DVB_USB_LOG_PREFIX "af9015"
#include "dvb-usb.h" #include "dvb-usb.h"
extern int dvb_usb_af9015_debug;
#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args) #define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
#define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args) #define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args)
#define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args) #define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args)
......
...@@ -46,7 +46,7 @@ module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644); ...@@ -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)"); MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 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, static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
u8 *rbuf, u8 rlen) u8 *rbuf, u8 rlen)
...@@ -456,8 +456,6 @@ static int anysee_probe(struct usb_interface *intf, ...@@ -456,8 +456,6 @@ static int anysee_probe(struct usb_interface *intf,
struct usb_host_interface *alt; struct usb_host_interface *alt;
int ret; int ret;
mutex_init(&anysee_usb_mutex);
/* There is one interface with two alternate settings. /* There is one interface with two alternate settings.
Alternate setting 0 is for bulk transfer. Alternate setting 0 is for bulk transfer.
Alternate setting 1 is for isochronous transfer. Alternate setting 1 is for isochronous transfer.
......
...@@ -13,14 +13,14 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, ...@@ -13,14 +13,14 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
{ {
int actlen,ret = -ENOMEM; int actlen,ret = -ENOMEM;
if (!d || wbuf == NULL || wlen == 0)
return -EINVAL;
if (d->props.generic_bulk_ctrl_endpoint == 0) { if (d->props.generic_bulk_ctrl_endpoint == 0) {
err("endpoint for generic control not specified."); err("endpoint for generic control not specified.");
return -EINVAL; return -EINVAL;
} }
if (wbuf == NULL || wlen == 0)
return -EINVAL;
if ((ret = mutex_lock_interruptible(&d->usb_mutex))) if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
return ret; return ret;
......
...@@ -1187,7 +1187,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) ...@@ -1187,7 +1187,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
if (tmp) if (tmp)
*status |= FE_HAS_SYNC | FE_HAS_LOCK; *status |= FE_HAS_SYNC | FE_HAS_LOCK;
if (!*status & FE_HAS_SIGNAL) { if (!(*status & FE_HAS_SIGNAL)) {
/* AGC lock */ /* AGC lock */
ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp);
if (ret) if (ret)
...@@ -1196,7 +1196,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) ...@@ -1196,7 +1196,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
*status |= FE_HAS_SIGNAL; *status |= FE_HAS_SIGNAL;
} }
if (!*status & FE_HAS_CARRIER) { if (!(*status & FE_HAS_CARRIER)) {
/* CFO lock */ /* CFO lock */
ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp);
if (ret) if (ret)
...@@ -1205,7 +1205,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) ...@@ -1205,7 +1205,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
*status |= FE_HAS_CARRIER; *status |= FE_HAS_CARRIER;
} }
if (!*status & FE_HAS_CARRIER) { if (!(*status & FE_HAS_CARRIER)) {
/* SFOE lock */ /* SFOE lock */
ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp);
if (ret) if (ret)
......
...@@ -355,6 +355,20 @@ config USB_SI470X ...@@ -355,6 +355,20 @@ config USB_SI470X
tristate "Silicon Labs Si470x FM Radio Receiver support" tristate "Silicon Labs Si470x FM Radio Receiver support"
depends on USB && VIDEO_V4L2 depends on USB && VIDEO_V4L2
---help--- ---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 Say Y here if you want to connect this type of radio to your
computer's USB port. computer's USB port.
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers: * Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers:
* - Silicon Labs USB FM Radio Reference Design * - Silicon Labs USB FM Radio Reference Design
* - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) * - 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 <tobias.lorenz@gmx.net> * Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
* *
...@@ -23,19 +24,6 @@ ...@@ -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: * History:
* 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net> * 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net>
...@@ -105,6 +93,9 @@ ...@@ -105,6 +93,9 @@
* - afc indication * - afc indication
* - more safety checks, let si470x_get_freq return errno * - more safety checks, let si470x_get_freq return errno
* - vidioc behavior corrected according to v4l2 spec * - vidioc behavior corrected according to v4l2 spec
* 2008-10-20 Alexey Klimov <klimov.linux@gmail.com>
* - add support for KWorld USB FM Radio FM700
* - blacklisted KWorld radio in hid-core.c and hid-ids.h
* *
* ToDo: * ToDo:
* - add firmware download/update support * - add firmware download/update support
...@@ -145,6 +136,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { ...@@ -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) }, { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
/* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, { 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 */ /* Terminating entry */
{ } { }
}; };
......
...@@ -1476,12 +1476,9 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) ...@@ -1476,12 +1476,9 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp)
{ {
struct cafe_camera *cam; struct cafe_camera *cam;
lock_kernel();
cam = cafe_find_dev(iminor(inode)); cam = cafe_find_dev(iminor(inode));
if (cam == NULL) { if (cam == NULL)
unlock_kernel();
return -ENODEV; return -ENODEV;
}
filp->private_data = cam; filp->private_data = cam;
mutex_lock(&cam->s_mutex); mutex_lock(&cam->s_mutex);
...@@ -1493,7 +1490,6 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) ...@@ -1493,7 +1490,6 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp)
} }
(cam->users)++; (cam->users)++;
mutex_unlock(&cam->s_mutex); mutex_unlock(&cam->s_mutex);
unlock_kernel();
return 0; return 0;
} }
......
...@@ -867,6 +867,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -867,6 +867,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOC_STREAMON32: case VIDIOC_STREAMON32:
case VIDIOC_STREAMOFF32: case VIDIOC_STREAMOFF32:
case VIDIOC_G_PARM: case VIDIOC_G_PARM:
case VIDIOC_S_PARM:
case VIDIOC_G_STD: case VIDIOC_G_STD:
case VIDIOC_S_STD: case VIDIOC_S_STD:
case VIDIOC_G_TUNER: case VIDIOC_G_TUNER:
...@@ -885,6 +886,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -885,6 +886,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOC_S_INPUT32: case VIDIOC_S_INPUT32:
case VIDIOC_TRY_FMT32: case VIDIOC_TRY_FMT32:
case VIDIOC_S_HW_FREQ_SEEK: case VIDIOC_S_HW_FREQ_SEEK:
case VIDIOC_ENUM_FRAMESIZES:
case VIDIOC_ENUM_FRAMEINTERVALS:
ret = do_video_ioctl(file, cmd, arg); ret = do_video_ioctl(file, cmd, arg);
break; break;
......
...@@ -448,7 +448,14 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) ...@@ -448,7 +448,14 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
mutex_init(&cx->gpio_lock); mutex_init(&cx->gpio_lock);
spin_lock_init(&cx->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 */ /* start counting open_id at 1 */
cx->open_id = 1; cx->open_id = 1;
...@@ -581,10 +588,10 @@ static void cx18_load_and_init_modules(struct cx18 *cx) ...@@ -581,10 +588,10 @@ static void cx18_load_and_init_modules(struct cx18 *cx)
#ifdef MODULE #ifdef MODULE
/* load modules */ /* load modules */
#ifndef CONFIG_MEDIA_TUNER #ifdef CONFIG_MEDIA_TUNER_MODULE
hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
#endif #endif
#ifndef CONFIG_VIDEO_CS5345 #ifdef CONFIG_VIDEO_CS5345_MODULE
hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
#endif #endif
#endif #endif
...@@ -832,6 +839,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, ...@@ -832,6 +839,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
free_mem: free_mem:
release_mem_region(cx->base_addr, CX18_MEM_SIZE); release_mem_region(cx->base_addr, CX18_MEM_SIZE);
free_workqueue: free_workqueue:
destroy_workqueue(cx->work_queue);
err: err:
if (retval == 0) if (retval == 0)
retval = -ENODEV; retval = -ENODEV;
...@@ -932,6 +940,9 @@ static void cx18_remove(struct pci_dev *pci_dev) ...@@ -932,6 +940,9 @@ static void cx18_remove(struct pci_dev *pci_dev)
cx18_halt_firmware(cx); cx18_halt_firmware(cx);
flush_workqueue(cx->work_queue);
destroy_workqueue(cx->work_queue);
cx18_streams_cleanup(cx, 1); cx18_streams_cleanup(cx, 1);
exit_cx18_i2c(cx); exit_cx18_i2c(cx);
......
...@@ -199,12 +199,15 @@ struct cx18_options { ...@@ -199,12 +199,15 @@ struct cx18_options {
#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
/* per-cx18, i_flags */ /* per-cx18, i_flags */
#define CX18_F_I_LOADED_FW 0 /* Loaded the firmware the first time */ #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
#define CX18_F_I_EOS 4 /* End of encoder stream reached */ #define CX18_F_I_EOS 4 /* End of encoder stream */
#define CX18_F_I_RADIO_USER 5 /* The radio tuner is selected */ #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_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_INITED 21 /* set after first open */
#define CX18_F_I_FAILED 22 /* set if first open failed */ #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. */ /* These are the VBI types as they appear in the embedded VBI private packets. */
#define CX18_SLICED_TYPE_TELETEXT_B (1) #define CX18_SLICED_TYPE_TELETEXT_B (1)
...@@ -402,8 +405,6 @@ struct cx18 { ...@@ -402,8 +405,6 @@ struct cx18 {
spinlock_t lock; /* lock access to this struct */ spinlock_t lock; /* lock access to this struct */
int search_pack_header; 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 int open_id; /* incremented each time an open occurs, used as
unique ID. Starts at 1, so 0 can be used as unique ID. Starts at 1, so 0 can be used as
uninitialized value in the stream->id. */ uninitialized value in the stream->id. */
...@@ -433,6 +434,9 @@ struct cx18 { ...@@ -433,6 +434,9 @@ struct cx18 {
/* when the current DMA is finished this queue is woken up */ /* when the current DMA is finished this queue is woken up */
wait_queue_head_t dma_waitq; wait_queue_head_t dma_waitq;
struct workqueue_struct *work_queue;
struct work_struct work;
/* i2c */ /* i2c */
struct i2c_adapter i2c_adap[2]; struct i2c_adapter i2c_adap[2];
struct i2c_algo_bit_data i2c_algo[2]; struct i2c_algo_bit_data i2c_algo[2];
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include "cx18-dvb.h" #include "cx18-dvb.h"
#include "cx18-io.h" #include "cx18-io.h"
#include "cx18-streams.h" #include "cx18-streams.h"
#include "cx18-queue.h"
#include "cx18-scb.h"
#include "cx18-cards.h" #include "cx18-cards.h"
#include "s5h1409.h" #include "s5h1409.h"
#include "mxl5005s.h" #include "mxl5005s.h"
...@@ -300,3 +302,24 @@ static int dvb_register(struct cx18_stream *stream) ...@@ -300,3 +302,24 @@ static int dvb_register(struct cx18_stream *stream)
return ret; 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);
}
}
...@@ -23,3 +23,4 @@ ...@@ -23,3 +23,4 @@
int cx18_dvb_register(struct cx18_stream *stream); int cx18_dvb_register(struct cx18_stream *stream);
void cx18_dvb_unregister(struct cx18_stream *stream); void cx18_dvb_unregister(struct cx18_stream *stream);
void cx18_dvb_work_handler(struct cx18 *cx);
...@@ -88,6 +88,19 @@ void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr) ...@@ -88,6 +88,19 @@ void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
cx18_log_write_retries(cx, i, 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) void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr)
{ {
int i; int i;
...@@ -218,7 +231,7 @@ void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) ...@@ -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) void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
{ {
u32 r; 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); r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
cx18_write_reg(cx, r | val, 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) ...@@ -233,7 +246,7 @@ void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
{ {
u32 r; 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); r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI);
} }
......
...@@ -133,6 +133,8 @@ static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr) ...@@ -133,6 +133,8 @@ static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
cx18_writel_noretry(cx, val, 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 static inline
void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) 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) ...@@ -271,6 +273,21 @@ static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
cx18_write_reg_noretry(cx, val, 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) static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg)
{ {
......
...@@ -29,8 +29,20 @@ ...@@ -29,8 +29,20 @@
#include "cx18-mailbox.h" #include "cx18-mailbox.h"
#include "cx18-vbi.h" #include "cx18-vbi.h"
#include "cx18-scb.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, &param);
}
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) 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) ...@@ -67,17 +79,11 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
if (buf) { if (buf) {
cx18_buf_sync_for_cpu(s, buf); cx18_buf_sync_for_cpu(s, buf);
if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
/* process the buffer here */ CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n",
CX18_DEBUG_HI_DMA("TS recv and sent bytesused=%d\n",
buf->bytesused); buf->bytesused);
dvb_dmx_swfilter(&s->dvb.demux, buf->buf, set_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags);
buf->bytesused); set_bit(CX18_F_I_HAVE_WORK, &cx->i_flags);
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);
} else } else
set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
} else { } else {
...@@ -109,7 +115,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb) ...@@ -109,7 +115,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb)
CX18_INFO("FW version: %s\n", p - 1); 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; struct cx18_mailbox mb;
...@@ -125,12 +131,31 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1) ...@@ -125,12 +131,31 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1)
epu_debug(cx, &mb); epu_debug(cx, &mb);
break; break;
default: default:
CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd); CX18_WARN("Unknown CPU_TO_EPU mailbox command %#08x\n",
mb.cmd);
break; 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) irqreturn_t cx18_irq_handler(int irq, void *dev_id)
...@@ -140,43 +165,36 @@ 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 sw2, sw2_mask;
u32 hw2, hw2_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_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI);
hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask; 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); if (sw1)
cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS); cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1);
cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS); 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) if (sw1 || sw2 || hw2)
CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
/* To do: interrupt-based I2C handling /* To do: interrupt-based I2C handling
if (hw2 & 0x00c00000) { if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) {
} }
*/ */
if (sw2) { if (sw2)
if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) | xpu_ack(cx, sw2);
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 (sw1) if (sw1)
hpu_cmd(cx, sw1); epu_cmd(cx, sw1);
spin_unlock(&cx->dma_reg_lock);
if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags))
queue_work(cx->work_queue, &cx->work);
return (hw2 | sw1 | sw2) ? IRQ_HANDLED : IRQ_NONE; return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE;
} }
...@@ -32,6 +32,4 @@ ...@@ -32,6 +32,4 @@
irqreturn_t cx18_irq_handler(int irq, void *dev_id); irqreturn_t cx18_irq_handler(int irq, void *dev_id);
void cx18_irq_work_handler(struct work_struct *work); void cx18_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);
...@@ -83,7 +83,7 @@ static const struct cx18_api_info api_info[] = { ...@@ -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_ACK, 0),
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
API_ENTRY(CPU, CX18_APU_RESETAI, 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), API_ENTRY(0, 0, 0),
}; };
...@@ -176,7 +176,7 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) ...@@ -176,7 +176,7 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb)
cx18_setup_page(cx, SCB_OFFSET); cx18_setup_page(cx, SCB_OFFSET);
cx18_write_sync(cx, mb->request, &ack_mb->ack); 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; return 0;
} }
...@@ -225,7 +225,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) ...@@ -225,7 +225,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
} }
if (info->flags & API_FAST) if (info->flags & API_FAST)
timeout /= 2; 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) while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request)
&& cnt < 660) { && cnt < 660) {
......
...@@ -88,15 +88,13 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, ...@@ -88,15 +88,13 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
if (buf->id != id) if (buf->id != id)
continue; continue;
buf->bytesused = bytesused; 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_dec(&s->q_free.buffers);
atomic_inc(&s->q_full.buffers); atomic_inc(&s->q_full.buffers);
s->q_full.bytesused += buf->bytesused; s->q_full.bytesused += buf->bytesused;
list_move_tail(&buf->list, &s->q_full.list); list_move_tail(&buf->list, &s->q_full.list);
}
spin_unlock(&s->qlock); spin_unlock(&s->qlock);
return buf; return buf;
} }
......
...@@ -128,22 +128,22 @@ struct cx18_scb { ...@@ -128,22 +128,22 @@ struct cx18_scb {
u32 apu2cpu_irq; u32 apu2cpu_irq;
/* Value to write to register SW2 register set (0xC7003140) after the /* Value to write to register SW2 register set (0xC7003140) after the
command is cleared */ command is cleared */
u32 apu2cpu_irq_ack; u32 cpu2apu_irq_ack;
u32 reserved2[13]; u32 reserved2[13];
u32 hpu2cpu_mb_offset; u32 hpu2cpu_mb_offset;
u32 hpu2cpu_irq; u32 hpu2cpu_irq;
u32 hpu2cpu_irq_ack; u32 cpu2hpu_irq_ack;
u32 reserved3[13]; u32 reserved3[13];
u32 ppu2cpu_mb_offset; u32 ppu2cpu_mb_offset;
u32 ppu2cpu_irq; u32 ppu2cpu_irq;
u32 ppu2cpu_irq_ack; u32 cpu2ppu_irq_ack;
u32 reserved4[13]; u32 reserved4[13];
u32 epu2cpu_mb_offset; u32 epu2cpu_mb_offset;
u32 epu2cpu_irq; u32 epu2cpu_irq;
u32 epu2cpu_irq_ack; u32 cpu2epu_irq_ack;
u32 reserved5[13]; u32 reserved5[13];
u32 reserved6[8]; u32 reserved6[8];
...@@ -153,22 +153,22 @@ struct cx18_scb { ...@@ -153,22 +153,22 @@ struct cx18_scb {
u32 reserved11[7]; u32 reserved11[7];
u32 cpu2apu_mb_offset; u32 cpu2apu_mb_offset;
u32 cpu2apu_irq; u32 cpu2apu_irq;
u32 cpu2apu_irq_ack; u32 apu2cpu_irq_ack;
u32 reserved12[13]; u32 reserved12[13];
u32 hpu2apu_mb_offset; u32 hpu2apu_mb_offset;
u32 hpu2apu_irq; u32 hpu2apu_irq;
u32 hpu2apu_irq_ack; u32 apu2hpu_irq_ack;
u32 reserved13[13]; u32 reserved13[13];
u32 ppu2apu_mb_offset; u32 ppu2apu_mb_offset;
u32 ppu2apu_irq; u32 ppu2apu_irq;
u32 ppu2apu_irq_ack; u32 apu2ppu_irq_ack;
u32 reserved14[13]; u32 reserved14[13];
u32 epu2apu_mb_offset; u32 epu2apu_mb_offset;
u32 epu2apu_irq; u32 epu2apu_irq;
u32 epu2apu_irq_ack; u32 apu2epu_irq_ack;
u32 reserved15[13]; u32 reserved15[13];
u32 reserved16[8]; u32 reserved16[8];
...@@ -178,22 +178,22 @@ struct cx18_scb { ...@@ -178,22 +178,22 @@ struct cx18_scb {
u32 reserved21[7]; u32 reserved21[7];
u32 cpu2hpu_mb_offset; u32 cpu2hpu_mb_offset;
u32 cpu2hpu_irq; u32 cpu2hpu_irq;
u32 cpu2hpu_irq_ack; u32 hpu2cpu_irq_ack;
u32 reserved22[13]; u32 reserved22[13];
u32 apu2hpu_mb_offset; u32 apu2hpu_mb_offset;
u32 apu2hpu_irq; u32 apu2hpu_irq;
u32 apu2hpu_irq_ack; u32 hpu2apu_irq_ack;
u32 reserved23[13]; u32 reserved23[13];
u32 ppu2hpu_mb_offset; u32 ppu2hpu_mb_offset;
u32 ppu2hpu_irq; u32 ppu2hpu_irq;
u32 ppu2hpu_irq_ack; u32 hpu2ppu_irq_ack;
u32 reserved24[13]; u32 reserved24[13];
u32 epu2hpu_mb_offset; u32 epu2hpu_mb_offset;
u32 epu2hpu_irq; u32 epu2hpu_irq;
u32 epu2hpu_irq_ack; u32 hpu2epu_irq_ack;
u32 reserved25[13]; u32 reserved25[13];
u32 reserved26[8]; u32 reserved26[8];
...@@ -203,22 +203,22 @@ struct cx18_scb { ...@@ -203,22 +203,22 @@ struct cx18_scb {
u32 reserved31[7]; u32 reserved31[7];
u32 cpu2ppu_mb_offset; u32 cpu2ppu_mb_offset;
u32 cpu2ppu_irq; u32 cpu2ppu_irq;
u32 cpu2ppu_irq_ack; u32 ppu2cpu_irq_ack;
u32 reserved32[13]; u32 reserved32[13];
u32 apu2ppu_mb_offset; u32 apu2ppu_mb_offset;
u32 apu2ppu_irq; u32 apu2ppu_irq;
u32 apu2ppu_irq_ack; u32 ppu2apu_irq_ack;
u32 reserved33[13]; u32 reserved33[13];
u32 hpu2ppu_mb_offset; u32 hpu2ppu_mb_offset;
u32 hpu2ppu_irq; u32 hpu2ppu_irq;
u32 hpu2ppu_irq_ack; u32 ppu2hpu_irq_ack;
u32 reserved34[13]; u32 reserved34[13];
u32 epu2ppu_mb_offset; u32 epu2ppu_mb_offset;
u32 epu2ppu_irq; u32 epu2ppu_irq;
u32 epu2ppu_irq_ack; u32 ppu2epu_irq_ack;
u32 reserved35[13]; u32 reserved35[13];
u32 reserved36[8]; u32 reserved36[8];
...@@ -228,22 +228,22 @@ struct cx18_scb { ...@@ -228,22 +228,22 @@ struct cx18_scb {
u32 reserved41[7]; u32 reserved41[7];
u32 cpu2epu_mb_offset; u32 cpu2epu_mb_offset;
u32 cpu2epu_irq; u32 cpu2epu_irq;
u32 cpu2epu_irq_ack; u32 epu2cpu_irq_ack;
u32 reserved42[13]; u32 reserved42[13];
u32 apu2epu_mb_offset; u32 apu2epu_mb_offset;
u32 apu2epu_irq; u32 apu2epu_irq;
u32 apu2epu_irq_ack; u32 epu2apu_irq_ack;
u32 reserved43[13]; u32 reserved43[13];
u32 hpu2epu_mb_offset; u32 hpu2epu_mb_offset;
u32 hpu2epu_irq; u32 hpu2epu_irq;
u32 hpu2epu_irq_ack; u32 epu2hpu_irq_ack;
u32 reserved44[13]; u32 reserved44[13];
u32 ppu2epu_mb_offset; u32 ppu2epu_mb_offset;
u32 ppu2epu_irq; u32 ppu2epu_irq;
u32 ppu2epu_irq_ack; u32 epu2ppu_irq_ack;
u32 reserved45[13]; u32 reserved45[13];
u32 reserved46[8]; u32 reserved46[8];
......
...@@ -1078,7 +1078,7 @@ static int mpeg_open(struct inode *inode, struct file *file) ...@@ -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) if (drv)
drv->request_release(drv); drv->request_release(drv);
unlock_kernel(); unlock_kernel();
...@@ -1109,6 +1109,8 @@ static int mpeg_open(struct inode *inode, struct file *file) ...@@ -1109,6 +1109,8 @@ static int mpeg_open(struct inode *inode, struct file *file)
fh->mpegq.field); fh->mpegq.field);
unlock_kernel(); unlock_kernel();
atomic_inc(&dev->core->mpeg_users);
return 0; return 0;
} }
...@@ -1118,7 +1120,7 @@ static int mpeg_release(struct inode *inode, struct file *file) ...@@ -1118,7 +1120,7 @@ static int mpeg_release(struct inode *inode, struct file *file)
struct cx8802_dev *dev = fh->dev; struct cx8802_dev *dev = fh->dev;
struct cx8802_driver *drv = NULL; struct cx8802_driver *drv = NULL;
if (dev->mpeg_active) if (dev->mpeg_active && atomic_read(&dev->core->mpeg_users) == 1)
blackbird_stop_codec(dev); blackbird_stop_codec(dev);
cx8802_cancel_buffers(fh->dev); cx8802_cancel_buffers(fh->dev);
...@@ -1138,6 +1140,8 @@ static int mpeg_release(struct inode *inode, struct file *file) ...@@ -1138,6 +1140,8 @@ static int mpeg_release(struct inode *inode, struct file *file)
if (drv) if (drv)
drv->request_release(drv); drv->request_release(drv);
atomic_dec(&dev->core->mpeg_users);
return 0; return 0;
} }
...@@ -1158,6 +1162,10 @@ static unsigned int ...@@ -1158,6 +1162,10 @@ static unsigned int
mpeg_poll(struct file *file, struct poll_table_struct *wait) mpeg_poll(struct file *file, struct poll_table_struct *wait)
{ {
struct cx8802_fh *fh = file->private_data; 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); return videobuf_poll_stream(file, &fh->mpegq, wait);
} }
......
...@@ -598,6 +598,11 @@ static int dvb_register(struct cx8802_dev *dev) ...@@ -598,6 +598,11 @@ static int dvb_register(struct cx8802_dev *dev)
struct videobuf_dvb_frontend *fe0, *fe1 = NULL; struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
int mfe_shared = 0; /* bus not shared by default */ 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 */ /* Get the first frontend */
fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
if (!fe0) if (!fe0)
......
...@@ -769,10 +769,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, ...@@ -769,10 +769,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
struct cx8802_dev *dev; struct cx8802_dev *dev;
struct cx88_core *core; struct cx88_core *core;
int err; int err;
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
struct videobuf_dvb_frontend *demod;
int i;
#endif
/* general setup */ /* general setup */
core = cx88_core_get(pci_dev); core = cx88_core_get(pci_dev);
...@@ -803,17 +799,23 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, ...@@ -803,17 +799,23 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
mutex_init(&dev->frontends.lock); mutex_init(&dev->frontends.lock);
INIT_LIST_HEAD(&dev->frontends.felist); INIT_LIST_HEAD(&dev->frontends.felist);
if (core->board.num_frontends) if (core->board.num_frontends) {
printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); struct videobuf_dvb_frontend *fe;
int i;
printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
core->board.num_frontends);
for (i = 1; i <= core->board.num_frontends; i++) { for (i = 1; i <= core->board.num_frontends; i++) {
demod = videobuf_dvb_alloc_frontend(&dev->frontends, i); fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
if(demod == NULL) { if(fe == NULL) {
printk(KERN_ERR "%s() failed to alloc\n", __func__); printk(KERN_ERR "%s() failed to alloc\n",
__func__);
videobuf_dvb_dealloc_frontends(&dev->frontends);
err = -ENOMEM; err = -ENOMEM;
goto fail_free; goto fail_free;
} }
} }
}
#endif #endif
/* Maintain a reference so cx88-video can query the 8802 device. */ /* Maintain a reference so cx88-video can query the 8802 device. */
......
...@@ -1216,8 +1216,12 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) ...@@ -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_fh *fh = priv;
struct cx8800_dev *dev = fh->dev; 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; return -EINVAL;
if (unlikely(i != fh->type)) if (unlikely(i != fh->type))
return -EINVAL; return -EINVAL;
...@@ -1232,8 +1236,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) ...@@ -1232,8 +1236,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
struct cx8800_dev *dev = fh->dev; struct cx8800_dev *dev = fh->dev;
int err, res; 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; return -EINVAL;
if (i != fh->type) if (i != fh->type)
return -EINVAL; return -EINVAL;
......
...@@ -352,6 +352,7 @@ struct cx88_core { ...@@ -352,6 +352,7 @@ struct cx88_core {
/* various v4l controls */ /* various v4l controls */
u32 freq; u32 freq;
atomic_t users; atomic_t users;
atomic_t mpeg_users;
/* cx88-video needs to access cx8802 for hybrid tuner pll access. */ /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
struct cx8802_dev *dvbdev; struct cx8802_dev *dvbdev;
......
...@@ -201,7 +201,7 @@ config USB_GSPCA_VC032X ...@@ -201,7 +201,7 @@ config USB_GSPCA_VC032X
module will be called gspca_vc032x. module will be called gspca_vc032x.
config USB_GSPCA_ZC3XX config USB_GSPCA_ZC3XX
tristate "VC3xx USB Camera Driver" tristate "ZC3XX USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA depends on VIDEO_V4L2 && USB_GSPCA
help 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.
......
...@@ -2266,7 +2266,7 @@ static const struct usb_action hdcs2020b_NoFliker[] = { ...@@ -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, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
...@@ -2290,7 +2290,7 @@ static const struct usb_action hv7131bxx_Initial[] = { ...@@ -2290,7 +2290,7 @@ static const struct usb_action hv7131bxx_Initial[] = {
{0xaa, 0x14, 0x0001}, {0xaa, 0x14, 0x0001},
{0xaa, 0x15, 0x00e8}, {0xaa, 0x15, 0x00e8},
{0xaa, 0x16, 0x0002}, {0xaa, 0x16, 0x0002},
{0xaa, 0x17, 0x0086}, {0xaa, 0x17, 0x0086}, /* 00,17,88,aa */
{0xaa, 0x31, 0x0038}, {0xaa, 0x31, 0x0038},
{0xaa, 0x32, 0x0038}, {0xaa, 0x32, 0x0038},
{0xaa, 0x33, 0x0038}, {0xaa, 0x33, 0x0038},
...@@ -2309,7 +2309,7 @@ static const struct usb_action hv7131bxx_Initial[] = { ...@@ -2309,7 +2309,7 @@ static const struct usb_action hv7131bxx_Initial[] = {
{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
{0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */ {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */
{0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0002},
{0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
...@@ -2374,7 +2374,7 @@ static const struct usb_action hv7131bxx_Initial[] = { ...@@ -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, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
...@@ -6388,6 +6388,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) ...@@ -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? */ /*fixme: is it really write to 011d and 018d for all other sensors? */
brightness = sd->brightness; brightness = sd->brightness;
reg_w(gspca_dev->dev, brightness, 0x011d); reg_w(gspca_dev->dev, brightness, 0x011d);
if (sd->sensor == SENSOR_HV7131B)
return;
if (brightness < 0x70) if (brightness < 0x70)
brightness += 0x10; brightness += 0x10;
else else
...@@ -6529,6 +6531,7 @@ static void setquality(struct gspca_dev *gspca_dev) ...@@ -6529,6 +6531,7 @@ static void setquality(struct gspca_dev *gspca_dev)
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_GC0305: case SENSOR_GC0305:
case SENSOR_HV7131B:
case SENSOR_OV7620: case SENSOR_OV7620:
case SENSOR_PO2030: case SENSOR_PO2030:
return; return;
...@@ -7209,7 +7212,6 @@ static int sd_start(struct gspca_dev *gspca_dev) ...@@ -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; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
zc3_init = init_tb[(int) sd->sensor][mode]; zc3_init = init_tb[(int) sd->sensor][mode];
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_HV7131B:
case SENSOR_HV7131C: case SENSOR_HV7131C:
zcxx_probeSensor(gspca_dev); zcxx_probeSensor(gspca_dev);
break; break;
......
config VIDEO_IVTV config VIDEO_IVTV
tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" 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 depends on INPUT # due to VIDEO_IR
select I2C_ALGOBIT select I2C_ALGOBIT
select VIDEO_IR select VIDEO_IR
...@@ -12,7 +12,6 @@ config VIDEO_IVTV ...@@ -12,7 +12,6 @@ config VIDEO_IVTV
select VIDEO_SAA711X select VIDEO_SAA711X
select VIDEO_SAA717X select VIDEO_SAA717X
select VIDEO_SAA7127 select VIDEO_SAA7127
select VIDEO_TVAUDIO
select VIDEO_CS53L32A select VIDEO_CS53L32A
select VIDEO_M52790 select VIDEO_M52790
select VIDEO_WM8775 select VIDEO_WM8775
...@@ -32,7 +31,7 @@ config VIDEO_IVTV ...@@ -32,7 +31,7 @@ config VIDEO_IVTV
config VIDEO_FB_IVTV config VIDEO_FB_IVTV
tristate "Conexant cx23415 framebuffer support" tristate "Conexant cx23415 framebuffer support"
depends on VIDEO_IVTV && FB && EXPERIMENTAL depends on VIDEO_IVTV && FB
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT
......
...@@ -875,43 +875,43 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) ...@@ -875,43 +875,43 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
#ifdef MODULE #ifdef MODULE
/* load modules */ /* load modules */
#ifndef CONFIG_MEDIA_TUNER #ifdef CONFIG_MEDIA_TUNER_MODULE
hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
#endif #endif
#ifndef CONFIG_VIDEO_CX25840 #ifdef CONFIG_VIDEO_CX25840_MODULE
hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840); hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840);
#endif #endif
#ifndef CONFIG_VIDEO_SAA711X #ifdef CONFIG_VIDEO_SAA711X_MODULE
hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X); hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X);
#endif #endif
#ifndef CONFIG_VIDEO_SAA7127 #ifdef CONFIG_VIDEO_SAA7127_MODULE
hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127);
#endif #endif
#ifndef CONFIG_VIDEO_SAA717X #ifdef CONFIG_VIDEO_SAA717X_MODULE
hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X);
#endif #endif
#ifndef CONFIG_VIDEO_UPD64031A #ifdef CONFIG_VIDEO_UPD64031A_MODULE
hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A);
#endif #endif
#ifndef CONFIG_VIDEO_UPD64083 #ifdef CONFIG_VIDEO_UPD64083_MODULE
hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X); hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X);
#endif #endif
#ifndef CONFIG_VIDEO_MSP3400 #ifdef CONFIG_VIDEO_MSP3400_MODULE
hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX); hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX);
#endif #endif
#ifndef CONFIG_VIDEO_VP27SMPX #ifdef CONFIG_VIDEO_VP27SMPX_MODULE
hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX); hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX);
#endif #endif
#ifndef CONFIG_VIDEO_WM8775 #ifdef CONFIG_VIDEO_WM8775_MODULE
hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775); hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775);
#endif #endif
#ifndef CONFIG_VIDEO_WM8739 #ifdef CONFIG_VIDEO_WM8739_MODULE
hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739); hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739);
#endif #endif
#ifndef CONFIG_VIDEO_CS53L32A #ifdef CONFIG_VIDEO_CS53L32A_MODULE
hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A); hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A);
#endif #endif
#ifndef CONFIG_VIDEO_M52790 #ifdef CONFIG_VIDEO_M52790_MODULE
hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790); hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
#endif #endif
#endif #endif
......
...@@ -47,7 +47,7 @@ module_param(debug, int, 0); ...@@ -47,7 +47,7 @@ module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)"); MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ #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 #define SAA7110_NR_REG 0x35
...@@ -327,7 +327,7 @@ saa7110_command (struct i2c_client *client, ...@@ -327,7 +327,7 @@ saa7110_command (struct i2c_client *client,
case DECODER_SET_INPUT: case DECODER_SET_INPUT:
v = *(int *) arg; 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); v4l_dbg(1, debug, client, "input=%d not available\n", v);
return -EINVAL; return -EINVAL;
} }
......
...@@ -941,7 +941,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, ...@@ -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)); dev->name,(unsigned long long)pci_resource_start(pci_dev,0));
goto fail1; 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; dev->bmmio = (__u8 __iomem *)dev->lmmio;
if (NULL == dev->lmmio) { if (NULL == dev->lmmio) {
err = -EIO; err = -EIO;
......
...@@ -3695,7 +3695,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * ...@@ -3695,7 +3695,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *
unsigned char video_ep = 0; unsigned char video_ep = 0;
if (debug >= 1) 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 */ /* We don't handle multi-config cameras */
if (dev->descriptor.bNumConfigurations != 1) if (dev->descriptor.bNumConfigurations != 1)
...@@ -3746,7 +3746,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * ...@@ -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 */ brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */
break; break;
} }
dev_info(&uvd->dev->dev, dev_info(&dev->dev,
"%s USB camera found (model %d, rev. 0x%04x)\n", "%s USB camera found (model %d, rev. 0x%04x)\n",
brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); brand, model, le16_to_cpu(dev->descriptor.bcdDevice));
} while (0); } while (0);
...@@ -3754,7 +3754,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * ...@@ -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 */ /* Validate found interface: must have one ISO endpoint */
nas = intf->num_altsetting; nas = intf->num_altsetting;
if (debug > 0) 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); nas);
if (nas < 2) { if (nas < 2) {
err("Too few alternate settings for this camera!"); 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 * ...@@ -3799,7 +3799,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *
actInterface = i; actInterface = i;
maxPS = le16_to_cpu(endpoint->wMaxPacketSize); maxPS = le16_to_cpu(endpoint->wMaxPacketSize);
if (debug > 0) if (debug > 0)
dev_info(&uvd->dev->dev, dev_info(&dev->dev,
"Active setting=%d. " "Active setting=%d. "
"maxPS=%d.\n", i, maxPS); "maxPS=%d.\n", i, maxPS);
} else } else
...@@ -3840,7 +3840,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * ...@@ -3840,7 +3840,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *
RESTRICT_TO_RANGE(framerate, 0, 5); RESTRICT_TO_RANGE(framerate, 0, 5);
break; break;
default: default:
dev_info(&uvd->dev->dev, "IBM camera: using 320x240\n"); dev_info(&dev->dev, "IBM camera: using 320x240\n");
size = SIZE_320x240; size = SIZE_320x240;
/* No break here */ /* No break here */
case SIZE_320x240: case SIZE_320x240:
...@@ -3869,7 +3869,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * ...@@ -3869,7 +3869,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id *
canvasY = 120; canvasY = 120;
break; break;
default: default:
dev_info(&uvd->dev->dev, "IBM NetCamera: using 176x144\n"); dev_info(&dev->dev, "IBM NetCamera: using 176x144\n");
size = SIZE_176x144; size = SIZE_176x144;
/* No break here */ /* No break here */
case SIZE_176x144: case SIZE_176x144:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment