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: (45 commits)
  V4L/DVB (10411): s5h1409: Perform s5h1409 soft reset after tuning
  V4L/DVB (10403): saa7134-alsa: saa7130 doesn't support digital audio
  V4L/DVB (10229): ivtv: fix memory leak
  V4L/DVB (10385): gspca - main: Fix memory leak when USB disconnection while streaming.
  V4L/DVB (10325): em28xx: Fix for fail to submit URB with IRQs and Pre-emption Disabled
  V4L/DVB (10317): radio-mr800: fix radio->muted and radio->stereo
  V4L/DVB (10314): cx25840: ignore TUNER_SET_CONFIG in the command callback.
  V4L/DVB (10288): af9015: bug fix: stick does not work always when plugged
  V4L/DVB (10287): af9015: fix second FE
  V4L/DVB (10270): saa7146: fix unbalanced mutex_lock/unlock
  V4L/DVB (10265): budget.c driver: Kernel oops: "BUG: unable to handle kernel paging request at ffffffff
  V4L/DVB (10261): em28xx: fix kernel panic on audio shutdown
  V4L/DVB (10257): em28xx: Fix for KWorld 330U Board
  V4L/DVB (10256): em28xx: Fix for KWorld 330U AC97
  V4L/DVB (10254): em28xx: Fix audio URB transfer buffer race condition
  V4L/DVB (10250): cx25840: fix regression: fw not loaded on first use
  V4L/DVB (10248): v4l-dvb: fix a bunch of compile warnings.
  V4L/DVB (10243): em28xx: fix compile warning
  V4L/DVB (10240): Fix obvious swapped names in v4l2_subdev logic
  V4L/DVB (10233): [PATCH] Terratec Cinergy DT XS Diversity new USB ID (0ccd:0081)
  ...
This commit is contained in:
Linus Torvalds 2009-02-02 19:26:06 -08:00
commit 9e6235e997
54 changed files with 877 additions and 754 deletions

View File

@ -4,12 +4,21 @@
*
* Compile with:
* gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
* Use as:
* v4lgrab >image.ppm
* Use as:
* v4lgrab >image.ppm
*
* Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
* Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
* with minor modifications (Dave Forrest, drf5n@virginia.edu).
* Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
* with minor modifications (Dave Forrest, drf5n@virginia.edu).
*
*
* For some cameras you may need to pre-load libv4l to perform
* the necessary decompression, e.g.:
*
* export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so
* ./v4lgrab >image.ppm
*
* see http://hansdegoede.livejournal.com/3636.html for details.
*
*/
@ -24,7 +33,7 @@
#include <linux/types.h>
#include <linux/videodev.h>
#define FILE "/dev/video0"
#define VIDEO_DEV "/dev/video0"
/* Stole this from tvset.c */
@ -90,7 +99,7 @@ int get_brightness_adj(unsigned char *image, long size, int *brightness) {
int main(int argc, char ** argv)
{
int fd = open(FILE, O_RDONLY), f;
int fd = open(VIDEO_DEV, O_RDONLY), f;
struct video_capability cap;
struct video_window win;
struct video_picture vpic;
@ -100,13 +109,13 @@ int main(int argc, char ** argv)
unsigned int i, src_depth;
if (fd < 0) {
perror(FILE);
perror(VIDEO_DEV);
exit(1);
}
if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
perror("VIDIOGCAP");
fprintf(stderr, "(" FILE " not a video4linux device?)\n");
fprintf(stderr, "(" VIDEO_DEV " not a video4linux device?)\n");
close(fd);
exit(1);
}

View File

@ -576,6 +576,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
vv->vflip = c->value;
break;
default: {
mutex_unlock(&dev->lock);
return -EINVAL;
}
}

View File

@ -657,7 +657,7 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
{
struct mxl5007t_state *state = fe->tuner_priv;
int rf_locked, ref_locked;
s32 rf_input_level;
s32 rf_input_level = 0;
int ret;
if (fe->ops.i2c_gate_ctrl)

View File

@ -93,6 +93,9 @@ struct dvb_ca_slot {
/* current state of the CAM */
int slot_state;
/* mutex used for serializing access to one CI slot */
struct mutex slot_lock;
/* Number of CAMCHANGES that have occurred since last processing */
atomic_t camchange_count;
@ -711,14 +714,20 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
dprintk("%s\n", __func__);
// sanity check
/* sanity check */
if (bytes_write > ca->slot_info[slot].link_buf_size)
return -EINVAL;
/* check if interface is actually waiting for us to read from it, or if a read is in progress */
/* it is possible we are dealing with a single buffer implementation,
thus if there is data available for read or if there is even a read
already in progress, we do nothing but awake the kernel thread to
process the data if necessary. */
if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
goto exitnowrite;
if (status & (STATUSREG_DA | STATUSREG_RE)) {
if (status & STATUSREG_DA)
dvb_ca_en50221_thread_wakeup(ca);
status = -EAGAIN;
goto exitnowrite;
}
@ -987,6 +996,8 @@ static int dvb_ca_en50221_thread(void *data)
/* go through all the slots processing them */
for (slot = 0; slot < ca->slot_count; slot++) {
mutex_lock(&ca->slot_info[slot].slot_lock);
// check the cam status + deal with CAMCHANGEs
while (dvb_ca_en50221_check_camstatus(ca, slot)) {
/* clear down an old CI slot if necessary */
@ -1122,7 +1133,7 @@ static int dvb_ca_en50221_thread(void *data)
case DVB_CA_SLOTSTATE_RUNNING:
if (!ca->open)
continue;
break;
// poll slots for data
pktcount = 0;
@ -1146,6 +1157,8 @@ static int dvb_ca_en50221_thread(void *data)
}
break;
}
mutex_unlock(&ca->slot_info[slot].slot_lock);
}
}
@ -1181,6 +1194,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case CA_RESET:
for (slot = 0; slot < ca->slot_count; slot++) {
mutex_lock(&ca->slot_info[slot].slot_lock);
if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
dvb_ca_en50221_slot_shutdown(ca, slot);
if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
@ -1188,6 +1202,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
slot,
DVB_CA_EN50221_CAMCHANGE_INSERTED);
}
mutex_unlock(&ca->slot_info[slot].slot_lock);
}
ca->next_read_slot = 0;
dvb_ca_en50221_thread_wakeup(ca);
@ -1308,7 +1323,9 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
goto exit;
}
mutex_lock(&ca->slot_info[slot].slot_lock);
status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
mutex_unlock(&ca->slot_info[slot].slot_lock);
if (status == (fraglen + 2)) {
written = 1;
break;
@ -1664,6 +1681,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
atomic_set(&ca->slot_info[i].camchange_count, 0);
ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
mutex_init(&ca->slot_info[i].slot_lock);
}
if (signal_pending(current)) {

View File

@ -45,8 +45,10 @@ struct dvb_ca_en50221 {
/* the module owning this structure */
struct module* owner;
/* NOTE: the read_*, write_* and poll_slot_status functions must use locks as
* they may be called from several threads at once */
/* NOTE: the read_*, write_* and poll_slot_status functions will be
* called for different slots concurrently and need to use locks where
* and if appropriate. There will be no concurrent access to one slot.
*/
/* functions for accessing attribute memory on the CAM */
int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);

View File

@ -220,7 +220,7 @@ static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
u16 * abort_count)
{
u32 loc_cw_count = 0, loc_err_count;
u16 loc_abort_count;
u16 loc_abort_count = 0;
int ret;
ret =

View File

@ -694,7 +694,12 @@ static int af9015_read_config(struct usb_device *udev)
/* IR remote controller */
req.addr = AF9015_EEPROM_IR_MODE;
ret = af9015_rw_udev(udev, &req);
/* first message will timeout often due to possible hw bug */
for (i = 0; i < 4; i++) {
ret = af9015_rw_udev(udev, &req);
if (!ret)
break;
}
if (ret)
goto error;
deb_info("%s: IR mode:%d\n", __func__, val);
@ -835,18 +840,19 @@ static int af9015_read_config(struct usb_device *udev)
if (!dvb_usb_af9015_dual_mode)
af9015_config.dual_mode = 0;
/* set buffer size according to USB port speed */
/* Set adapter0 buffer size according to USB port speed, adapter1 buffer
size can be static because it is enabled only USB2.0 */
for (i = 0; i < af9015_properties_count; i++) {
/* USB1.1 set smaller buffersize and disable 2nd adapter */
if (udev->speed == USB_SPEED_FULL) {
af9015_properties[i].adapter->stream.u.bulk.buffersize =
TS_USB11_MAX_PACKET_SIZE;
af9015_properties[i].adapter[0].stream.u.bulk.buffersize
= TS_USB11_MAX_PACKET_SIZE;
/* disable 2nd adapter because we don't have
PID-filters */
af9015_config.dual_mode = 0;
} else {
af9015_properties[i].adapter->stream.u.bulk.buffersize =
TS_USB20_MAX_PACKET_SIZE;
af9015_properties[i].adapter[0].stream.u.bulk.buffersize
= TS_USB20_MAX_PACKET_SIZE;
}
}
@ -1254,6 +1260,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.type = USB_BULK,
.count = 6,
.endpoint = 0x85,
.u = {
.bulk = {
.buffersize =
TS_USB20_MAX_PACKET_SIZE,
}
}
},
}
},
@ -1353,6 +1365,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.type = USB_BULK,
.count = 6,
.endpoint = 0x85,
.u = {
.bulk = {
.buffersize =
TS_USB20_MAX_PACKET_SIZE,
}
}
},
}
},

View File

@ -1393,6 +1393,9 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
{ USB_DEVICE(USB_VID_TERRATEC,
USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@ -1537,7 +1540,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "DiBcom STK7700D reference design",
{ &dib0700_usb_id_table[14], NULL },
{ NULL },
}
},
},
.rc_interval = DEFAULT_RC_INTERVAL,
@ -1557,7 +1561,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
.num_device_descs = 2,
.num_device_descs = 3,
.devices = {
{ "ASUS My Cinema U3000 Mini DVBT Tuner",
{ &dib0700_usb_id_table[23], NULL },
@ -1566,6 +1570,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Yuan EC372S",
{ &dib0700_usb_id_table[31], NULL },
{ NULL },
},
{ "Terratec Cinergy T Express",
{ &dib0700_usb_id_table[42], NULL },
{ NULL },
}
},
@ -1653,7 +1661,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
}
},
.num_device_descs = 4,
.num_device_descs = 5,
.devices = {
{ "DiBcom STK7070PD reference design",
{ &dib0700_usb_id_table[17], NULL },
@ -1670,6 +1678,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Hauppauge Nova-TD-500 (84xxx)",
{ &dib0700_usb_id_table[36], NULL },
{ NULL },
},
{ "Terratec Cinergy DT USB XS Diversity",
{ &dib0700_usb_id_table[43], NULL },
{ NULL },
}
}
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,

View File

@ -162,8 +162,10 @@
#define USB_PID_AVERMEDIA_A309 0xa309
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060
#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
#define USB_PID_PINNACLE_PCTV2000E 0x022c

View File

@ -646,7 +646,7 @@ static int drx_tune(struct drx397xD_state *s,
u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
int rc, df_tuner;
int rc, df_tuner = 0;
int a, b, c, d;
pr_debug("%s %d\n", __func__, s->config.d60);

View File

@ -545,9 +545,6 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
s5h1409_enable_modulation(fe, p->u.vsb.modulation);
/* Allow the demod to settle */
msleep(100);
if (fe->ops.tuner_ops.set_params) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@ -562,6 +559,10 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
s5h1409_set_qam_interleave_mode(fe);
}
/* Issue a reset to the demod so it knows to resync against the
newly tuned frequency */
s5h1409_softreset(fe);
return 0;
}

View File

@ -31,6 +31,8 @@ inline u32 stb0899_do_div(u64 n, u32 d)
return n;
}
#if 0
/* These functions are currently unused */
/*
* stb0899_calc_srate
* Compute symbol rate
@ -63,6 +65,7 @@ static u32 stb0899_get_srate(struct stb0899_state *state)
return stb0899_calc_srate(internal->master_clk, sfr);
}
#endif
/*
* stb0899_set_srate

View File

@ -470,6 +470,7 @@ static void frontend_init(struct budget *budget)
budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
budget->dvb_frontend->tuner_priv = NULL;
break;
}
break;

View File

@ -1384,7 +1384,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
static int ttusb_dec_init_stb(struct ttusb_dec *dec)
{
int result;
unsigned int mode, model, version;
unsigned int mode = 0, model = 0, version = 0;
dprintk("%s\n", __func__);

View File

@ -194,10 +194,10 @@ static int amradio_start(struct amradio_device *radio)
return retval;
}
mutex_unlock(&radio->lock);
radio->muted = 0;
mutex_unlock(&radio->lock);
return retval;
}
@ -230,10 +230,10 @@ static int amradio_stop(struct amradio_device *radio)
return retval;
}
mutex_unlock(&radio->lock);
radio->muted = 1;
mutex_unlock(&radio->lock);
return retval;
}
@ -284,10 +284,10 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
return retval;
}
mutex_unlock(&radio->lock);
radio->stereo = 0;
mutex_unlock(&radio->lock);
return retval;
}

View File

@ -18,7 +18,6 @@
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>

View File

@ -1586,7 +1586,8 @@ static int mpeg_open(struct file *file)
lock_kernel();
list_for_each(list, &cx23885_devlist) {
h = list_entry(list, struct cx23885_dev, devlist);
if (h->v4l_device->minor == minor) {
if (h->v4l_device &&
h->v4l_device->minor == minor) {
dev = h;
break;
}

View File

@ -730,12 +730,13 @@ static int video_open(struct file *file)
lock_kernel();
list_for_each(list, &cx23885_devlist) {
h = list_entry(list, struct cx23885_dev, devlist);
if (h->video_dev->minor == minor) {
if (h->video_dev &&
h->video_dev->minor == minor) {
dev = h;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
}
if (h->vbi_dev &&
h->vbi_dev->minor == minor) {
h->vbi_dev->minor == minor) {
dev = h;
type = V4L2_BUF_TYPE_VBI_CAPTURE;
}

View File

@ -1382,6 +1382,14 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
{
/* ignore this command */
if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
return 0;
/* Old-style drivers rely on initialization on first use, so
call the init whenever a command is issued to this driver.
New-style drivers using v4l2_subdev should call init explicitly. */
cx25840_init(i2c_get_clientdata(client), 0);
return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
}

View File

@ -614,35 +614,42 @@ static struct stv0288_config tevii_tuner_earda_config = {
.set_ts_params = cx24116_set_ts_param,
};
static int cx8802_alloc_frontends(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
struct videobuf_dvb_frontend *fe = NULL;
int i;
mutex_init(&dev->frontends.lock);
INIT_LIST_HEAD(&dev->frontends.felist);
if (!core->board.num_frontends)
return -ENODEV;
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) {
printk(KERN_ERR "%s() failed to alloc\n", __func__);
videobuf_dvb_dealloc_frontends(&dev->frontends);
return -ENOMEM;
}
}
return 0;
}
static int dvb_register(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
int mfe_shared = 0; /* bus not shared by default */
int i;
if (0 != core->i2c_rc) {
printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
goto frontend_detach;
}
if (!core->board.num_frontends)
return -EINVAL;
mutex_init(&dev->frontends.lock);
INIT_LIST_HEAD(&dev->frontends.felist);
printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
core->board.num_frontends);
for (i = 1; i <= core->board.num_frontends; i++) {
fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i);
if (!fe0) {
printk(KERN_ERR "%s() failed to alloc\n", __func__);
videobuf_dvb_dealloc_frontends(&dev->frontends);
goto frontend_detach;
}
}
/* Get the first frontend */
fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
if (!fe0)
@ -1243,6 +1250,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
struct cx88_core *core = drv->core;
struct cx8802_dev *dev = drv->core->dvbdev;
int err;
struct videobuf_dvb_frontend *fe;
int i;
dprintk( 1, "%s\n", __func__);
dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@ -1258,39 +1267,34 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
/* If vp3054 isn't enabled, a stub will just return 0 */
err = vp3054_i2c_probe(dev);
if (0 != err)
goto fail_probe;
goto fail_core;
/* dvb stuff */
printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
dev->ts_gen_cntrl = 0x0c;
err = -ENODEV;
if (core->board.num_frontends) {
struct videobuf_dvb_frontend *fe;
int i;
err = cx8802_alloc_frontends(dev);
if (err)
goto fail_core;
for (i = 1; i <= core->board.num_frontends; i++) {
fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
if (fe == NULL) {
printk(KERN_ERR "%s() failed to get frontend(%d)\n",
err = -ENODEV;
for (i = 1; i <= core->board.num_frontends; i++) {
fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
if (fe == NULL) {
printk(KERN_ERR "%s() failed to get frontend(%d)\n",
__func__, i);
goto fail_probe;
}
videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
goto fail_probe;
}
videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_TOP,
sizeof(struct cx88_buffer),
dev);
/* init struct videobuf_dvb */
fe->dvb.name = dev->core->name;
}
} else {
/* no frontends allocated */
printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n",
core->name);
goto fail_core;
/* init struct videobuf_dvb */
fe->dvb.name = dev->core->name;
}
err = dvb_register(dev);
if (err)
/* frontends/adapter de-allocated in dvb_register */

View File

@ -336,8 +336,8 @@ struct cx88_core {
/* config info -- dvb */
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
void (*gate_ctrl)(struct cx88_core *core, int open);
#endif
void (*gate_ctrl)(struct cx88_core *core, int open);
/* state info */
struct task_struct *kthread;

View File

@ -62,9 +62,15 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
dprintk("Stopping isoc\n");
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
usb_unlink_urb(dev->adev.urb[i]);
if (!irqs_disabled())
usb_kill_urb(dev->adev.urb[i]);
else
usb_unlink_urb(dev->adev.urb[i]);
usb_free_urb(dev->adev.urb[i]);
dev->adev.urb[i] = NULL;
kfree(dev->adev.transfer_buffer[i]);
dev->adev.transfer_buffer[i] = NULL;
}
return 0;
@ -389,11 +395,15 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
*substream)
{
struct em28xx *dev;
unsigned long flags;
struct em28xx *dev;
snd_pcm_uframes_t hwptr_done;
dev = snd_pcm_substream_chip(substream);
spin_lock_irqsave(&dev->adev.slock, flags);
hwptr_done = dev->adev.hwptr_done_capture;
spin_unlock_irqrestore(&dev->adev.slock, flags);
return hwptr_done;
}

View File

@ -102,6 +102,18 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
/* Board - EM2870 Kworld 355u
Analog - No input analog */
static struct em28xx_reg_seq kworld_330u_analog[] = {
{EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x00, 0xff, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq kworld_330u_digital[] = {
{EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x08, 0xff, 10},
{ -1, -1, -1, -1},
};
/* Callback for the most boards */
static struct em28xx_reg_seq default_tuner_gpio[] = {
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
@ -1177,29 +1189,33 @@ struct em28xx_board em28xx_boards[] = {
.gpio = hauppauge_wintv_hvr_900_analog,
} },
},
[EM2883_BOARD_KWORLD_HYBRID_A316] = {
[EM2883_BOARD_KWORLD_HYBRID_330U] = {
.name = "Kworld PlusTV HD Hybrid 330",
.tuner_type = TUNER_XC2028,
.tuner_gpio = default_tuner_gpio,
.decoder = EM28XX_TVP5150,
.mts_firmware = 1,
.has_dvb = 1,
.dvb_gpio = default_digital,
.dvb_gpio = kworld_330u_digital,
.xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
.amux = EM28XX_AMUX_VIDEO,
.gpio = default_analog,
.gpio = kworld_330u_analog,
.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
}, {
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = TVP5150_COMPOSITE1,
.amux = EM28XX_AMUX_LINE_IN,
.gpio = hauppauge_wintv_hvr_900_analog,
.gpio = kworld_330u_analog,
.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
}, {
.type = EM28XX_VMUX_SVIDEO,
.vmux = TVP5150_SVIDEO,
.amux = EM28XX_AMUX_LINE_IN,
.gpio = hauppauge_wintv_hvr_900_analog,
.gpio = kworld_330u_analog,
} },
},
[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
@ -1249,7 +1265,7 @@ struct usb_device_id em28xx_id_table [] = {
{ USB_DEVICE(0xeb1a, 0xe310),
.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
{ USB_DEVICE(0xeb1a, 0xa316),
.driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 },
.driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
{ USB_DEVICE(0xeb1a, 0xe320),
.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
{ USB_DEVICE(0xeb1a, 0xe323),
@ -1526,6 +1542,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
/* FIXME: Better to specify the needed IF */
ctl->demod = XC3028_FE_DEFAULT;
break;
case EM2883_BOARD_KWORLD_HYBRID_330U:
ctl->demod = XC3028_FE_CHINA;
ctl->fname = XC2028_DEFAULT_FIRMWARE;
break;
default:
ctl->demod = XC3028_FE_OREN538;
}

View File

@ -438,6 +438,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
int vol;
em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200);
em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031);
em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80);
/* LSB: left channel - both channels with the same level */
vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8);
@ -454,6 +458,15 @@ int em28xx_audio_analog_set(struct em28xx *dev)
em28xx_warn("couldn't setup AC97 register %d\n",
outputs[i].reg);
}
if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
int sel = ac97_return_record_select(dev->ctl_aoutput);
/* Use the same input for both left and right channels */
sel |= (sel << 8);
em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
}
}
return ret;
@ -847,8 +860,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
urb = dev->isoc_ctl.urb[i];
if (urb) {
usb_kill_urb(urb);
usb_unlink_urb(urb);
if (!irqs_disabled())
usb_kill_urb(urb);
else
usb_unlink_urb(urb);
if (dev->isoc_ctl.transfer_buffer[i]) {
usb_buffer_free(dev->udev,
urb->transfer_buffer_length,

View File

@ -28,6 +28,7 @@
#include "lgdt330x.h"
#include "zl10353.h"
#include "s5h1409.h"
#ifdef EM28XX_DRX397XD_SUPPORT
#include "drx397xD.h"
#endif
@ -232,6 +233,15 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = {
.if2 = 45600,
};
static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
.demod_address = 0x32 >> 1,
.output_mode = S5H1409_PARALLEL_OUTPUT,
.gpio = S5H1409_GPIO_OFF,
.inversion = S5H1409_INVERSION_OFF,
.status_mode = S5H1409_DEMODLOCKING,
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
};
#ifdef EM28XX_DRX397XD_SUPPORT
/* [TODO] djh - not sure yet what the device config needs to contain */
static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
@ -412,7 +422,6 @@ static int dvb_init(struct em28xx *dev)
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
case EM2883_BOARD_KWORLD_HYBRID_A316:
case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
dvb->frontend = dvb_attach(lgdt330x_attach,
&em2880_lgdt3303_dev,
@ -433,6 +442,15 @@ static int dvb_init(struct em28xx *dev)
goto out_free;
}
break;
case EM2883_BOARD_KWORLD_HYBRID_330U:
dvb->frontend = dvb_attach(s5h1409_attach,
&em28xx_s5h1409_with_xc3028,
&dev->i2c_adap);
if (attach_xc3028(0x61, dev) < 0) {
result = -EINVAL;
goto out_free;
}
break;
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
#ifdef EM28XX_DRX397XD_SUPPORT
/* We don't have the config structure properly populated, so

View File

@ -886,10 +886,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
if (0 == INPUT(i)->type)
return -EINVAL;
dev->ctl_input = i;
mutex_lock(&dev->lock);
video_mux(dev, i);
video_mux(dev, dev->ctl_input);
mutex_unlock(&dev->lock);
return 0;
}
@ -939,6 +939,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
if (a->index >= MAX_EM28XX_INPUT)
return -EINVAL;
if (0 == INPUT(a->index)->type)
return -EINVAL;
mutex_lock(&dev->lock);
dev->ctl_ainput = INPUT(a->index)->amux;
@ -1950,6 +1956,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
int em28xx_register_analog_devices(struct em28xx *dev)
{
u8 val;
int ret;
printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n",
@ -1957,23 +1964,6 @@ int em28xx_register_analog_devices(struct em28xx *dev)
(EM28XX_VERSION_CODE >> 16) & 0xff,
(EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
/* Analog specific initialization */
dev->format = &format[0];
video_mux(dev, 0);
/* enable vbi capturing */
/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
/* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
dev->mute = 1; /* maybe not the right place... */
dev->volume = 0x1f;
em28xx_set_outfmt(dev);
em28xx_colorlevels_set_default(dev);
em28xx_compression_disable(dev);
/* set default norm */
dev->norm = em28xx_video_template.current_norm;
dev->width = norm_maxw(dev);
@ -1981,9 +1971,26 @@ int em28xx_register_analog_devices(struct em28xx *dev)
dev->interlaced = EM28XX_INTERLACED_DEFAULT;
dev->hscale = 0;
dev->vscale = 0;
dev->ctl_input = 0;
/* FIXME: This is a very bad hack! Not all devices have TV on input 2 */
dev->ctl_input = 2;
/* Analog specific initialization */
dev->format = &format[0];
video_mux(dev, dev->ctl_input);
/* Audio defaults */
dev->mute = 1;
dev->volume = 0x1f;
/* enable vbi capturing */
/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val));
em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
em28xx_set_outfmt(dev);
em28xx_colorlevels_set_default(dev);
em28xx_compression_disable(dev);
/* allocate and fill video video_device struct */
dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");

View File

@ -94,7 +94,7 @@
#define EM2882_BOARD_KWORLD_VS_DVBT 54
#define EM2882_BOARD_TERRATEC_HYBRID_XS 55
#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56
#define EM2883_BOARD_KWORLD_HYBRID_A316 57
#define EM2883_BOARD_KWORLD_HYBRID_330U 57
#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
#define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61
@ -300,13 +300,32 @@ enum em28xx_amux {
};
enum em28xx_aout {
/* AC97 outputs */
EM28XX_AOUT_MASTER = 1 << 0,
EM28XX_AOUT_LINE = 1 << 1,
EM28XX_AOUT_MONO = 1 << 2,
EM28XX_AOUT_LFE = 1 << 3,
EM28XX_AOUT_SURR = 1 << 4,
/* PCM IN Mixer - used by AC97_RECORD_SELECT register */
EM28XX_AOUT_PCM_IN = 1 << 7,
/* Bits 10-8 are used to indicate the PCM IN record select */
EM28XX_AOUT_PCM_MIC_PCM = 0 << 8,
EM28XX_AOUT_PCM_CD = 1 << 8,
EM28XX_AOUT_PCM_VIDEO = 2 << 8,
EM28XX_AOUT_PCM_AUX = 3 << 8,
EM28XX_AOUT_PCM_LINE = 4 << 8,
EM28XX_AOUT_PCM_STEREO = 5 << 8,
EM28XX_AOUT_PCM_MONO = 6 << 8,
EM28XX_AOUT_PCM_PHONE = 7 << 8,
};
static inline int ac97_return_record_select(int a_out)
{
return (a_out & 0x700) >> 8;
}
struct em28xx_reg_seq {
int reg;
unsigned char val, mask;

View File

@ -423,7 +423,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
break;
gspca_dev->urb[i] = NULL;
usb_kill_urb(urb);
if (!gspca_dev->present)
usb_kill_urb(urb);
if (urb->transfer_buffer != NULL)
usb_buffer_free(gspca_dev->dev,
urb->transfer_buffer_length,
@ -1950,7 +1951,6 @@ void gspca_disconnect(struct usb_interface *intf)
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
gspca_dev->present = 0;
gspca_dev->streaming = 0;
usb_set_intfdata(intf, NULL);

View File

@ -949,8 +949,10 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
itv->instance = atomic_inc_return(&ivtv_instance) - 1;
retval = v4l2_device_register(&dev->dev, &itv->device);
if (retval)
if (retval) {
kfree(itv);
return retval;
}
/* "ivtv + PCI ID" is a bit of a mouthful, so use
"ivtv + instance" instead. */
snprintf(itv->device.name, sizeof(itv->device.name),

View File

@ -62,7 +62,6 @@
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/version.h>
#include <asm/io.h>
#include "pwc.h"

View File

@ -149,7 +149,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = {
{ SAA7127_REG_COPYGEN_0, 0x77 },
{ SAA7127_REG_COPYGEN_1, 0x41 },
{ SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */
{ SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e },
{ SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf },
{ SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 },
{ SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 },
{ SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */
@ -488,12 +488,18 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
break;
case SAA7127_OUTPUT_TYPE_COMPOSITE:
state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
if (state->ident == V4L2_IDENT_SAA7129)
state->reg_2d = 0x20; /* CVBS only */
else
state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
case SAA7127_OUTPUT_TYPE_SVIDEO:
state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */
if (state->ident == V4L2_IDENT_SAA7129)
state->reg_2d = 0x18; /* Y + C */
else
state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
@ -508,7 +514,10 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
break;
case SAA7127_OUTPUT_TYPE_BOTH:
state->reg_2d = 0xbf;
if (state->ident == V4L2_IDENT_SAA7129)
state->reg_2d = 0x38;
else
state->reg_2d = 0xbf;
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
@ -731,24 +740,6 @@ static int saa7127_probe(struct i2c_client *client,
return -ENODEV;
}
/* Configure Encoder */
v4l2_dbg(1, debug, sd, "Configuring encoder\n");
saa7127_write_inittab(sd, saa7127_init_config_common);
saa7127_set_std(sd, V4L2_STD_NTSC);
saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
saa7127_set_vps(sd, &vbi);
saa7127_set_wss(sd, &vbi);
saa7127_set_cc(sd, &vbi);
saa7127_set_xds(sd, &vbi);
if (test_image == 1)
/* The Encoder has an internal Colorbar generator */
/* This can be used for debugging */
saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
else
saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
saa7127_set_video_enable(sd, 1);
if (id->driver_data) { /* Chip type is already known */
state->ident = id->driver_data;
} else { /* Needs detection */
@ -770,6 +761,23 @@ static int saa7127_probe(struct i2c_client *client,
v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
client->addr << 1, client->adapter->name);
v4l2_dbg(1, debug, sd, "Configuring encoder\n");
saa7127_write_inittab(sd, saa7127_init_config_common);
saa7127_set_std(sd, V4L2_STD_NTSC);
saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
saa7127_set_vps(sd, &vbi);
saa7127_set_wss(sd, &vbi);
saa7127_set_cc(sd, &vbi);
saa7127_set_xds(sd, &vbi);
if (test_image == 1)
/* The Encoder has an internal Colorbar generator */
/* This can be used for debugging */
saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
else
saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
saa7127_set_video_enable(sd, 1);
if (state->ident == V4L2_IDENT_SAA7129)
saa7127_write_inittab(sd, saa7129_init_config_extra);
return 0;

View File

@ -1089,7 +1089,11 @@ static int saa7134_alsa_init(void)
list_for_each(list,&saa7134_devlist) {
dev = list_entry(list, struct saa7134_dev, devlist);
alsa_device_init(dev);
if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n",
dev->name, saa7134_boards[dev->board].name);
else
alsa_device_init(dev);
}
if (dev == NULL)

View File

@ -660,6 +660,10 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, 0);
/* Clear any stale IRQ reports */
saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT));
mutex_init(&dev->lock);
spin_lock_init(&dev->slock);

View File

@ -30,7 +30,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>

View File

@ -242,7 +242,7 @@ static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct tda9875 *t = to_state(sd);
int chvol=0, volume, balance, left, right;
int chvol = 0, volume = 0, balance = 0, left, right;
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:

View File

@ -427,6 +427,9 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
memset(tvee, 0, sizeof(*tvee));
tvee->tuner_type = TUNER_ABSENT;
tvee->tuner2_type = TUNER_ABSENT;
done = len = beenhere = 0;
/* Different eeprom start offsets for em28xx, cx2388x and cx23418 */

View File

@ -1401,7 +1401,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
decoder->pdata = client->dev.platform_data;
if (!decoder->pdata) {
v4l_err(client, "No platform data\n!!");
v4l_err(client, "No platform data!!\n");
return -ENODEV;
}
/*

View File

@ -21,7 +21,6 @@
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>

View File

@ -21,7 +21,6 @@
* 02110-1301, USA.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>

View File

@ -157,7 +157,7 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
struct i2c_msg *pmsg;
struct usb_usbvision *usbvision;
int i, ret;
unsigned char addr;
unsigned char addr = 0;
usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);

View File

@ -1,7 +1,7 @@
/*
* uvc_ctrl.c -- USB Video Class driver - Controls
*
* Copyright (C) 2005-2008
* Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/uaccess.h>
@ -29,7 +28,7 @@
#define UVC_CTRL_DATA_BACKUP 1
/* ------------------------------------------------------------------------
* Control, formats, ...
* Controls
*/
static struct uvc_control_info uvc_ctrls[] = {
@ -635,7 +634,7 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
mask = (1 << bits) - 1;
}
/* Sign-extend the value if needed */
/* Sign-extend the value if needed. */
if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
value |= -(value & (1 << (mapping->size - 1)));

View File

@ -1,7 +1,7 @@
/*
* uvc_driver.c -- USB Video Class driver
*
* Copyright (C) 2005-2008
* Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@ -24,7 +24,6 @@
*/
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
@ -49,7 +48,7 @@ static unsigned int uvc_quirks_param;
unsigned int uvc_trace_param;
/* ------------------------------------------------------------------------
* Control, formats, ...
* Video formats
*/
static struct uvc_format_desc uvc_fmts[] = {
@ -474,7 +473,7 @@ static int uvc_parse_format(struct uvc_device *dev,
/* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
* completely. Observed behaviours range from setting the
* value to 1.1x the actual frame size of hardwiring the
* value to 1.1x the actual frame size to hardwiring the
* 16 low bits to 0. This results in a higher than necessary
* memory usage as well as a wrong image size information. For
* uncompressed formats this can be fixed by computing the
@ -487,7 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev,
/* Some bogus devices report dwMinFrameInterval equal to
* dwMaxFrameInterval and have dwFrameIntervalStep set to
* zero. Setting all null intervals to 1 fixes the problem and
* some other divisions by zero which could happen.
* some other divisions by zero that could happen.
*/
for (i = 0; i < n; ++i) {
interval = get_unaligned_le32(&buffer[26+4*i]);
@ -1200,13 +1199,13 @@ static void uvc_unregister_video(struct uvc_device *dev)
* Scan the UVC descriptors to locate a chain starting at an Output Terminal
* and containing the following units:
*
* - a USB Streaming Output Terminal
* - one Output Terminal (USB Streaming or Display)
* - zero or one Processing Unit
* - zero, one or mode single-input Selector Units
* - zero or one multiple-input Selector Units, provided all inputs are
* connected to input terminals
* - zero, one or mode single-input Extension Units
* - one Camera Input Terminal, or one or more External terminals.
* - one or more Input Terminals (Camera, External or USB Streaming)
*
* A side forward scan is made on each detected entity to check for additional
* extension units.
@ -1531,10 +1530,6 @@ static int uvc_register_video(struct uvc_device *dev)
/* Set the driver data before calling video_register_device, otherwise
* uvc_v4l2_open might race us.
*
* FIXME: usb_set_intfdata hasn't been called so far. Is that a
* problem ? Does any function which could be called here get
* a pointer to the usb_interface ?
*/
dev->video.vdev = vdev;
video_set_drvdata(vdev, &dev->video);
@ -1569,7 +1564,7 @@ void uvc_delete(struct kref *kref)
struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
struct list_head *p, *n;
/* Unregister the video device */
/* Unregister the video device. */
uvc_unregister_video(dev);
usb_put_intf(dev->intf);
usb_put_dev(dev->udev);
@ -1612,7 +1607,7 @@ static int uvc_probe(struct usb_interface *intf,
uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",
udev->devpath);
/* Allocate memory for the device and initialize it */
/* Allocate memory for the device and initialize it. */
if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
return -ENOMEM;
@ -1633,14 +1628,14 @@ static int uvc_probe(struct usb_interface *intf,
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
/* Parse the Video Class control descriptor */
/* Parse the Video Class control descriptor. */
if (uvc_parse_control(dev) < 0) {
uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
"descriptors.\n");
goto error;
}
uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n",
uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
dev->uvc_version >> 8, dev->uvc_version & 0xff,
udev->product ? udev->product : "<unnamed>",
le16_to_cpu(udev->descriptor.idVendor),
@ -1653,18 +1648,18 @@ static int uvc_probe(struct usb_interface *intf,
"linux-uvc-devel mailing list.\n");
}
/* Initialize controls */
/* Initialize controls. */
if (uvc_ctrl_init_device(dev) < 0)
goto error;
/* Register the video devices */
/* Register the video devices. */
if (uvc_register_video(dev) < 0)
goto error;
/* Save our data pointer in the interface data */
/* Save our data pointer in the interface data. */
usb_set_intfdata(intf, dev);
/* Initialize the interrupt URB */
/* Initialize the interrupt URB. */
if ((ret = uvc_status_init(dev)) < 0) {
uvc_printk(KERN_INFO, "Unable to initialize the status "
"endpoint (%d), status interrupt will not be "
@ -1839,24 +1834,24 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0 },
/* Apple Built-In iSight */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x05ac,
.idProduct = 0x8501,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_MINMAX
| UVC_QUIRK_BUILTIN_ISIGHT },
/* Genesys Logic USB 2.0 PC Camera */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x05e3,
.idProduct = 0x0505,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
.idVendor = 0x05e3,
.idProduct = 0x0505,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,

View File

@ -3,6 +3,8 @@
*
* Copyright (C) 2006-2007
* Ivan N. Zlatev <contact@i-nz.net>
* Copyright (C) 2008-2009
* Laurent Pinchart <laurent.pinchart@skynet.be>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/*
* uvc_queue.c -- USB Video Class driver - Buffers management
*
* Copyright (C) 2005-2008
* Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/mm.h>
#include <linux/list.h>
#include <linux/module.h>
@ -37,22 +36,22 @@
* to user space will return -EBUSY.
*
* Video buffers are managed using two queues. However, unlike most USB video
* drivers which use an in queue and an out queue, we use a main queue which
* holds all queued buffers (both 'empty' and 'done' buffers), and an irq
* queue which holds empty buffers. This design (copied from video-buf)
* minimizes locking in interrupt, as only one queue is shared between
* interrupt and user contexts.
* drivers that use an in queue and an out queue, we use a main queue to hold
* all queued buffers (both 'empty' and 'done' buffers), and an irq queue to
* hold empty buffers. This design (copied from video-buf) minimizes locking
* in interrupt, as only one queue is shared between interrupt and user
* contexts.
*
* Use cases
* ---------
*
* Unless stated otherwise, all operations which modify the irq buffers queue
* Unless stated otherwise, all operations that modify the irq buffers queue
* are protected by the irq spinlock.
*
* 1. The user queues the buffers, starts streaming and dequeues a buffer.
*
* The buffers are added to the main and irq queues. Both operations are
* protected by the queue lock, and the latert is protected by the irq
* protected by the queue lock, and the later is protected by the irq
* spinlock as well.
*
* The completion handler fetches a buffer from the irq queue and fills it
@ -60,7 +59,7 @@
* returns immediately.
*
* When the buffer is full, the completion handler removes it from the irq
* queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue.
* queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
* At that point, any process waiting on the buffer will be woken up. If a
* process tries to dequeue a buffer after it has been marked ready, the
* dequeing will succeed immediately.
@ -91,8 +90,8 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
/*
* Allocate the video buffers.
*
* Pages are reserved to make sure they will not be swaped, as they will be
* filled in URB completion handler.
* Pages are reserved to make sure they will not be swapped, as they will be
* filled in the URB completion handler.
*
* Buffers will be individually mapped, so they must all be page aligned.
*/
@ -210,8 +209,8 @@ int uvc_query_buffer(struct uvc_video_queue *queue,
__uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
done:
mutex_unlock(&queue->mutex);
return ret;
mutex_unlock(&queue->mutex);
return ret;
}
/*
@ -236,7 +235,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
}
mutex_lock(&queue->mutex);
if (v4l2_buf->index >= queue->count) {
if (v4l2_buf->index >= queue->count) {
uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
ret = -EINVAL;
goto done;
@ -429,7 +428,7 @@ done:
* Cancel the video buffers queue.
*
* Cancelling the queue marks all buffers on the irq queue as erroneous,
* wakes them up and remove them from the queue.
* wakes them up and removes them from the queue.
*
* If the disconnect parameter is set, further calls to uvc_queue_buffer will
* fail with -ENODEV.

View File

@ -1,7 +1,7 @@
/*
* uvc_status.c -- USB Video Class driver - Status endpoint
*
* Copyright (C) 2007-2008
* Copyright (C) 2007-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/usb/input.h>

View File

@ -1,7 +1,7 @@
/*
* uvc_v4l2.c -- USB Video Class driver - V4L2 API
*
* Copyright (C) 2005-2008
* Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@ -37,7 +37,7 @@
* must be grouped (for instance the Red Balance, Blue Balance and Do White
* Balance V4L2 controls use the White Balance Component UVC control) or
* otherwise translated. The approach we take here is to use a translation
* table for the controls which can be mapped directly, and handle the others
* table for the controls that can be mapped directly, and handle the others
* manually.
*/
static int uvc_v4l2_query_menu(struct uvc_video_device *video,
@ -189,7 +189,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
probe->dwMaxVideoFrameSize =
video->streaming->ctrl.dwMaxVideoFrameSize;
/* Probe the device */
/* Probe the device. */
if ((ret = uvc_probe_video(video, probe)) < 0)
goto done;
@ -354,11 +354,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
*
* Each open instance of a UVC device can either be in a privileged or
* unprivileged state. Only a single instance can be in a privileged state at
* a given time. Trying to perform an operation which requires privileges will
* a given time. Trying to perform an operation that requires privileges will
* automatically acquire the required privileges if possible, or return -EBUSY
* otherwise. Privileges are dismissed when closing the instance.
*
* Operations which require privileges are:
* Operations that require privileges are:
*
* - VIDIOC_S_INPUT
* - VIDIOC_S_PARM

View File

@ -1,7 +1,7 @@
/*
* uvc_video.c -- USB Video Class driver - Video handling
*
* Copyright (C) 2005-2008
* Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
@ -115,7 +114,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
ret = 0;
goto out;
} else if (query == GET_DEF && probe == 1) {
} else if (query == GET_DEF && probe == 1 && ret != size) {
/* Many cameras don't support the GET_DEF request on their
* video probe control. Warn once and return, the caller will
* fall back to GET_CUR.
@ -160,7 +159,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
}
/* Some broken devices return a null or wrong dwMaxVideoFrameSize.
* Try to get the value from the format and frame descriptor.
* Try to get the value from the format and frame descriptors.
*/
uvc_fixup_buffer_size(video, ctrl);
ret = 0;
@ -191,9 +190,6 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
*(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality);
*(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize);
*(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay);
/* Note: Some of the fields below are not required for IN devices (see
* UVC spec, 4.3.1.1), but we still copy them in case support for OUT
* devices is added in the future. */
put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]);
put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]);
@ -400,7 +396,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
*
* Empty buffers (bytesused == 0) don't trigger end of frame detection
* as it doesn't make sense to return an empty buffer. This also
* avoids detecting and of frame conditions at FID toggling if the
* avoids detecting end of frame conditions at FID toggling if the
* previous payload had the EOF bit set.
*/
if (fid != video->last_fid && buf->buf.bytesused != 0) {
@ -453,6 +449,17 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
}
}
/* Video payload encoding is handled by uvc_video_encode_header() and
* uvc_video_encode_data(). Only bulk transfers are currently supported.
*
* uvc_video_encode_header is called at the start of a payload. It adds header
* data to the transfer buffer and returns the header size. As the only known
* UVC output device transfers a whole frame in a single payload, the EOF bit
* is always set in the header.
*
* uvc_video_encode_data is called for every URB and copies the data from the
* video buffer to the transfer buffer.
*/
static int uvc_video_encode_header(struct uvc_video_device *video,
struct uvc_buffer *buf, __u8 *data, int len)
{
@ -953,7 +960,7 @@ int uvc_video_suspend(struct uvc_video_device *video)
}
/*
* Reconfigure the video interface and restart streaming if it was enable
* Reconfigure the video interface and restart streaming if it was enabled
* before suspend.
*
* If an error occurs, disable the video queue. This will wake all pending
@ -985,8 +992,8 @@ int uvc_video_resume(struct uvc_video_device *video)
*/
/*
* Initialize the UVC video device by retrieving the default format and
* committing it.
* Initialize the UVC video device by switching to alternate setting 0 and
* retrieve the default format.
*
* Some cameras (namely the Fuji Finepix) set the format and frame
* indexes to zero. The UVC standard doesn't clearly make this a spec
@ -1014,7 +1021,7 @@ int uvc_video_init(struct uvc_video_device *video)
*/
usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
/* Some webcams don't suport GET_DEF request on the probe control. We
/* Some webcams don't suport GET_DEF requests on the probe control. We
* fall back to GET_CUR if GET_DEF fails.
*/
if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&

View File

@ -72,149 +72,149 @@ struct uvc_xu_control {
* UVC constants
*/
#define SC_UNDEFINED 0x00
#define SC_VIDEOCONTROL 0x01
#define SC_VIDEOSTREAMING 0x02
#define SC_VIDEO_INTERFACE_COLLECTION 0x03
#define SC_UNDEFINED 0x00
#define SC_VIDEOCONTROL 0x01
#define SC_VIDEOSTREAMING 0x02
#define SC_VIDEO_INTERFACE_COLLECTION 0x03
#define PC_PROTOCOL_UNDEFINED 0x00
#define PC_PROTOCOL_UNDEFINED 0x00
#define CS_UNDEFINED 0x20
#define CS_DEVICE 0x21
#define CS_CONFIGURATION 0x22
#define CS_STRING 0x23
#define CS_INTERFACE 0x24
#define CS_ENDPOINT 0x25
#define CS_UNDEFINED 0x20
#define CS_DEVICE 0x21
#define CS_CONFIGURATION 0x22
#define CS_STRING 0x23
#define CS_INTERFACE 0x24
#define CS_ENDPOINT 0x25
/* VideoControl class specific interface descriptor */
#define VC_DESCRIPTOR_UNDEFINED 0x00
#define VC_HEADER 0x01
#define VC_INPUT_TERMINAL 0x02
#define VC_OUTPUT_TERMINAL 0x03
#define VC_SELECTOR_UNIT 0x04
#define VC_PROCESSING_UNIT 0x05
#define VC_EXTENSION_UNIT 0x06
#define VC_DESCRIPTOR_UNDEFINED 0x00
#define VC_HEADER 0x01
#define VC_INPUT_TERMINAL 0x02
#define VC_OUTPUT_TERMINAL 0x03
#define VC_SELECTOR_UNIT 0x04
#define VC_PROCESSING_UNIT 0x05
#define VC_EXTENSION_UNIT 0x06
/* VideoStreaming class specific interface descriptor */
#define VS_UNDEFINED 0x00
#define VS_INPUT_HEADER 0x01
#define VS_OUTPUT_HEADER 0x02
#define VS_STILL_IMAGE_FRAME 0x03
#define VS_FORMAT_UNCOMPRESSED 0x04
#define VS_FRAME_UNCOMPRESSED 0x05
#define VS_FORMAT_MJPEG 0x06
#define VS_FRAME_MJPEG 0x07
#define VS_FORMAT_MPEG2TS 0x0a
#define VS_FORMAT_DV 0x0c
#define VS_COLORFORMAT 0x0d
#define VS_FORMAT_FRAME_BASED 0x10
#define VS_FRAME_FRAME_BASED 0x11
#define VS_FORMAT_STREAM_BASED 0x12
#define VS_UNDEFINED 0x00
#define VS_INPUT_HEADER 0x01
#define VS_OUTPUT_HEADER 0x02
#define VS_STILL_IMAGE_FRAME 0x03
#define VS_FORMAT_UNCOMPRESSED 0x04
#define VS_FRAME_UNCOMPRESSED 0x05
#define VS_FORMAT_MJPEG 0x06
#define VS_FRAME_MJPEG 0x07
#define VS_FORMAT_MPEG2TS 0x0a
#define VS_FORMAT_DV 0x0c
#define VS_COLORFORMAT 0x0d
#define VS_FORMAT_FRAME_BASED 0x10
#define VS_FRAME_FRAME_BASED 0x11
#define VS_FORMAT_STREAM_BASED 0x12
/* Endpoint type */
#define EP_UNDEFINED 0x00
#define EP_GENERAL 0x01
#define EP_ENDPOINT 0x02
#define EP_INTERRUPT 0x03
#define EP_UNDEFINED 0x00
#define EP_GENERAL 0x01
#define EP_ENDPOINT 0x02
#define EP_INTERRUPT 0x03
/* Request codes */
#define RC_UNDEFINED 0x00
#define SET_CUR 0x01
#define GET_CUR 0x81
#define GET_MIN 0x82
#define GET_MAX 0x83
#define GET_RES 0x84
#define GET_LEN 0x85
#define GET_INFO 0x86
#define GET_DEF 0x87
#define RC_UNDEFINED 0x00
#define SET_CUR 0x01
#define GET_CUR 0x81
#define GET_MIN 0x82
#define GET_MAX 0x83
#define GET_RES 0x84
#define GET_LEN 0x85
#define GET_INFO 0x86
#define GET_DEF 0x87
/* VideoControl interface controls */
#define VC_CONTROL_UNDEFINED 0x00
#define VC_VIDEO_POWER_MODE_CONTROL 0x01
#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
#define VC_CONTROL_UNDEFINED 0x00
#define VC_VIDEO_POWER_MODE_CONTROL 0x01
#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
/* Terminal controls */
#define TE_CONTROL_UNDEFINED 0x00
#define TE_CONTROL_UNDEFINED 0x00
/* Selector Unit controls */
#define SU_CONTROL_UNDEFINED 0x00
#define SU_INPUT_SELECT_CONTROL 0x01
#define SU_CONTROL_UNDEFINED 0x00
#define SU_INPUT_SELECT_CONTROL 0x01
/* Camera Terminal controls */
#define CT_CONTROL_UNDEFINED 0x00
#define CT_SCANNING_MODE_CONTROL 0x01
#define CT_AE_MODE_CONTROL 0x02
#define CT_AE_PRIORITY_CONTROL 0x03
#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
#define CT_FOCUS_RELATIVE_CONTROL 0x07
#define CT_FOCUS_AUTO_CONTROL 0x08
#define CT_IRIS_ABSOLUTE_CONTROL 0x09
#define CT_IRIS_RELATIVE_CONTROL 0x0a
#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
#define CT_ZOOM_RELATIVE_CONTROL 0x0c
#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
#define CT_PANTILT_RELATIVE_CONTROL 0x0e
#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
#define CT_ROLL_RELATIVE_CONTROL 0x10
#define CT_PRIVACY_CONTROL 0x11
#define CT_CONTROL_UNDEFINED 0x00
#define CT_SCANNING_MODE_CONTROL 0x01
#define CT_AE_MODE_CONTROL 0x02
#define CT_AE_PRIORITY_CONTROL 0x03
#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
#define CT_FOCUS_RELATIVE_CONTROL 0x07
#define CT_FOCUS_AUTO_CONTROL 0x08
#define CT_IRIS_ABSOLUTE_CONTROL 0x09
#define CT_IRIS_RELATIVE_CONTROL 0x0a
#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
#define CT_ZOOM_RELATIVE_CONTROL 0x0c
#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
#define CT_PANTILT_RELATIVE_CONTROL 0x0e
#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
#define CT_ROLL_RELATIVE_CONTROL 0x10
#define CT_PRIVACY_CONTROL 0x11
/* Processing Unit controls */
#define PU_CONTROL_UNDEFINED 0x00
#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
#define PU_BRIGHTNESS_CONTROL 0x02
#define PU_CONTRAST_CONTROL 0x03
#define PU_GAIN_CONTROL 0x04
#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
#define PU_HUE_CONTROL 0x06
#define PU_SATURATION_CONTROL 0x07
#define PU_SHARPNESS_CONTROL 0x08
#define PU_GAMMA_CONTROL 0x09
#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
#define PU_HUE_AUTO_CONTROL 0x10
#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
#define PU_CONTROL_UNDEFINED 0x00
#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
#define PU_BRIGHTNESS_CONTROL 0x02
#define PU_CONTRAST_CONTROL 0x03
#define PU_GAIN_CONTROL 0x04
#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
#define PU_HUE_CONTROL 0x06
#define PU_SATURATION_CONTROL 0x07
#define PU_SHARPNESS_CONTROL 0x08
#define PU_GAMMA_CONTROL 0x09
#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
#define PU_HUE_AUTO_CONTROL 0x10
#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
#define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01
#define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02
#define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03
/* VideoStreaming interface controls */
#define VS_CONTROL_UNDEFINED 0x00
#define VS_PROBE_CONTROL 0x01
#define VS_COMMIT_CONTROL 0x02
#define VS_STILL_PROBE_CONTROL 0x03
#define VS_STILL_COMMIT_CONTROL 0x04
#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
#define VS_STREAM_ERROR_CODE_CONTROL 0x06
#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
#define VS_SYNC_DELAY_CONTROL 0x09
#define VS_CONTROL_UNDEFINED 0x00
#define VS_PROBE_CONTROL 0x01
#define VS_COMMIT_CONTROL 0x02
#define VS_STILL_PROBE_CONTROL 0x03
#define VS_STILL_COMMIT_CONTROL 0x04
#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
#define VS_STREAM_ERROR_CODE_CONTROL 0x06
#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
#define VS_SYNC_DELAY_CONTROL 0x09
#define TT_VENDOR_SPECIFIC 0x0100
#define TT_STREAMING 0x0101
#define TT_VENDOR_SPECIFIC 0x0100
#define TT_STREAMING 0x0101
/* Input Terminal types */
#define ITT_VENDOR_SPECIFIC 0x0200
#define ITT_CAMERA 0x0201
#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
#define ITT_VENDOR_SPECIFIC 0x0200
#define ITT_CAMERA 0x0201
#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
/* Output Terminal types */
#define OTT_VENDOR_SPECIFIC 0x0300
#define OTT_DISPLAY 0x0301
#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
#define OTT_VENDOR_SPECIFIC 0x0300
#define OTT_DISPLAY 0x0301
#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
/* External Terminal types */
#define EXTERNAL_VENDOR_SPECIFIC 0x0400
#define COMPOSITE_CONNECTOR 0x0401
#define SVIDEO_CONNECTOR 0x0402
#define COMPONENT_CONNECTOR 0x0403
#define EXTERNAL_VENDOR_SPECIFIC 0x0400
#define COMPOSITE_CONNECTOR 0x0401
#define SVIDEO_CONNECTOR 0x0402
#define COMPONENT_CONNECTOR 0x0403
#define UVC_TERM_INPUT 0x0000
#define UVC_TERM_OUTPUT 0x8000
@ -541,11 +541,11 @@ struct uvc_streaming {
};
enum uvc_buffer_state {
UVC_BUF_STATE_IDLE = 0,
UVC_BUF_STATE_QUEUED = 1,
UVC_BUF_STATE_ACTIVE = 2,
UVC_BUF_STATE_DONE = 3,
UVC_BUF_STATE_ERROR = 4,
UVC_BUF_STATE_IDLE = 0,
UVC_BUF_STATE_QUEUED = 1,
UVC_BUF_STATE_ACTIVE = 2,
UVC_BUF_STATE_DONE = 3,
UVC_BUF_STATE_ERROR = 4,
};
struct uvc_buffer {

View File

@ -28,13 +28,13 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
{
switch (cmd) {
case VIDIOC_QUERYCTRL:
return v4l2_subdev_call(sd, core, querymenu, arg);
return v4l2_subdev_call(sd, core, queryctrl, arg);
case VIDIOC_G_CTRL:
return v4l2_subdev_call(sd, core, g_ctrl, arg);
case VIDIOC_S_CTRL:
return v4l2_subdev_call(sd, core, s_ctrl, arg);
case VIDIOC_QUERYMENU:
return v4l2_subdev_call(sd, core, queryctrl, arg);
return v4l2_subdev_call(sd, core, querymenu, arg);
case VIDIOC_LOG_STATUS:
return v4l2_subdev_call(sd, core, log_status);
case VIDIOC_DBG_G_CHIP_IDENT:

View File

@ -349,7 +349,6 @@ struct card_info {
u16 i2c_decoder, i2c_encoder; /* I2C types */
u16 video_vfe, video_codec; /* videocodec types */
u16 audio_chip; /* audio type */
u16 vendor_id, device_id; /* subsystem vendor/device ID */
int inputs; /* number of video inputs */
struct input {
@ -401,7 +400,6 @@ struct zoran {
char name[32]; /* name of this device */
struct pci_dev *pci_dev; /* PCI device */
unsigned char revision; /* revision of zr36057 */
unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */
unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
spinlock_t spinlock; /* Spinlock */
@ -490,16 +488,10 @@ struct zoran {
wait_queue_head_t test_q;
};
/*The following should be done in more portable way. It depends on define
of _ALPHA_BUZ in the Makefile.*/
#ifdef _ALPHA_BUZ
#define btwrite(dat,adr) writel((dat), zr->zr36057_adr+(adr))
#define btread(adr) readl(zr->zr36057_adr+(adr))
#else
/* There was something called _ALPHA_BUZ that used the PCI address instead of
* the kernel iomapped address for btread/btwrite. */
#define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr))
#define btread(adr) readl(zr->zr36057_mem+(adr))
#endif
#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
#define btor(dat,adr) btwrite((dat) | btread(adr), adr)

View File

@ -61,17 +61,17 @@
extern const struct zoran_format zoran_formats[];
static int card[BUZ_MAX] = { -1, -1, -1, -1 };
static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(card, "The type of card");
MODULE_PARM_DESC(card, "Card type");
static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(encoder, int, NULL, 0444);
MODULE_PARM_DESC(encoder, "i2c TV encoder");
MODULE_PARM_DESC(encoder, "Video encoder chip");
static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(decoder, int, NULL, 0444);
MODULE_PARM_DESC(decoder, "i2c TV decoder");
MODULE_PARM_DESC(decoder, "Video decoder chip");
/*
The video mem address of the video card.
@ -104,9 +104,9 @@ module_param(default_norm, int, 0444);
MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
/* /dev/videoN, -1 for autodetect */
static int video_nr[BUZ_MAX] = {-1, -1, -1, -1};
static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(video_nr, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
/*
Number and size of grab buffers for Video 4 Linux
@ -153,9 +153,21 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
MODULE_AUTHOR("Serguei Miridonov");
MODULE_LICENSE("GPL");
#define ZR_DEVICE(subven, subdev, data) { \
.vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
.subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
int zoran_num; /* number of Buzs in use */
struct zoran *zoran[BUZ_MAX];
static struct pci_device_id zr36067_pci_tbl[] = {
ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus),
ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus),
ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
{0}
};
MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
static unsigned int zoran_num; /* number of cards found */
/* videocodec bus functions ZR36060 */
static u32
@ -472,8 +484,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC10plus,
.name = "DC10plus",
.vendor_id = PCI_VENDOR_ID_MIRO,
.device_id = PCI_DEVICE_ID_MIRO_DC10PLUS,
.i2c_decoder = I2C_DRIVERID_SAA7110,
.i2c_encoder = I2C_DRIVERID_ADV7175,
.video_codec = CODEC_TYPE_ZR36060,
@ -531,8 +541,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC30plus,
.name = "DC30plus",
.vendor_id = PCI_VENDOR_ID_MIRO,
.device_id = PCI_DEVICE_ID_MIRO_DC30PLUS,
.i2c_decoder = I2C_DRIVERID_VPX3220,
.i2c_encoder = I2C_DRIVERID_ADV7175,
.video_codec = CODEC_TYPE_ZR36050,
@ -589,8 +597,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = LML33R10,
.name = "LML33R10",
.vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH,
.device_id = PCI_DEVICE_ID_LML_33R10,
.i2c_decoder = I2C_DRIVERID_SAA7114,
.i2c_encoder = I2C_DRIVERID_ADV7170,
.video_codec = CODEC_TYPE_ZR36060,
@ -618,8 +624,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = BUZ,
.name = "Buz",
.vendor_id = PCI_VENDOR_ID_IOMEGA,
.device_id = PCI_DEVICE_ID_IOMEGA_BUZ,
.i2c_decoder = I2C_DRIVERID_SAA7111A,
.i2c_encoder = I2C_DRIVERID_SAA7185B,
.video_codec = CODEC_TYPE_ZR36060,
@ -649,8 +653,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
.name = "6-Eyes",
/* AverMedia chose not to brand the 6-Eyes. Thus it
can't be autodetected, and requires card=x. */
.vendor_id = -1,
.device_id = -1,
.i2c_decoder = I2C_DRIVERID_KS0127,
.i2c_encoder = I2C_DRIVERID_BT866,
.video_codec = CODEC_TYPE_ZR36060,
@ -1138,7 +1140,8 @@ zr36057_init (struct zoran *zr)
strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
if (err < 0)
goto exit_unregister;
goto exit_free;
video_set_drvdata(zr->video_dev, zr);
zoran_init_hardware(zr);
if (zr36067_debug > 2)
@ -1153,19 +1156,19 @@ zr36057_init (struct zoran *zr)
zr->initialized = 1;
return 0;
exit_unregister:
zoran_unregister_i2c(zr);
exit_free:
kfree(zr->stat_com);
kfree(zr->video_dev);
return err;
}
static void
zoran_release (struct zoran *zr)
static void __devexit zoran_remove(struct pci_dev *pdev)
{
struct zoran *zr = pci_get_drvdata(pdev);
if (!zr->initialized)
goto exit_free;
/* unregister videocodec bus */
if (zr->codec) {
struct videocodec_master *master = zr->codec->master_data;
@ -1194,6 +1197,7 @@ zoran_release (struct zoran *zr)
pci_disable_device(zr->pci_dev);
video_unregister_device(zr->video_dev);
exit_free:
pci_set_drvdata(pdev, NULL);
kfree(zr);
}
@ -1256,338 +1260,329 @@ zoran_setup_videocodec (struct zoran *zr,
* Scan for a Buz card (actually for the PCI controller ZR36057),
* request the irq and map the io memory
*/
static int __devinit
find_zr36057 (void)
static int __devinit zoran_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
unsigned char latency, need_latency;
struct zoran *zr;
struct pci_dev *dev = NULL;
int result;
struct videocodec_master *master_vfe = NULL;
struct videocodec_master *master_codec = NULL;
int card_num;
char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
unsigned int nr;
zoran_num = 0;
while (zoran_num < BUZ_MAX &&
(dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
card_num = card[zoran_num];
zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
if (!zr) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - kzalloc failed\n",
ZORAN_NAME);
continue;
}
zr->pci_dev = dev;
//zr->zr36057_mem = NULL;
zr->id = zoran_num;
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
spin_lock_init(&zr->spinlock);
mutex_init(&zr->resource_lock);
if (pci_enable_device(dev))
goto zr_free_mem;
zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
&zr->revision);
nr = zoran_num++;
if (nr >= BUZ_MAX) {
dprintk(1,
KERN_ERR
"%s: driver limited to %d card(s) maximum\n",
ZORAN_NAME, BUZ_MAX);
return -ENOENT;
}
zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
if (!zr) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - kzalloc failed\n",
ZORAN_NAME);
return -ENOMEM;
}
zr->pci_dev = pdev;
zr->id = nr;
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
spin_lock_init(&zr->spinlock);
mutex_init(&zr->resource_lock);
if (pci_enable_device(pdev))
goto zr_free_mem;
pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
dprintk(1,
KERN_INFO
"%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision,
zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
if (zr->revision >= 2) {
dprintk(1,
KERN_INFO
"%s: Subsystem vendor=0x%04x id=0x%04x\n",
ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor,
zr->pci_dev->subsystem_device);
}
/* Use auto-detected card type? */
if (card[nr] == -1) {
if (zr->revision < 2) {
dprintk(1,
KERN_INFO
"%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
zr->zr36057_adr);
if (card_num == -1) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
ZR_DEVNAME(zr));
goto zr_free_mem;
}
} else {
int i;
unsigned short ss_vendor, ss_device;
ss_vendor = zr->pci_dev->subsystem_vendor;
ss_device = zr->pci_dev->subsystem_device;
dprintk(1,
KERN_INFO
"%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
zr->zr36057_adr);
dprintk(1,
KERN_INFO
"%s: subsystem vendor=0x%04x id=0x%04x\n",
ZR_DEVNAME(zr), ss_vendor, ss_device);
if (card_num == -1) {
dprintk(3,
KERN_DEBUG
"%s: find_zr36057() - trying to autodetect card type\n",
ZR_DEVNAME(zr));
for (i=0;i<NUM_CARDS;i++) {
if (ss_vendor == zoran_cards[i].vendor_id &&
ss_device == zoran_cards[i].device_id) {
dprintk(3,
KERN_DEBUG
"%s: find_zr36057() - card %s detected\n",
ZR_DEVNAME(zr),
zoran_cards[i].name);
card_num = i;
break;
}
}
if (i == NUM_CARDS) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - unknown card\n",
ZR_DEVNAME(zr));
goto zr_free_mem;
}
}
}
if (card_num < 0 || card_num >= NUM_CARDS) {
dprintk(2,
KERN_ERR
"%s: find_zr36057() - invalid cardnum %d\n",
ZR_DEVNAME(zr), card_num);
goto zr_free_mem;
}
/* even though we make this a non pointer and thus
* theoretically allow for making changes to this struct
* on a per-individual card basis at runtime, this is
* strongly discouraged. This structure is intended to
* keep general card information, no settings or anything */
zr->card = zoran_cards[card_num];
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
"%s[%u]", zr->card.name, zr->id);
zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
if (!zr->zr36057_mem) {
"%s: No card type specified, please use the card=X module parameter\n",
ZR_DEVNAME(zr));
dprintk(1,
KERN_ERR
"%s: find_zr36057() - ioremap failed\n",
"%s: It is not possible to auto-detect ZR36057 based cards\n",
ZR_DEVNAME(zr));
goto zr_free_mem;
}
result = request_irq(zr->pci_dev->irq,
zoran_irq,
IRQF_SHARED | IRQF_DISABLED,
ZR_DEVNAME(zr),
(void *) zr);
if (result < 0) {
if (result == -EINVAL) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - bad irq number or handler\n",
ZR_DEVNAME(zr));
} else if (result == -EBUSY) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
ZR_DEVNAME(zr), zr->pci_dev->irq);
} else {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - can't assign irq, error code %d\n",
ZR_DEVNAME(zr), result);
}
goto zr_unmap;
}
/* set PCI latency timer */
pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
&latency);
need_latency = zr->revision > 1 ? 32 : 48;
if (latency != need_latency) {
dprintk(2,
KERN_INFO
"%s: Changing PCI latency from %d to %d.\n",
ZR_DEVNAME(zr), latency, need_latency);
pci_write_config_byte(zr->pci_dev,
PCI_LATENCY_TIMER,
need_latency);
}
zr36057_restart(zr);
/* i2c */
dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
ZR_DEVNAME(zr));
/* i2c decoder */
if (decoder[zr->id] != -1) {
i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
zr->card.i2c_decoder = decoder[zr->id];
} else if (zr->card.i2c_decoder != 0) {
i2c_dec_name =
i2cid_to_modulename(zr->card.i2c_decoder);
} else {
i2c_dec_name = NULL;
}
if (i2c_dec_name) {
if ((result = request_module(i2c_dec_name)) < 0) {
dprintk(1,
KERN_ERR
"%s: failed to load module %s: %d\n",
ZR_DEVNAME(zr), i2c_dec_name, result);
}
}
/* i2c encoder */
if (encoder[zr->id] != -1) {
i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
zr->card.i2c_encoder = encoder[zr->id];
} else if (zr->card.i2c_encoder != 0) {
i2c_enc_name =
i2cid_to_modulename(zr->card.i2c_encoder);
} else {
i2c_enc_name = NULL;
}
if (i2c_enc_name) {
if ((result = request_module(i2c_enc_name)) < 0) {
dprintk(1,
KERN_ERR
"%s: failed to load module %s: %d\n",
ZR_DEVNAME(zr), i2c_enc_name, result);
}
}
if (zoran_register_i2c(zr) < 0) {
card_num = ent->driver_data;
if (card_num >= NUM_CARDS) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - can't initialize i2c bus\n",
"%s: Unknown card, try specifying card=X module parameter\n",
ZR_DEVNAME(zr));
goto zr_free_irq;
goto zr_free_mem;
}
dprintk(3,
KERN_DEBUG
"%s: %s() - card %s detected\n",
ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name);
} else {
card_num = card[nr];
if (card_num >= NUM_CARDS || card_num < 0) {
dprintk(1,
KERN_ERR
"%s: User specified card type %d out of range (0 .. %d)\n",
ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
goto zr_free_mem;
}
}
/* even though we make this a non pointer and thus
* theoretically allow for making changes to this struct
* on a per-individual card basis at runtime, this is
* strongly discouraged. This structure is intended to
* keep general card information, no settings or anything */
zr->card = zoran_cards[card_num];
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
"%s[%u]", zr->card.name, zr->id);
zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
if (!zr->zr36057_mem) {
dprintk(1,
KERN_ERR
"%s: %s() - ioremap failed\n",
ZR_DEVNAME(zr), __func__);
goto zr_free_mem;
}
result = request_irq(zr->pci_dev->irq, zoran_irq,
IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
if (result < 0) {
if (result == -EINVAL) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - bad irq number or handler\n",
ZR_DEVNAME(zr));
} else if (result == -EBUSY) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
ZR_DEVNAME(zr), zr->pci_dev->irq);
} else {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - can't assign irq, error code %d\n",
ZR_DEVNAME(zr), result);
}
goto zr_unmap;
}
/* set PCI latency timer */
pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
&latency);
need_latency = zr->revision > 1 ? 32 : 48;
if (latency != need_latency) {
dprintk(2,
KERN_INFO "%s: Initializing videocodec bus...\n",
ZR_DEVNAME(zr));
KERN_INFO
"%s: Changing PCI latency from %d to %d\n",
ZR_DEVNAME(zr), latency, need_latency);
pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
need_latency);
}
if (zr->card.video_codec != 0 &&
(codec_name =
codecid_to_modulename(zr->card.video_codec)) != NULL) {
if ((result = request_module(codec_name)) < 0) {
zr36057_restart(zr);
/* i2c */
dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
ZR_DEVNAME(zr));
/* i2c decoder */
if (decoder[zr->id] != -1) {
i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
zr->card.i2c_decoder = decoder[zr->id];
} else if (zr->card.i2c_decoder != 0) {
i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
} else {
i2c_dec_name = NULL;
}
if (i2c_dec_name) {
result = request_module(i2c_dec_name);
if (result < 0) {
dprintk(1,
KERN_ERR
"%s: failed to load module %s: %d\n",
ZR_DEVNAME(zr), i2c_dec_name, result);
}
}
/* i2c encoder */
if (encoder[zr->id] != -1) {
i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
zr->card.i2c_encoder = encoder[zr->id];
} else if (zr->card.i2c_encoder != 0) {
i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
} else {
i2c_enc_name = NULL;
}
if (i2c_enc_name) {
result = request_module(i2c_enc_name);
if (result < 0) {
dprintk(1,
KERN_ERR
"%s: failed to load module %s: %d\n",
ZR_DEVNAME(zr), i2c_enc_name, result);
}
}
if (zoran_register_i2c(zr) < 0) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - can't initialize i2c bus\n",
ZR_DEVNAME(zr));
goto zr_free_irq;
}
dprintk(2,
KERN_INFO "%s: Initializing videocodec bus...\n",
ZR_DEVNAME(zr));
if (zr->card.video_codec) {
codec_name = codecid_to_modulename(zr->card.video_codec);
if (codec_name) {
result = request_module(codec_name);
if (result) {
dprintk(1,
KERN_ERR
"%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), codec_name, result);
}
}
if (zr->card.video_vfe != 0 &&
(vfe_name =
codecid_to_modulename(zr->card.video_vfe)) != NULL) {
if ((result = request_module(vfe_name)) < 0) {
}
if (zr->card.video_vfe) {
vfe_name = codecid_to_modulename(zr->card.video_vfe);
if (vfe_name) {
result = request_module(vfe_name);
if (result < 0) {
dprintk(1,
KERN_ERR
"%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), vfe_name, result);
}
}
/* reset JPEG codec */
jpeg_codec_sleep(zr, 1);
jpeg_codec_reset(zr);
/* video bus enabled */
/* display codec revision */
if (zr->card.video_codec != 0) {
master_codec = zoran_setup_videocodec(zr,
zr->card.video_codec);
if (!master_codec)
goto zr_unreg_i2c;
zr->codec = videocodec_attach(master_codec);
if (!zr->codec) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - no codec found\n",
ZR_DEVNAME(zr));
goto zr_free_codec;
}
if (zr->codec->type != zr->card.video_codec) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - wrong codec\n",
ZR_DEVNAME(zr));
goto zr_detach_codec;
}
}
if (zr->card.video_vfe != 0) {
master_vfe = zoran_setup_videocodec(zr,
zr->card.video_vfe);
if (!master_vfe)
goto zr_detach_codec;
zr->vfe = videocodec_attach(master_vfe);
if (!zr->vfe) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - no VFE found\n",
ZR_DEVNAME(zr));
goto zr_free_vfe;
}
if (zr->vfe->type != zr->card.video_vfe) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() = wrong VFE\n",
ZR_DEVNAME(zr));
goto zr_detach_vfe;
}
}
/* Success so keep the pci_dev referenced */
pci_dev_get(zr->pci_dev);
zoran[zoran_num++] = zr;
continue;
// Init errors
zr_detach_vfe:
videocodec_detach(zr->vfe);
zr_free_vfe:
kfree(master_vfe);
zr_detach_codec:
videocodec_detach(zr->codec);
zr_free_codec:
kfree(master_codec);
zr_unreg_i2c:
zoran_unregister_i2c(zr);
zr_free_irq:
btwrite(0, ZR36057_SPGPPCR);
free_irq(zr->pci_dev->irq, zr);
zr_unmap:
iounmap(zr->zr36057_mem);
zr_free_mem:
kfree(zr);
continue;
}
if (dev) /* Clean up ref count on early exit */
pci_dev_put(dev);
if (zoran_num == 0) {
dprintk(1, KERN_INFO "No known MJPEG cards found.\n");
/* reset JPEG codec */
jpeg_codec_sleep(zr, 1);
jpeg_codec_reset(zr);
/* video bus enabled */
/* display codec revision */
if (zr->card.video_codec != 0) {
master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
if (!master_codec)
goto zr_unreg_i2c;
zr->codec = videocodec_attach(master_codec);
if (!zr->codec) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - no codec found\n",
ZR_DEVNAME(zr));
goto zr_free_codec;
}
if (zr->codec->type != zr->card.video_codec) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - wrong codec\n",
ZR_DEVNAME(zr));
goto zr_detach_codec;
}
}
return zoran_num;
if (zr->card.video_vfe != 0) {
master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
if (!master_vfe)
goto zr_detach_codec;
zr->vfe = videocodec_attach(master_vfe);
if (!zr->vfe) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - no VFE found\n",
ZR_DEVNAME(zr));
goto zr_free_vfe;
}
if (zr->vfe->type != zr->card.video_vfe) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() = wrong VFE\n",
ZR_DEVNAME(zr));
goto zr_detach_vfe;
}
}
/* take care of Natoma chipset and a revision 1 zr36057 */
if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
zr->jpg_buffers.need_contiguous = 1;
dprintk(1,
KERN_INFO
"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
ZR_DEVNAME(zr));
}
if (zr36057_init(zr) < 0)
goto zr_detach_vfe;
zoran_proc_init(zr);
pci_set_drvdata(pdev, zr);
return 0;
zr_detach_vfe:
videocodec_detach(zr->vfe);
zr_free_vfe:
kfree(master_vfe);
zr_detach_codec:
videocodec_detach(zr->codec);
zr_free_codec:
kfree(master_codec);
zr_unreg_i2c:
zoran_unregister_i2c(zr);
zr_free_irq:
btwrite(0, ZR36057_SPGPPCR);
free_irq(zr->pci_dev->irq, zr);
zr_unmap:
iounmap(zr->zr36057_mem);
zr_free_mem:
kfree(zr);
return -ENODEV;
}
static int __init
init_dc10_cards (void)
{
int i;
static struct pci_driver zoran_driver = {
.name = "zr36067",
.id_table = zr36067_pci_tbl,
.probe = zoran_probe,
.remove = zoran_remove,
};
static int __init zoran_init(void)
{
int res;
memset(zoran, 0, sizeof(zoran));
printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
/* Look for cards */
if (find_zr36057() < 0) {
return -EIO;
}
if (zoran_num == 0)
return -ENODEV;
dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME,
zoran_num);
/* check the parameters we have been given, adjust if necessary */
if (v4l_nbufs < 2)
v4l_nbufs = 2;
@ -1629,37 +1624,22 @@ init_dc10_cards (void)
ZORAN_NAME);
}
/* take care of Natoma chipset and a revision 1 zr36057 */
for (i = 0; i < zoran_num; i++) {
struct zoran *zr = zoran[i];
if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
zr->jpg_buffers.need_contiguous = 1;
dprintk(1,
KERN_INFO
"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
ZR_DEVNAME(zr));
}
if (zr36057_init(zr) < 0) {
for (i = 0; i < zoran_num; i++)
zoran_release(zoran[i]);
return -EIO;
}
zoran_proc_init(zr);
res = pci_register_driver(&zoran_driver);
if (res) {
dprintk(1,
KERN_ERR
"%s: Unable to register ZR36057 driver\n",
ZORAN_NAME);
return res;
}
return 0;
}
static void __exit
unload_dc10_cards (void)
static void __exit zoran_exit(void)
{
int i;
for (i = 0; i < zoran_num; i++)
zoran_release(zoran[i]);
pci_unregister_driver(&zoran_driver);
}
module_init(init_dc10_cards);
module_exit(unload_dc10_cards);
module_init(zoran_init);
module_exit(zoran_exit);

View File

@ -40,8 +40,6 @@ extern int zr36067_debug;
/* Anybody who uses more than four? */
#define BUZ_MAX 4
extern int zoran_num;
extern struct zoran *zoran[BUZ_MAX];
extern struct video_device zoran_template;

View File

@ -1196,83 +1196,54 @@ zoran_close_end_session (struct file *file)
* Open a zoran card. Right now the flags stuff is just playing
*/
static int
zoran_open(struct file *file)
static int zoran_open(struct file *file)
{
unsigned int minor = video_devdata(file)->minor;
struct zoran *zr = NULL;
struct zoran *zr = video_drvdata(file);
struct zoran_fh *fh;
int i, res, first_open = 0, have_module_locks = 0;
int res, first_open = 0;
dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
lock_kernel();
/* find the device */
for (i = 0; i < zoran_num; i++) {
if (zoran[i]->video_dev->minor == minor) {
zr = zoran[i];
break;
}
}
if (!zr) {
dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME);
res = -ENODEV;
goto open_unlock_and_return;
}
/* see fs/device.c - the kernel already locks during open(),
* so locking ourselves only causes deadlocks */
/*mutex_lock(&zr->resource_lock);*/
if (zr->user >= 2048) {
dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
ZR_DEVNAME(zr), zr->user);
res = -EBUSY;
goto fail_unlock;
}
if (!zr->decoder) {
dprintk(1,
KERN_ERR "%s: no TV decoder loaded for device!\n",
ZR_DEVNAME(zr));
res = -EIO;
goto open_unlock_and_return;
goto fail_unlock;
}
/* try to grab a module lock */
if (!try_module_get(THIS_MODULE)) {
dprintk(1,
KERN_ERR
"%s: failed to acquire my own lock! PANIC!\n",
ZR_DEVNAME(zr));
res = -ENODEV;
goto open_unlock_and_return;
}
if (!try_module_get(zr->decoder->driver->driver.owner)) {
dprintk(1,
KERN_ERR
"%s: failed to grab ownership of i2c decoder\n",
"%s: failed to grab ownership of video decoder\n",
ZR_DEVNAME(zr));
res = -EIO;
module_put(THIS_MODULE);
goto open_unlock_and_return;
goto fail_unlock;
}
if (zr->encoder &&
!try_module_get(zr->encoder->driver->driver.owner)) {
dprintk(1,
KERN_ERR
"%s: failed to grab ownership of i2c encoder\n",
"%s: failed to grab ownership of video encoder\n",
ZR_DEVNAME(zr));
res = -EIO;
module_put(zr->decoder->driver->driver.owner);
module_put(THIS_MODULE);
goto open_unlock_and_return;
goto fail_decoder;
}
have_module_locks = 1;
if (zr->user >= 2048) {
dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
ZR_DEVNAME(zr), zr->user);
res = -EBUSY;
goto open_unlock_and_return;
}
dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
/* now, create the open()-specific file_ops struct */
fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
if (!fh) {
@ -1281,7 +1252,7 @@ zoran_open(struct file *file)
"%s: zoran_open() - allocation of zoran_fh failed\n",
ZR_DEVNAME(zr));
res = -ENOMEM;
goto open_unlock_and_return;
goto fail_encoder;
}
/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
* on norm-change! */
@ -1292,9 +1263,8 @@ zoran_open(struct file *file)
KERN_ERR
"%s: zoran_open() - allocation of overlay_mask failed\n",
ZR_DEVNAME(zr));
kfree(fh);
res = -ENOMEM;
goto open_unlock_and_return;
goto fail_fh;
}
if (zr->user++ == 0)
@ -1319,22 +1289,19 @@ zoran_open(struct file *file)
return 0;
open_unlock_and_return:
/* if we grabbed locks, release them accordingly */
if (have_module_locks) {
module_put(zr->decoder->driver->driver.owner);
if (zr->encoder) {
module_put(zr->encoder->driver->driver.owner);
}
module_put(THIS_MODULE);
}
/* if there's no device found, we didn't obtain the lock either */
if (zr) {
/*mutex_unlock(&zr->resource_lock);*/
}
fail_fh:
kfree(fh);
fail_encoder:
if (zr->encoder)
module_put(zr->encoder->driver->driver.owner);
fail_decoder:
module_put(zr->decoder->driver->driver.owner);
fail_unlock:
unlock_kernel();
dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
ZR_DEVNAME(zr), res, zr->user);
return res;
}
@ -1344,8 +1311,8 @@ zoran_close(struct file *file)
struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
/* kernel locks (fs/device.c), so don't do that ourselves
* (prevents deadlocks) */
@ -1391,10 +1358,8 @@ zoran_close(struct file *file)
/* release locks on the i2c modules */
module_put(zr->decoder->driver->driver.owner);
if (zr->encoder) {
module_put(zr->encoder->driver->driver.owner);
}
module_put(THIS_MODULE);
if (zr->encoder)
module_put(zr->encoder->driver->driver.owner);
/*mutex_unlock(&zr->resource_lock);*/

View File

@ -94,16 +94,16 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
/* Call the specified callback for all subdevs matching grp_id (if 0, then
match them all). Ignore any errors. Note that you cannot add or delete
a subdev while walking the subdevs list. */
#define v4l2_device_call_all(dev, grp_id, o, f, args...) \
#define v4l2_device_call_all(dev, grpid, o, f, args...) \
__v4l2_device_call_subdevs(dev, \
!(grp_id) || sd->grp_id == (grp_id), o, f , ##args)
!(grpid) || sd->grp_id == (grpid), o, f , ##args)
/* Call the specified callback for all subdevs matching grp_id (if 0, then
match them all). If the callback returns an error other than 0 or
-ENOIOCTLCMD, then return with that error code. Note that you cannot
add or delete a subdev while walking the subdevs list. */
#define v4l2_device_call_until_err(dev, grp_id, o, f, args...) \
#define v4l2_device_call_until_err(dev, grpid, o, f, args...) \
__v4l2_device_call_subdevs_until_err(dev, \
!(grp_id) || sd->grp_id == (grp_id), o, f , ##args)
!(grpid) || sd->grp_id == (grpid), o, f , ##args)
#endif