aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c120
1 files changed, 83 insertions, 37 deletions
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index c8f958151677..ddca21d9c948 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -785,15 +785,15 @@ static const struct v4l2_queryctrl bttv_ctls[] = {
785 785
786 786
787}; 787};
788static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
789 788
790static const struct v4l2_queryctrl *ctrl_by_id(int id) 789static const struct v4l2_queryctrl *ctrl_by_id(int id)
791{ 790{
792 int i; 791 int i;
793 792
794 for (i = 0; i < BTTV_CTLS; i++) 793 for (i = 0; i < ARRAY_SIZE(bttv_ctls); i++)
795 if (bttv_ctls[i].id == id) 794 if (bttv_ctls[i].id == id)
796 return bttv_ctls+i; 795 return bttv_ctls+i;
796
797 return NULL; 797 return NULL;
798} 798}
799 799
@@ -2479,6 +2479,7 @@ static int bttv_try_fmt_cap(struct file *file, void *priv,
2479 struct bttv *btv = fh->btv; 2479 struct bttv *btv = fh->btv;
2480 enum v4l2_field field; 2480 enum v4l2_field field;
2481 __s32 width, height; 2481 __s32 width, height;
2482 int rc;
2482 2483
2483 fmt = format_by_fourcc(f->fmt.pix.pixelformat); 2484 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2484 if (NULL == fmt) 2485 if (NULL == fmt)
@@ -2515,6 +2516,14 @@ static int bttv_try_fmt_cap(struct file *file, void *priv,
2515 width = f->fmt.pix.width; 2516 width = f->fmt.pix.width;
2516 height = f->fmt.pix.height; 2517 height = f->fmt.pix.height;
2517 2518
2519 rc = limit_scaled_size(fh, &width, &height, field,
2520 /* width_mask: 4 pixels */ ~3,
2521 /* width_bias: nearest */ 2,
2522 /* adjust_size */ 1,
2523 /* adjust_crop */ 0);
2524 if (0 != rc)
2525 return rc;
2526
2518 /* update data for the application */ 2527 /* update data for the application */
2519 f->fmt.pix.field = field; 2528 f->fmt.pix.field = field;
2520 pix_format_set_size(&f->fmt.pix, fmt, width, height); 2529 pix_format_set_size(&f->fmt.pix, fmt, width, height);
@@ -2539,6 +2548,8 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
2539 const struct bttv_format *fmt; 2548 const struct bttv_format *fmt;
2540 struct bttv_fh *fh = priv; 2549 struct bttv_fh *fh = priv;
2541 struct bttv *btv = fh->btv; 2550 struct bttv *btv = fh->btv;
2551 __s32 width, height;
2552 enum v4l2_field field;
2542 2553
2543 retval = bttv_switch_type(fh, f->type); 2554 retval = bttv_switch_type(fh, f->type);
2544 if (0 != retval) 2555 if (0 != retval)
@@ -2548,6 +2559,20 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
2548 if (0 != retval) 2559 if (0 != retval)
2549 return retval; 2560 return retval;
2550 2561
2562 width = f->fmt.pix.width;
2563 height = f->fmt.pix.height;
2564 field = f->fmt.pix.field;
2565
2566 retval = limit_scaled_size(fh, &width, &height, f->fmt.pix.field,
2567 /* width_mask: 4 pixels */ ~3,
2568 /* width_bias: nearest */ 2,
2569 /* adjust_size */ 1,
2570 /* adjust_crop */ 1);
2571 if (0 != retval)
2572 return retval;
2573
2574 f->fmt.pix.field = field;
2575
2551 fmt = format_by_fourcc(f->fmt.pix.pixelformat); 2576 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2552 2577
2553 /* update our state informations */ 2578 /* update our state informations */
@@ -2571,8 +2596,10 @@ static int bttv_s_fmt_overlay(struct file *file, void *priv,
2571 struct bttv_fh *fh = priv; 2596 struct bttv_fh *fh = priv;
2572 struct bttv *btv = fh->btv; 2597 struct bttv *btv = fh->btv;
2573 2598
2574 if (no_overlay > 0) 2599 if (no_overlay > 0) {
2600 printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
2575 return -EINVAL; 2601 return -EINVAL;
2602 }
2576 2603
2577 return setup_window(fh, btv, &f->fmt.win, 1); 2604 return setup_window(fh, btv, &f->fmt.win, 1);
2578} 2605}
@@ -2645,15 +2672,32 @@ static int bttv_enum_fmt_vbi(struct file *file, void *priv,
2645 return 0; 2672 return 0;
2646} 2673}
2647 2674
2675static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f)
2676{
2677 int index = -1, i;
2678
2679 for (i = 0; i < FORMATS; i++) {
2680 if (formats[i].fourcc != -1)
2681 index++;
2682 if ((unsigned int)index == f->index)
2683 break;
2684 }
2685 if (FORMATS == i)
2686 return -EINVAL;
2687
2688 f->pixelformat = formats[i].fourcc;
2689 strlcpy(f->description, formats[i].name, sizeof(f->description));
2690
2691 return i;
2692}
2693
2648static int bttv_enum_fmt_cap(struct file *file, void *priv, 2694static int bttv_enum_fmt_cap(struct file *file, void *priv,
2649 struct v4l2_fmtdesc *f) 2695 struct v4l2_fmtdesc *f)
2650{ 2696{
2651 if (f->index >= FORMATS) 2697 int rc = bttv_enum_fmt_cap_ovr(f);
2652 return -EINVAL;
2653 2698
2654 strlcpy(f->description, formats[f->index].name, 2699 if (rc < 0)
2655 sizeof(f->description)); 2700 return rc;
2656 f->pixelformat = formats[f->index].fourcc;
2657 2701
2658 return 0; 2702 return 0;
2659} 2703}
@@ -2661,18 +2705,20 @@ static int bttv_enum_fmt_cap(struct file *file, void *priv,
2661static int bttv_enum_fmt_overlay(struct file *file, void *priv, 2705static int bttv_enum_fmt_overlay(struct file *file, void *priv,
2662 struct v4l2_fmtdesc *f) 2706 struct v4l2_fmtdesc *f)
2663{ 2707{
2708 int rc;
2709
2664 if (no_overlay > 0) { 2710 if (no_overlay > 0) {
2665 printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); 2711 printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
2666 return -EINVAL; 2712 return -EINVAL;
2667 } 2713 }
2668 2714
2669 if (f->index >= FORMATS) 2715 rc = bttv_enum_fmt_cap_ovr(f);
2670 return -EINVAL;
2671 2716
2672 strlcpy(f->description, formats[f->index].name, 2717 if (rc < 0)
2673 sizeof(f->description)); 2718 return rc;
2674 2719
2675 f->pixelformat = formats[f->index].fourcc; 2720 if (!(formats[rc].flags & FORMAT_FLAGS_PACKED))
2721 return -EINVAL;
2676 2722
2677 return 0; 2723 return 0;
2678} 2724}
@@ -2871,12 +2917,13 @@ static int bttv_queryctrl(struct file *file, void *priv,
2871 c->id >= V4L2_CID_PRIVATE_LASTP1)) 2917 c->id >= V4L2_CID_PRIVATE_LASTP1))
2872 return -EINVAL; 2918 return -EINVAL;
2873 2919
2874 ctrl = ctrl_by_id(c->id); 2920 if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME))
2875 *c = (NULL != ctrl) ? *ctrl : no_ctl; 2921 *c = no_ctl;
2922 else {
2923 ctrl = ctrl_by_id(c->id);
2876 2924
2877 if (!btv->volume_gpio && 2925 *c = (NULL != ctrl) ? *ctrl : no_ctl;
2878 (ctrl->id == V4L2_CID_AUDIO_VOLUME)) 2926 }
2879 * c = no_ctl;
2880 2927
2881 return 0; 2928 return 0;
2882} 2929}
@@ -3306,9 +3353,6 @@ static const struct file_operations bttv_fops =
3306 3353
3307static struct video_device bttv_video_template = 3354static struct video_device bttv_video_template =
3308{ 3355{
3309 .name = "UNSET",
3310 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
3311 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
3312 .fops = &bttv_fops, 3356 .fops = &bttv_fops,
3313 .minor = -1, 3357 .minor = -1,
3314 .vidioc_querycap = bttv_querycap, 3358 .vidioc_querycap = bttv_querycap,
@@ -3364,14 +3408,6 @@ static struct video_device bttv_video_template =
3364 .current_norm = V4L2_STD_PAL, 3408 .current_norm = V4L2_STD_PAL,
3365}; 3409};
3366 3410
3367static struct video_device bttv_vbi_template =
3368{
3369 .name = "bt848/878 vbi",
3370 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
3371 .fops = &bttv_fops,
3372 .minor = -1,
3373};
3374
3375/* ----------------------------------------------------------------------- */ 3411/* ----------------------------------------------------------------------- */
3376/* radio interface */ 3412/* radio interface */
3377 3413
@@ -3570,8 +3606,6 @@ static const struct file_operations radio_fops =
3570 3606
3571static struct video_device radio_template = 3607static struct video_device radio_template =
3572{ 3608{
3573 .name = "bt848/878 radio",
3574 .type = VID_TYPE_TUNER,
3575 .fops = &radio_fops, 3609 .fops = &radio_fops,
3576 .minor = -1, 3610 .minor = -1,
3577 .vidioc_querycap = radio_querycap, 3611 .vidioc_querycap = radio_querycap,
@@ -4109,8 +4143,9 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
4109/* initialitation */ 4143/* initialitation */
4110 4144
4111static struct video_device *vdev_init(struct bttv *btv, 4145static struct video_device *vdev_init(struct bttv *btv,
4112 struct video_device *template, 4146 const struct video_device *template,
4113 char *type) 4147 const char *type_name,
4148 const int type)
4114{ 4149{
4115 struct video_device *vfd; 4150 struct video_device *vfd;
4116 4151
@@ -4121,9 +4156,10 @@ static struct video_device *vdev_init(struct bttv *btv,
4121 vfd->minor = -1; 4156 vfd->minor = -1;
4122 vfd->dev = &btv->c.pci->dev; 4157 vfd->dev = &btv->c.pci->dev;
4123 vfd->release = video_device_release; 4158 vfd->release = video_device_release;
4159 vfd->type = type;
4124 snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", 4160 snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
4125 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", 4161 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
4126 type, bttv_tvcards[btv->c.type].name); 4162 type_name, bttv_tvcards[btv->c.type].name);
4127 return vfd; 4163 return vfd;
4128} 4164}
4129 4165
@@ -4155,6 +4191,11 @@ static void bttv_unregister_video(struct bttv *btv)
4155/* register video4linux devices */ 4191/* register video4linux devices */
4156static int __devinit bttv_register_video(struct bttv *btv) 4192static int __devinit bttv_register_video(struct bttv *btv)
4157{ 4193{
4194 int video_type = VID_TYPE_CAPTURE |
4195 VID_TYPE_TUNER |
4196 VID_TYPE_CLIPPING|
4197 VID_TYPE_SCALES;
4198
4158 if (no_overlay <= 0) { 4199 if (no_overlay <= 0) {
4159 bttv_video_template.type |= VID_TYPE_OVERLAY; 4200 bttv_video_template.type |= VID_TYPE_OVERLAY;
4160 } else { 4201 } else {
@@ -4162,7 +4203,9 @@ static int __devinit bttv_register_video(struct bttv *btv)
4162 } 4203 }
4163 4204
4164 /* video */ 4205 /* video */
4165 btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); 4206 btv->video_dev = vdev_init(btv, &bttv_video_template,
4207 "video", video_type);
4208
4166 if (NULL == btv->video_dev) 4209 if (NULL == btv->video_dev)
4167 goto err; 4210 goto err;
4168 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) 4211 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
@@ -4177,7 +4220,9 @@ static int __devinit bttv_register_video(struct bttv *btv)
4177 } 4220 }
4178 4221
4179 /* vbi */ 4222 /* vbi */
4180 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); 4223 btv->vbi_dev = vdev_init(btv, &bttv_video_template,
4224 "vbi", VID_TYPE_TUNER | VID_TYPE_TELETEXT);
4225
4181 if (NULL == btv->vbi_dev) 4226 if (NULL == btv->vbi_dev)
4182 goto err; 4227 goto err;
4183 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 4228 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
@@ -4188,7 +4233,8 @@ static int __devinit bttv_register_video(struct bttv *btv)
4188 if (!btv->has_radio) 4233 if (!btv->has_radio)
4189 return 0; 4234 return 0;
4190 /* radio */ 4235 /* radio */
4191 btv->radio_dev = vdev_init(btv, &radio_template, "radio"); 4236 btv->radio_dev = vdev_init(btv, &radio_template,
4237 "radio", VID_TYPE_TUNER);
4192 if (NULL == btv->radio_dev) 4238 if (NULL == btv->radio_dev)
4193 goto err; 4239 goto err;
4194 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) 4240 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)