diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-12-27 23:28:31 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-12-27 23:28:31 -0200 |
commit | ea98723e247ccdf7c17c187994dc18296824e569 (patch) | |
tree | 902d55b0c38719cfd71d27d05d2d169760d56530 /linux/drivers/media/video/bt8xx/bttv-driver.c | |
parent | 333c1bfb02df3597ca136e4bf0b05d29c8a4e000 (diff) | |
download | mediapointer-dvb-s2-ea98723e247ccdf7c17c187994dc18296824e569.tar.gz mediapointer-dvb-s2-ea98723e247ccdf7c17c187994dc18296824e569.tar.bz2 |
Fix a few issues at the bttv conversion
From: Mauro Carvalho Chehab <mchehab@infradead.org>
bttv driver is working as previously. An additional gain of about 1,5Kb were
obtained with the driver conversion to vidioc_ioctl2:
text data bss dec hex filename
89208 40244 57556 187008 2da80 old/bttv.ko
88960 38740 57556 185256 2d3a8 new/bttv.ko
(measured on a x86_64)
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/bt8xx/bttv-driver.c')
-rw-r--r-- | linux/drivers/media/video/bt8xx/bttv-driver.c | 120 |
1 files changed, 83 insertions, 37 deletions
diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 13be3c44a..6d542b1b0 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -814,15 +814,15 @@ static const struct v4l2_queryctrl bttv_ctls[] = { }; -static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); static const struct v4l2_queryctrl *ctrl_by_id(int id) { int i; - for (i = 0; i < BTTV_CTLS; i++) + for (i = 0; i < ARRAY_SIZE(bttv_ctls); i++) if (bttv_ctls[i].id == id) return bttv_ctls+i; + return NULL; } @@ -2520,6 +2520,7 @@ static int bttv_try_fmt_cap(struct file *file, void *priv, struct bttv *btv = fh->btv; enum v4l2_field field; __s32 width, height; + int rc; fmt = format_by_fourcc(f->fmt.pix.pixelformat); if (NULL == fmt) @@ -2556,6 +2557,14 @@ static int bttv_try_fmt_cap(struct file *file, void *priv, width = f->fmt.pix.width; height = f->fmt.pix.height; + rc = limit_scaled_size(fh, &width, &height, field, + /* width_mask: 4 pixels */ ~3, + /* width_bias: nearest */ 2, + /* adjust_size */ 1, + /* adjust_crop */ 0); + if (0 != rc) + return rc; + /* update data for the application */ f->fmt.pix.field = field; pix_format_set_size(&f->fmt.pix, fmt, width, height); @@ -2580,6 +2589,8 @@ static int bttv_s_fmt_cap(struct file *file, void *priv, const struct bttv_format *fmt; struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; + __s32 width, height; + enum v4l2_field field; retval = bttv_switch_type(fh, f->type); if (0 != retval) @@ -2589,6 +2600,20 @@ static int bttv_s_fmt_cap(struct file *file, void *priv, if (0 != retval) return retval; + width = f->fmt.pix.width; + height = f->fmt.pix.height; + field = f->fmt.pix.field; + + retval = limit_scaled_size(fh, &width, &height, f->fmt.pix.field, + /* width_mask: 4 pixels */ ~3, + /* width_bias: nearest */ 2, + /* adjust_size */ 1, + /* adjust_crop */ 1); + if (0 != retval) + return retval; + + f->fmt.pix.field = field; + fmt = format_by_fourcc(f->fmt.pix.pixelformat); /* update our state informations */ @@ -2612,8 +2637,10 @@ static int bttv_s_fmt_overlay(struct file *file, void *priv, struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - if (no_overlay > 0) + if (no_overlay > 0) { + printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; + } return setup_window(fh, btv, &f->fmt.win, 1); } @@ -2686,15 +2713,32 @@ static int bttv_enum_fmt_vbi(struct file *file, void *priv, return 0; } +static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f) +{ + int index = -1, i; + + for (i = 0; i < FORMATS; i++) { + if (formats[i].fourcc != -1) + index++; + if ((unsigned int)index == f->index) + break; + } + if (FORMATS == i) + return -EINVAL; + + f->pixelformat = formats[i].fourcc; + strlcpy(f->description, formats[i].name, sizeof(f->description)); + + return i; +} + static int bttv_enum_fmt_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - if (f->index >= FORMATS) - return -EINVAL; + int rc = bttv_enum_fmt_cap_ovr(f); - strlcpy(f->description, formats[f->index].name, - sizeof(f->description)); - f->pixelformat = formats[f->index].fourcc; + if (rc < 0) + return rc; return 0; } @@ -2702,18 +2746,20 @@ static int bttv_enum_fmt_cap(struct file *file, void *priv, static int bttv_enum_fmt_overlay(struct file *file, void *priv, struct v4l2_fmtdesc *f) { + int rc; + if (no_overlay > 0) { printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; } - if (f->index >= FORMATS) - return -EINVAL; + rc = bttv_enum_fmt_cap_ovr(f); - strlcpy(f->description, formats[f->index].name, - sizeof(f->description)); + if (rc < 0) + return rc; - f->pixelformat = formats[f->index].fourcc; + if (!(formats[rc].flags & FORMAT_FLAGS_PACKED)) + return -EINVAL; return 0; } @@ -2912,12 +2958,13 @@ static int bttv_queryctrl(struct file *file, void *priv, c->id >= V4L2_CID_PRIVATE_LASTP1)) return -EINVAL; - ctrl = ctrl_by_id(c->id); - *c = (NULL != ctrl) ? *ctrl : no_ctl; + if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) + *c = no_ctl; + else { + ctrl = ctrl_by_id(c->id); - if (!btv->volume_gpio && - (ctrl->id == V4L2_CID_AUDIO_VOLUME)) - * c = no_ctl; + *c = (NULL != ctrl) ? *ctrl : no_ctl; + } return 0; } @@ -3349,9 +3396,6 @@ static const struct file_operations bttv_fops = static struct video_device bttv_video_template = { - .name = "UNSET", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| - VID_TYPE_CLIPPING|VID_TYPE_SCALES, .fops = &bttv_fops, .minor = -1, .vidioc_querycap = bttv_querycap, @@ -3407,14 +3451,6 @@ static struct video_device bttv_video_template = .current_norm = V4L2_STD_PAL, }; -static struct video_device bttv_vbi_template = -{ - .name = "bt848/878 vbi", - .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT, - .fops = &bttv_fops, - .minor = -1, -}; - /* ----------------------------------------------------------------------- */ /* radio interface */ @@ -3613,8 +3649,6 @@ static const struct file_operations radio_fops = static struct video_device radio_template = { - .name = "bt848/878 radio", - .type = VID_TYPE_TUNER, .fops = &radio_fops, .minor = -1, .vidioc_querycap = radio_querycap, @@ -4160,8 +4194,9 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) /* initialitation */ static struct video_device *vdev_init(struct bttv *btv, - struct video_device *template, - char *type) + const struct video_device *template, + const char *type_name, + const int type) { struct video_device *vfd; @@ -4174,9 +4209,10 @@ static struct video_device *vdev_init(struct bttv *btv, vfd->dev = &btv->c.pci->dev; vfd->release = video_device_release; #endif + vfd->type = type; snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", - type, bttv_tvcards[btv->c.type].name); + type_name, bttv_tvcards[btv->c.type].name); return vfd; } @@ -4208,6 +4244,11 @@ static void bttv_unregister_video(struct bttv *btv) /* register video4linux devices */ static int __devinit bttv_register_video(struct bttv *btv) { + int video_type = VID_TYPE_CAPTURE | + VID_TYPE_TUNER | + VID_TYPE_CLIPPING| + VID_TYPE_SCALES; + if (no_overlay <= 0) { bttv_video_template.type |= VID_TYPE_OVERLAY; } else { @@ -4215,7 +4256,9 @@ static int __devinit bttv_register_video(struct bttv *btv) } /* video */ - btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); + btv->video_dev = vdev_init(btv, &bttv_video_template, + "video", video_type); + if (NULL == btv->video_dev) goto err; if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) @@ -4230,7 +4273,9 @@ static int __devinit bttv_register_video(struct bttv *btv) } /* vbi */ - btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); + btv->vbi_dev = vdev_init(btv, &bttv_video_template, + "vbi", VID_TYPE_TUNER | VID_TYPE_TELETEXT); + if (NULL == btv->vbi_dev) goto err; if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) @@ -4241,7 +4286,8 @@ static int __devinit bttv_register_video(struct bttv *btv) if (!btv->has_radio) return 0; /* radio */ - btv->radio_dev = vdev_init(btv, &radio_template, "radio"); + btv->radio_dev = vdev_init(btv, &radio_template, + "radio", VID_TYPE_TUNER); if (NULL == btv->radio_dev) goto err; if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) |