extractedLnx/linux-2.5.7/drivers/media/video/bttv-driver.c_bttv_ioctl.c
static int bttv_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
struct bttv_fh *fh = file->private_data;
struct bttv *btv = fh->btv;
int retval;
if (bttv_debug > 1) {
switch (_IOC_TYPE(cmd)) {
case 'v':
printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n",
btv->nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
v4l1_ioctls[_IOC_NR(cmd)] : "???");
break;
case 'V':
printk("bttv%d: ioctl 0x%x (v4l2, VIDIOC_%s)\n",
btv->nr, cmd, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
v4l2_ioctls[_IOC_NR(cmd)] : "???");
break;
default:
printk("bttv%d: ioctl 0x%x (???)\n",
btv->nr, cmd);
}
}
if (btv->errors)
bttv_reinit_bt848(btv);
switch (cmd) {
/* *** v4l1 *** ************************************************ */
case VIDIOCGCAP:
{
struct video_capability *cap = arg;
memset(cap,0,sizeof(*cap));
strcpy(cap->name,btv->video_dev.name);
cap->type = VID_TYPE_CAPTURE|
VID_TYPE_TUNER|
VID_TYPE_OVERLAY|
VID_TYPE_CLIPPING|
VID_TYPE_SCALES;
cap->channels = bttv_tvcards[btv->type].video_inputs;
cap->audios = bttv_tvcards[btv->type].audio_inputs;
cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
cap->minwidth = 48;
cap->minheight = 32;
return 0;
}
case VIDIOCGPICT:
{
struct video_picture *pic = arg;
memset(pic,0,sizeof(*pic));
pic->brightness = btv->bright;
pic->contrast = btv->contrast;
pic->hue = btv->hue;
pic->colour = btv->saturation;
if (fh->buf.fmt) {
pic->depth = fh->buf.fmt->depth;
pic->palette = fh->buf.fmt->palette;
}
return 0;
}
case VIDIOCSPICT:
{
struct video_picture *pic = arg;
const struct bttv_format *fmt;
fmt = format_by_palette(pic->palette);
if (NULL == fmt)
return -EINVAL;
down(&fh->lock);
retval = -EINVAL;
if (fmt->depth != pic->depth && !sloppy)
goto fh_unlock_and_return;
fh->ovfmt = fmt;
fh->buf.fmt = fmt;
btv->init.ovfmt = fmt;
btv->init.buf.fmt = fmt;
if (bigendian) {
/* dirty hack time: swap bytes for overlay if the
display adaptor is big endian (insmod option) */
if (fmt->palette == VIDEO_PALETTE_RGB555 ||
fmt->palette == VIDEO_PALETTE_RGB565 ||
fmt->palette == VIDEO_PALETTE_RGB32) {
fh->ovfmt = fmt+1;
}
}
bt848_bright(btv,pic->brightness);
bt848_contrast(btv,pic->contrast);
bt848_hue(btv,pic->hue);
bt848_sat(btv,pic->colour);
up(&fh->lock);
return 0;
}
case VIDIOCGWIN:
{
struct video_window *win = arg;
memset(win,0,sizeof(*win));
win->x = fh->ov.x;
win->y = fh->ov.y;
win->width = fh->ov.width;
win->height = fh->ov.height;
return 0;
}
case VIDIOCSWIN:
{
struct video_window *win = arg;
retval = setup_window(fh,btv,win->x,win->y,
win->width,win->height,
win->clips,
win->clipcount);
if (0 == retval) {
/* on v4l1 this ioctl affects the read() size too */
fh->buf.vb.width = fh->ov.width;
fh->buf.vb.height = fh->ov.height;
btv->init.buf.vb.width = fh->ov.width;
btv->init.buf.vb.height = fh->ov.height;
}
return retval;
}
case VIDIOCGFBUF:
{
struct video_buffer *fbuf = arg;
*fbuf = btv->fbuf;
return 0;
}
case VIDIOCSFBUF:
{
struct video_buffer *fbuf = arg;
const struct bttv_format *fmt;
unsigned long end;
if(!capable(CAP_SYS_ADMIN) &&
!capable(CAP_SYS_RAWIO))
return -EPERM;
end = (unsigned long)fbuf->base +
fbuf->height * fbuf->bytesperline;
if (0 == find_videomem((unsigned long)fbuf->base,end))
return -EINVAL;
down(&fh->lock);
retval = -EINVAL;
if (sloppy) {
/* also set the default palette -- for backward
compatibility with older versions */
switch (fbuf->depth) {
case 8:
fmt = format_by_palette(VIDEO_PALETTE_HI240);
break;
case 16:
fmt = format_by_palette(VIDEO_PALETTE_RGB565);
break;
case 24:
fmt = format_by_palette(VIDEO_PALETTE_RGB24);
break;
case 32:
fmt = format_by_palette(VIDEO_PALETTE_RGB32);
break;
case 15:
fbuf->depth = 16;
fmt = format_by_palette(VIDEO_PALETTE_RGB555);
break;
default:
fmt = NULL;
break;
}
if (NULL == fmt)
goto fh_unlock_and_return;
fh->ovfmt = fmt;
fh->buf.fmt = fmt;
btv->init.ovfmt = fmt;
btv->init.buf.fmt = fmt;
} else {
if (15 == fbuf->depth)
fbuf->depth = 16;
if (fbuf->depth != 8 && fbuf->depth != 16 &&
fbuf->depth != 24 && fbuf->depth != 32)
goto fh_unlock_and_return;
}
btv->fbuf = *fbuf;
up(&fh->lock);
return 0;
}
case VIDIOCCAPTURE:
#ifdef HAVE_V4L2
case VIDIOC_PREVIEW:
#endif
{
struct bttv_buffer *new;
int *on = arg;
if (*on) {
/* verify args */
if (NULL == btv->fbuf.base)
return -EINVAL;
if (fh->ov.width <48 ||
fh->ov.height<32 ||
fh->ov.width >bttv_tvnorms[btv->tvnorm].swidth ||
fh->ov.height>bttv_tvnorms[btv->tvnorm].sheight ||
NULL == fh->ovfmt)
return -EINVAL;
}
if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
return -EBUSY;
down(&fh->lock);
if (*on) {
fh->ov.tvnorm = btv->tvnorm;
new = videobuf_alloc(sizeof(*new),
V4L2_BUF_TYPE_CAPTURE);
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
} else {
new = NULL;
}
/* switch over */
retval = bttv_switch_overlay(btv,fh,new);
up(&fh->lock);
return retval;
}
case VIDIOCGMBUF:
{
struct video_mbuf *mbuf = arg;
int i;
if (!mmap)
return -EINVAL;
down(&fh->lock);
retval = videobuf_mmap_setup
(file,(struct videobuf_buffer**)fh->bufs,
sizeof(struct bttv_buffer),
gbuffers,gbufsize,V4L2_BUF_TYPE_CAPTURE,
release_buffer);
if (retval < 0)
goto fh_unlock_and_return;
memset(mbuf,0,sizeof(*mbuf));
mbuf->frames = gbuffers;
mbuf->size = gbuffers * gbufsize;
for (i = 0; i < gbuffers; i++)
mbuf->offsets[i] = i * gbufsize;
up(&fh->lock);
return 0;
}
case VIDIOCMCAPTURE:
{
struct video_mmap *vm = arg;
struct bttv_buffer *buf;
if (vm->frame >= VIDEO_MAX_FRAME)
return -EINVAL;
down(&fh->lock);
retval = -EINVAL;
buf = fh->bufs[vm->frame];
if (NULL == buf)
goto fh_unlock_and_return;
if (0 == buf->vb.baddr)
goto fh_unlock_and_return;
if (buf->vb.state == STATE_QUEUED ||
buf->vb.state == STATE_ACTIVE)
goto fh_unlock_and_return;
retval = bttv_prepare_buffer(btv,buf,
format_by_palette(vm->format),
vm->width,vm->height,0);
if (0 != retval)
goto fh_unlock_and_return;
bttv_queue_buffer(btv,buf);
up(&fh->lock);
return 0;
}
case VIDIOCSYNC:
{
int *frame = arg;
struct bttv_buffer *buf;
if (*frame >= VIDEO_MAX_FRAME)
return -EINVAL;
down(&fh->lock);
retval = -EINVAL;
buf = fh->bufs[*frame];
if (NULL == buf)
goto fh_unlock_and_return;
retval = videobuf_waiton(&buf->vb,0,1);
if (0 != retval)
goto fh_unlock_and_return;
switch (buf->vb.state) {
case STATE_ERROR:
retval = -EIO;
/* fall through */
case STATE_DONE:
videobuf_dma_pci_sync(btv->dev,&buf->vb.dma);
bttv_dma_free(btv,buf);
break;
default:
retval = -EINVAL;
break;
}
up(&fh->lock);
return retval;
}
case BTTV_VERSION:
case VIDIOCGFREQ:
case VIDIOCSFREQ:
case VIDIOCGTUNER:
case VIDIOCSTUNER:
case VIDIOCGCHAN:
case VIDIOCSCHAN:
case VIDIOCGAUDIO:
case VIDIOCSAUDIO:
return bttv_common_ioctls(btv,cmd,arg);
#ifdef HAVE_V4L2
/* *** v4l2 *** ************************************************ */
case VIDIOC_QUERYCAP:
{
struct v4l2_capability *cap = arg;
if (0 == v4l2)
return -EINVAL;
strcpy(cap->name,btv->video_dev.name);
cap->type = V4L2_TYPE_CAPTURE;
cap->flags = V4L2_FLAG_TUNER | V4L2_FLAG_PREVIEW
| V4L2_FLAG_READ | V4L2_FLAG_SELECT;
if (mmap)
cap->flags |= V4L2_FLAG_STREAMING;
cap->inputs = bttv_tvcards[btv->type].video_inputs;
cap->outputs = 0;
cap->audios = bttv_tvcards[btv->type].audio_inputs;
cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
cap->minwidth = 48;
cap->minheight = 32;
cap->maxframerate = 30;
return 0;
}
case VIDIOC_ENUM_PIXFMT:
case VIDIOC_ENUM_FBUFFMT:
{
struct v4l2_fmtdesc *f = arg;
int i, index;
index = -1;
for (i = 0; i < BTTV_FORMATS; i++) {
if (bttv_formats[i].fourcc != -1)
index++;
if (index == f->index)
break;
}
if (BTTV_FORMATS == i)
return -EINVAL;
if (cmd == VIDIOC_ENUM_FBUFFMT &&
0 == (bttv_formats[i].flags & FORMAT_FLAGS_PACKED))
return -EINVAL;
memset(f,0,sizeof(*f));
f->index = index;
strncpy(f->description,bttv_formats[i].name,31);
f->pixelformat = bttv_formats[i].fourcc;
f->depth = bttv_formats[i].depth;
return 0;
}
case VIDIOC_G_FMT:
{
struct v4l2_format *f = arg;
memset(f,0,sizeof(*f));
f->type = V4L2_BUF_TYPE_CAPTURE;
f->fmt.pix.width = fh->buf.vb.width;
f->fmt.pix.height = fh->buf.vb.height;
f->fmt.pix.depth = fh->buf.fmt->depth;
f->fmt.pix.pixelformat = fh->buf.fmt->fourcc;
f->fmt.pix.sizeimage =
(fh->buf.vb.width*fh->buf.vb.height*fh->buf.fmt->depth)/8;
return 0;
}
case VIDIOC_S_FMT:
{
struct v4l2_format *f = arg;
const struct bttv_format *fmt;
if ((f->type & V4L2_BUF_TYPE_field) != V4L2_BUF_TYPE_CAPTURE)
return -EINVAL;
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
if (NULL == fmt)
return -EINVAL;
if (f->fmt.pix.width < 48 ||
f->fmt.pix.height < 32)
return -EINVAL;
if (f->fmt.pix.flags & V4L2_FMT_FLAG_BYTESPERLINE)
/* FIXME -- not implemented yet */
return -EINVAL;
down(&fh->lock);
/* fixup format */
if (f->fmt.pix.width > bttv_tvnorms[btv->tvnorm].swidth)
f->fmt.pix.width = bttv_tvnorms[btv->tvnorm].swidth;
if (f->fmt.pix.height > bttv_tvnorms[btv->tvnorm].sheight)
f->fmt.pix.height = bttv_tvnorms[btv->tvnorm].sheight;
if (!(f->fmt.pix.flags & V4L2_FMT_FLAG_INTERLACED) &&
f->fmt.pix.height>bttv_tvnorms[btv->tvnorm].sheight/2)
f->fmt.pix.height=bttv_tvnorms[btv->tvnorm].sheight/2;
if (f->fmt.pix.height > bttv_tvnorms[btv->tvnorm].sheight/2) {
/* must interlace -- no field splitting available */
f->fmt.pix.flags &= ~(V4L2_FMT_FLAG_TOPFIELD|
V4L2_FMT_FLAG_BOTFIELD);
} else {
/* one field is enouth -- no interlace needed */
f->fmt.pix.flags &= ~V4L2_FMT_FLAG_INTERLACED;
}
/* update our state informations */
fh->buf.fmt = fmt;
fh->buf.vb.width = f->fmt.pix.width;
fh->buf.vb.height = f->fmt.pix.height;
btv->init.buf.fmt = fmt;
btv->init.buf.vb.width = f->fmt.pix.width;
btv->init.buf.vb.height = f->fmt.pix.height;
/* update data for the application */
f->fmt.pix.depth = fmt->depth;
f->fmt.pix.sizeimage =
(fh->buf.vb.width * fh->buf.vb.height * fmt->depth)/8;
up(&fh->lock);
return 0;
}
case VIDIOC_G_FBUF:
{
struct v4l2_framebuffer *fb = arg;
memset(fb,0,sizeof(*fb));
fb->base[0] = btv->fbuf.base;
fb->fmt.width = btv->fbuf.width;
fb->fmt.height = btv->fbuf.height;
fb->fmt.bytesperline = btv->fbuf.bytesperline;
fb->fmt.flags = V4L2_FMT_FLAG_BYTESPERLINE;
fb->capability = V4L2_FBUF_CAP_CLIPPING;
if (fh->ovfmt) {
fb->fmt.depth = fh->ovfmt->depth;
fb->fmt.pixelformat = fh->ovfmt->fourcc;
}
return 0;
}
case VIDIOC_S_FBUF:
{
struct v4l2_framebuffer *fb = arg;
const struct bttv_format *fmt;
unsigned long end;
if(!capable(CAP_SYS_ADMIN) &&
!capable(CAP_SYS_RAWIO))
return -EPERM;
/* check args */
end = (unsigned long)fb->base[0] +
fb->fmt.height * fb->fmt.bytesperline;
if (0 == find_videomem((unsigned long)fb->base[0],end))
return -EINVAL;
fmt = format_by_fourcc(fb->fmt.pixelformat);
if (NULL == fmt)
return -EINVAL;
if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
return -EINVAL;
down(&fh->lock);
retval = -EINVAL;
if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
goto fh_unlock_and_return;
if (fb->fmt.height > bttv_tvnorms[btv->tvnorm].sheight)
goto fh_unlock_and_return;
}
/* ok, accept it */
btv->fbuf.base = fb->base[0];
btv->fbuf.width = fb->fmt.width;
btv->fbuf.height = fb->fmt.height;
btv->fbuf.depth = fmt->depth;
if (fb->fmt.flags & V4L2_FMT_FLAG_BYTESPERLINE)
btv->fbuf.bytesperline = fb->fmt.bytesperline;
else
btv->fbuf.bytesperline = btv->fbuf.width*fmt->depth/8;
retval = 0;
fh->ovfmt = fmt;
btv->init.ovfmt = fmt;
if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
fh->ov.x = 0;
fh->ov.y = 0;
fh->ov.width = fb->fmt.width;
fh->ov.height = fb->fmt.height;
btv->init.ov.width = fb->fmt.width;
btv->init.ov.height = fb->fmt.height;
if (fh->ov.clips)
kfree(fh->ov.clips);
fh->ov.clips = NULL;
fh->ov.nclips = 0;
if (check_btres(fh, RESOURCE_OVERLAY)) {
struct bttv_buffer *new;
new = videobuf_alloc(sizeof(*new),
V4L2_BUF_TYPE_CAPTURE);
bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new);
retval = bttv_switch_overlay(btv,fh,new);
}
}
up(&fh->lock);
return retval;
}
case VIDIOC_G_WIN:
{
struct v4l2_window *win = arg;
memset(win,0,sizeof(*win));
win->x = fh->ov.x;
win->y = fh->ov.y;
win->width = fh->ov.width;
win->height = fh->ov.height;
return 0;
}
case VIDIOC_S_WIN:
{
struct v4l2_window *win = arg;
return setup_window(fh,btv,win->x,win->y,
win->width,win->height,
(struct video_clip*)win->clips,
win->clipcount);
}
case VIDIOC_REQBUFS:
{
struct v4l2_requestbuffers *req = arg;
int size,count;
if (!mmap)
return -EINVAL;
if ((req->type & V4L2_BUF_TYPE_field) != V4L2_BUF_TYPE_CAPTURE)
return -EINVAL;
if (req->count < 0)
return -EINVAL;
down(&fh->lock);
retval = -EINVAL;
if (NULL == fh->buf.fmt ||
0 == fh->buf.vb.width ||
0 == fh->buf.vb.height)
goto fh_unlock_and_return;
size = (fh->buf.vb.width*fh->buf.vb.height*fh->buf.fmt->depth) >> 3;
size = (size + PAGE_SIZE - 1) & PAGE_MASK;
count = req->count;
if (count > VIDEO_MAX_FRAME)
count = VIDEO_MAX_FRAME;
while (size * count > gbuffers * gbufsize)
count--;
retval = videobuf_mmap_setup(file,
(struct videobuf_buffer**)fh->bufs,
sizeof(struct bttv_buffer),
count,size,V4L2_BUF_TYPE_CAPTURE,
release_buffer);
if (retval < 0)
goto fh_unlock_and_return;
req->type = V4L2_BUF_TYPE_CAPTURE;
req->count = count;
up(&fh->lock);
return 0;
}
case VIDIOC_QUERYBUF:
{
struct v4l2_buffer *b = arg;
if ((b->type & V4L2_BUF_TYPE_field) != V4L2_BUF_TYPE_CAPTURE)
return -EINVAL;
if (b->index < 0 || b->index > VIDEO_MAX_FRAME)
return -EINVAL;
if (NULL == fh->bufs[b->index])
return -EINVAL;
videobuf_status(b,&fh->bufs[b->index]->vb);
return 0;
}
case VIDIOC_QBUF:
{
struct v4l2_buffer *b = arg;
struct bttv_buffer *buf;
int field = 0;
if ((b->type & V4L2_BUF_TYPE_field) != V4L2_BUF_TYPE_CAPTURE)
return -EINVAL;
if (b->index < 0 || b->index > VIDEO_MAX_FRAME)
return -EINVAL;
down(&fh->lock);
retval = -EINVAL;
buf = fh->bufs[b->index];
if (NULL == buf)
goto fh_unlock_and_return;
if (0 == buf->vb.baddr)
goto fh_unlock_and_return;
if (buf->vb.state == STATE_QUEUED ||
buf->vb.state == STATE_ACTIVE)
goto fh_unlock_and_return;
if (b->flags & V4L2_BUF_FLAG_TOPFIELD)
field |= VBUF_FIELD_ODD;
if (b->flags & V4L2_BUF_FLAG_BOTFIELD)
field |= VBUF_FIELD_EVEN;
retval = bttv_prepare_buffer(btv,buf,fh->buf.fmt,
fh->buf.vb.width,fh->buf.vb.height,field);
if (0 != retval)
goto fh_unlock_and_return;
list_add_tail(&buf->vb.stream,&fh->stream);
if (check_btres(fh, RESOURCE_STREAMING))
bttv_queue_buffer(btv,buf);
up(&fh->lock);
return 0;
}
case VIDIOC_DQBUF:
{
struct v4l2_buffer *b = arg;
struct bttv_buffer *buf;
if ((b->type & V4L2_BUF_TYPE_field) != V4L2_BUF_TYPE_CAPTURE)
return -EINVAL;
down(&fh->lock);
retval = -EINVAL;
if (list_empty(&fh->stream))
goto fh_unlock_and_return;
buf = list_entry(fh->stream.next, struct bttv_buffer, vb.stream);
retval = videobuf_waiton(&buf->vb,0,1);
if (retval < 0)
goto fh_unlock_and_return;
switch (buf->vb.state) {
case STATE_ERROR:
retval = -EIO;
/* fall through */
case STATE_DONE:
videobuf_dma_pci_sync(btv->dev,&buf->vb.dma);
buf->vb.state = STATE_IDLE;
break;
default:
retval = -EINVAL;
goto fh_unlock_and_return;
}
list_del(&buf->vb.stream);
memset(b,0,sizeof(*b));
videobuf_status(b,&buf->vb);
up(&fh->lock);
return retval;
}
case VIDIOC_STREAMON:
{
struct list_head *list;
struct bttv_buffer *buf;
if (!check_alloc_btres(btv,fh,RESOURCE_STREAMING))
return -EBUSY;
bttv_field_count(btv);
down(&fh->lock);
list_for_each(list,&fh->stream) {
buf = list_entry(list, struct bttv_buffer, vb.stream);
if (buf->vb.state == STATE_PREPARED)
bttv_queue_buffer(btv,buf);
}
up(&fh->lock);
return 0;
}
case VIDIOC_STREAMOFF:
{
down(&fh->lock);
retval = -EINVAL;
if (!check_btres(fh, RESOURCE_STREAMING))
goto fh_unlock_and_return;
bttv_stop_streaming(btv,fh);
up(&fh->lock);
return 0;
}
case VIDIOC_QUERYCTRL:
{
struct v4l2_queryctrl *c = arg;
int i;
v4l2_fill_ctrl_category(c);
if ((c->id < V4L2_CID_BASE ||
c->id >= V4L2_CID_LASTP1) &&
(c->id < V4L2_CID_PRIVATE_BASE ||
c->id >= V4L2_CID_PRIVATE_LASTP1))
return -EINVAL;
for (i = 0; i < BTTV_CTLS; i++)
if (bttv_ctls[i].id == c->id)
break;
if (i == BTTV_CTLS) {
*c = no_ctl;
return 0;
}
*c = bttv_ctls[i];
if (bttv_ctls[i].category == V4L2_CTRL_CAT_AUDIO) {
struct video_audio va;
memset(&va,0,sizeof(va));
bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
if (bttv_tvcards[btv->type].audio_hook)
bttv_tvcards[btv->type].audio_hook(btv,&va,0);
switch (bttv_ctls[i].id) {
case V4L2_CID_AUDIO_VOLUME:
if (!(va.flags & VIDEO_AUDIO_VOLUME))
*c = no_ctl;
break;
case V4L2_CID_AUDIO_BALANCE:
if (!(va.flags & VIDEO_AUDIO_BALANCE))
*c = no_ctl;
break;
case V4L2_CID_AUDIO_BASS:
if (!(va.flags & VIDEO_AUDIO_BASS))
*c = no_ctl;
break;
case V4L2_CID_AUDIO_TREBLE:
if (!(va.flags & VIDEO_AUDIO_TREBLE))
*c = no_ctl;
break;
}
}
return 0;
}
case VIDIOC_G_CTRL:
return get_control(btv,arg);
case VIDIOC_S_CTRL:
return set_control(btv,arg);
case VIDIOC_G_PARM:
{
struct v4l2_streamparm *parm = arg;
struct v4l2_standard s;
if (parm->type != V4L2_BUF_TYPE_CAPTURE)
return -EINVAL;
memset(parm,0,sizeof(*parm));
v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id, 0);
parm->parm.capture.timeperframe = v4l2_video_std_tpf(&s);
return 0;
}
case VIDIOC_ENUMSTD:
case VIDIOC_G_STD:
case VIDIOC_S_STD:
case VIDIOC_ENUMINPUT:
case VIDIOC_G_INPUT:
case VIDIOC_S_INPUT:
case VIDIOC_G_TUNER:
case VIDIOC_S_TUNER:
case VIDIOC_G_FREQ:
case VIDIOC_S_FREQ:
return bttv_common_ioctls(btv,cmd,arg);
#endif /* HAVE_V4L2 */
default:
return -ENOIOCTLCMD;
}
return 0;
fh_unlock_and_return:
up(&fh->lock);
return retval;
}
Generated by GNU enscript 1.6.4.