Skip to content

Commit

Permalink
[PATCH] V4L: 907: em28xx cleanups and fixes
Browse files Browse the repository at this point in the history
- Em28xx cleanups and fixes.
- Some cleanups and audio amux adjust.
- em28xx will allways try, by default, the biggest size alt.
- Fixes audio mux code.
- Fixes some logs.
- Adds support for digital output for WinTV USB2 board.

Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Mauro Carvalho Chehab authored and Linus Torvalds committed Nov 9, 2005
1 parent c3d9319 commit eac9435
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 81 deletions.
15 changes: 10 additions & 5 deletions drivers/media/video/em28xx/em28xx-cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ struct em28xx_board em28xx_boards[] = {
.input = {{
.type = EM28XX_VMUX_TELEVISION,
.vmux = 0,
.amux = 0,
.amux = 6,
},{
.type = EM28XX_VMUX_SVIDEO,
.vmux = 2,
Expand Down Expand Up @@ -261,9 +261,11 @@ void em28xx_card_setup(struct em28xx *dev)
/* request some modules */
if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
struct tveeprom tv;
struct v4l2_audioout ao;
#ifdef CONFIG_MODULES
request_module("tveeprom");
request_module("ir-kbd-i2c");
request_module("msp3400");
#endif
/* Call first TVeeprom */

Expand All @@ -273,10 +275,13 @@ void em28xx_card_setup(struct em28xx *dev)
dev->tuner_type= tv.tuner_type;
if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
dev->has_msp34xx=1;
} else dev->has_msp34xx=0;
em28xx_write_regs_req(dev,0x06,0x00,"\x40",1);// Serial Bus Frequency Select Register
em28xx_write_regs_req(dev,0x0f,0x00,"\x87",1);// XCLK Frequency Select Register
em28xx_write_regs_req(dev,0x88,0x0d,"\xd0",1);
memset (&ao,0,sizeof(ao));

ao.index=2;
ao.mode=V4L2_AUDMODE_32BITS;
em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
} else
dev->has_msp34xx=0;
}
}

Expand Down
17 changes: 3 additions & 14 deletions drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,20 +797,9 @@ int em28xx_set_alternate(struct em28xx *dev)
dev->alt = alt;
if (dev->alt == 0) {
int i;
if(dev->is_em2800){ /* always use the max packet size for em2800 based devices */
for(i=0;i< EM28XX_MAX_ALT; i++)
if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
dev->alt=i;
}else{
unsigned int min_pkt_size = dev->field_size / 137; /* FIXME: empiric magic number */
em28xx_coredbg("minimum isoc packet size: %u", min_pkt_size);
dev->alt = 7;
for (i = 1; i < EM28XX_MAX_ALT; i += 2) /* FIXME: skip even alternate: why do they not work? */
if (dev->alt_max_pkt_size[i] >= min_pkt_size) {
dev->alt = i;
break;
}
}
for(i=0;i< EM28XX_MAX_ALT; i++)
if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
dev->alt=i;
}

if (dev->alt != prev_alt) {
Expand Down
107 changes: 58 additions & 49 deletions drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,35 @@ static void em28xx_empty_framequeues(struct em28xx *dev)
}
}

static void video_mux(struct em28xx *dev, int index)
{
int input, ainput;

input = INPUT(index)->vmux;
dev->ctl_input = index;
dev->ctl_ainput = INPUT(index)->amux;

em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);


em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);

if (dev->has_msp34xx) {
em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
ainput = EM28XX_AUDIO_SRC_TUNER;
em28xx_audio_source(dev, ainput);
} else {
switch (dev->ctl_ainput) {
case 0:
ainput = EM28XX_AUDIO_SRC_TUNER;
break;
default:
ainput = EM28XX_AUDIO_SRC_LINE;
}
em28xx_audio_source(dev, ainput);
}
}

/*
* em28xx_v4l2_open()
* inits the device and starts isoc transfer
Expand All @@ -298,7 +327,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
filp->private_data=dev;


em28xx_videodbg("users=%d", dev->users);
em28xx_videodbg("users=%d\n", dev->users);

if (!down_read_trylock(&em28xx_disconnect))
return -ERESTARTSYS;
Expand Down Expand Up @@ -352,6 +381,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)

dev->state |= DEV_INITIALIZED;

video_mux(dev, 0);

err:
up(&dev->lock);
up_read(&em28xx_disconnect);
Expand Down Expand Up @@ -386,7 +417,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
int errCode;
struct em28xx *dev=filp->private_data;

em28xx_videodbg("users=%d", dev->users);
em28xx_videodbg("users=%d\n", dev->users);

down(&dev->lock);

Expand All @@ -404,7 +435,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)

/* set alternate 0 */
dev->alt = 0;
em28xx_videodbg("setting alternate 0");
em28xx_videodbg("setting alternate 0\n");
errCode = usb_set_interface(dev->udev, 0, 0);
if (errCode < 0) {
em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n",
Expand Down Expand Up @@ -434,20 +465,20 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
return -ERESTARTSYS;

if (dev->state & DEV_DISCONNECTED) {
em28xx_videodbg("device not present");
em28xx_videodbg("device not present\n");
up(&dev->fileop_lock);
return -ENODEV;
}

if (dev->state & DEV_MISCONFIGURED) {
em28xx_videodbg("device misconfigured; close and open it again");
em28xx_videodbg("device misconfigured; close and open it again\n");
up(&dev->fileop_lock);
return -EIO;
}

if (dev->io == IO_MMAP) {
em28xx_videodbg ("IO method is set to mmap; close and open"
" the device again to choose the read method");
" the device again to choose the read method\n");
up(&dev->fileop_lock);
return -EINVAL;
}
Expand Down Expand Up @@ -524,9 +555,9 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
return POLLERR;

if (dev->state & DEV_DISCONNECTED) {
em28xx_videodbg("device not present");
em28xx_videodbg("device not present\n");
} else if (dev->state & DEV_MISCONFIGURED) {
em28xx_videodbg("device is misconfigured; close and open it again");
em28xx_videodbg("device is misconfigured; close and open it again\n");
} else {
if (dev->io == IO_NONE) {
if (!em28xx_request_buffers
Expand Down Expand Up @@ -595,14 +626,14 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
return -ERESTARTSYS;

if (dev->state & DEV_DISCONNECTED) {
em28xx_videodbg("mmap: device not present");
em28xx_videodbg("mmap: device not present\n");
up(&dev->fileop_lock);
return -ENODEV;
}

if (dev->state & DEV_MISCONFIGURED) {
em28xx_videodbg ("mmap: Device is misconfigured; close and "
"open it again");
"open it again\n");
up(&dev->fileop_lock);
return -EIO;
}
Expand All @@ -618,7 +649,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
break;
}
if (i == dev->num_frames) {
em28xx_videodbg("mmap: user supplied mapping address is out of range");
em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
up(&dev->fileop_lock);
return -EINVAL;
}
Expand All @@ -632,7 +663,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
page = vmalloc_to_pfn((void *)pos);
if (remap_pfn_range(vma, start, page, PAGE_SIZE,
vma->vm_page_prot)) {
em28xx_videodbg("mmap: rename page map failed");
em28xx_videodbg("mmap: rename page map failed\n");
up(&dev->fileop_lock);
return -EAGAIN;
}
Expand Down Expand Up @@ -749,7 +780,7 @@ static int em28xx_stream_interrupt(struct em28xx *dev)
else if (ret) {
dev->state |= DEV_MISCONFIGURED;
em28xx_videodbg("device is misconfigured; close and "
"open /dev/video%d again", dev->vdev->minor);
"open /dev/video%d again\n", dev->vdev->minor);
return ret;
}

Expand Down Expand Up @@ -800,28 +831,6 @@ static int em28xx_set_norm(struct em28xx *dev, int width, int height)
return 0;
}

static void video_mux(struct em28xx *dev, int index)
{
int input, ainput;

input = INPUT(index)->vmux;
dev->ctl_input = index;

em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);

dev->ctl_ainput = INPUT(index)->amux;

switch (dev->ctl_ainput) {
case 0:
ainput = EM28XX_AUDIO_SRC_TUNER;
break;
default:
ainput = EM28XX_AUDIO_SRC_LINE;
}

em28xx_audio_source(dev, ainput);
}

/*
* em28xx_v4l2_do_ioctl()
* This function is _not_ called directly, but from
Expand Down Expand Up @@ -1062,7 +1071,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
t->signal =
(status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;

em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x", t->signal,
em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
t->afc);
return 0;
}
Expand Down Expand Up @@ -1146,7 +1155,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,

dev->stream = STREAM_ON; /* FIXME: Start video capture here? */

em28xx_videodbg("VIDIOC_STREAMON: starting stream");
em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");

return 0;
}
Expand All @@ -1160,7 +1169,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
return -EINVAL;

if (dev->stream == STREAM_ON) {
em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream");
em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
if ((ret = em28xx_stream_interrupt(dev)))
return ret;
}
Expand Down Expand Up @@ -1234,7 +1243,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
{
struct v4l2_format *format = arg;

em28xx_videodbg("VIDIOC_G_FMT: type=%s",
em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
format->type ==
V4L2_BUF_TYPE_VIDEO_CAPTURE ?
"V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
Expand All @@ -1253,7 +1262,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */

em28xx_videodbg("VIDIOC_G_FMT: %dx%d", dev->width,
em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
dev->height);
return 0;
}
Expand All @@ -1274,7 +1283,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,

/* int both_fields; */

em28xx_videodbg("%s: type=%s",
em28xx_videodbg("%s: type=%s\n",
cmd ==
VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
"VIDIOC_S_FMT",
Expand All @@ -1288,7 +1297,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;

em28xx_videodbg("%s: requested %dx%d",
em28xx_videodbg("%s: requested %dx%d\n",
cmd ==
VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
"VIDIOC_S_FMT", format->fmt.pix.width,
Expand Down Expand Up @@ -1347,7 +1356,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
format->fmt.pix.field = V4L2_FIELD_INTERLACED;

em28xx_videodbg("%s: returned %dx%d (%d, %d)",
em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
cmd ==
VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
"VIDIOC_S_FMT", format->fmt.pix.width,
Expand All @@ -1359,13 +1368,13 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
for (i = 0; i < dev->num_frames; i++)
if (dev->frame[i].vma_use_count) {
em28xx_videodbg("VIDIOC_S_FMT failed. "
"Unmap the buffers first.");
"Unmap the buffers first.\n");
return -EINVAL;
}

/* stop io in case it is already in progress */
if (dev->stream == STREAM_ON) {
em28xx_videodbg("VIDIOC_SET_FMT: interupting stream");
em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
if ((ret = em28xx_stream_interrupt(dev)))
return ret;
}
Expand Down Expand Up @@ -1405,18 +1414,18 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
if (dev->io == IO_READ) {
em28xx_videodbg ("method is set to read;"
" close and open the device again to"
" choose the mmap I/O method");
" choose the mmap I/O method\n");
return -EINVAL;
}

for (i = 0; i < dev->num_frames; i++)
if (dev->frame[i].vma_use_count) {
em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped");
em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
return -EINVAL;
}

if (dev->stream == STREAM_ON) {
em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream");
em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
if ((ret = em28xx_stream_interrupt(dev)))
return ret;
}
Expand All @@ -1430,7 +1439,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,

dev->frame_current = NULL;

em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i",
em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
rb->count);
dev->io = rb->count ? IO_MMAP : IO_NONE;
return 0;
Expand Down
Loading

0 comments on commit eac9435

Please sign in to comment.