Commit f33e9868 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] cx88: fix a number of v4l2-compliance violations

- missing COMPRESSED flag for MPEG formats
- set colorspace
- set sizeimage
- add tuner index checks
- setup the frequency ranges correctly
- add missing g_chip_ident ioctl
- fix audmode handling
- don't handle vbi formats on a video node and vice versa.

cx88 now passes the v4l2-compliance tests.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 1a3c60a0
...@@ -709,6 +709,7 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, ...@@ -709,6 +709,7 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
strlcpy(f->description, "MPEG", sizeof(f->description)); strlcpy(f->description, "MPEG", sizeof(f->description));
f->pixelformat = V4L2_PIX_FMT_MPEG; f->pixelformat = V4L2_PIX_FMT_MPEG;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
return 0; return 0;
} }
...@@ -720,8 +721,8 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, ...@@ -720,8 +721,8 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0; f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */ f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
f->fmt.pix.colorspace = 0; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.width = dev->width; f->fmt.pix.width = dev->width;
f->fmt.pix.height = dev->height; f->fmt.pix.height = dev->height;
f->fmt.pix.field = fh->mpegq.field; f->fmt.pix.field = fh->mpegq.field;
...@@ -738,8 +739,8 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, ...@@ -738,8 +739,8 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0; f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
f->fmt.pix.colorspace = 0; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
dev->width, dev->height, fh->mpegq.field ); dev->width, dev->height, fh->mpegq.field );
return 0; return 0;
...@@ -754,8 +755,8 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, ...@@ -754,8 +755,8 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0; f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
f->fmt.pix.colorspace = 0; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
dev->width = f->fmt.pix.width; dev->width = f->fmt.pix.width;
dev->height = f->fmt.pix.height; dev->height = f->fmt.pix.height;
fh->mpegq.field = f->fmt.pix.field; fh->mpegq.field = f->fmt.pix.field;
...@@ -819,6 +820,10 @@ static int vidioc_s_frequency (struct file *file, void *priv, ...@@ -819,6 +820,10 @@ static int vidioc_s_frequency (struct file *file, void *priv,
struct cx8802_dev *dev = fh->dev; struct cx8802_dev *dev = fh->dev;
struct cx88_core *core = dev->core; struct cx88_core *core = dev->core;
if (unlikely(UNSET == core->board.tuner_type))
return -EINVAL;
if (unlikely(f->tuner != 0))
return -EINVAL;
if (dev->mpeg_active) if (dev->mpeg_active)
blackbird_stop_codec(dev); blackbird_stop_codec(dev);
...@@ -856,8 +861,9 @@ static int vidioc_g_frequency (struct file *file, void *priv, ...@@ -856,8 +861,9 @@ static int vidioc_g_frequency (struct file *file, void *priv,
if (unlikely(UNSET == core->board.tuner_type)) if (unlikely(UNSET == core->board.tuner_type))
return -EINVAL; return -EINVAL;
if (unlikely(f->tuner != 0))
return -EINVAL;
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = core->freq; f->frequency = core->freq;
call_all(core, tuner, g_frequency, f); call_all(core, tuner, g_frequency, f);
...@@ -878,6 +884,8 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) ...@@ -878,6 +884,8 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
if (i >= 4) if (i >= 4)
return -EINVAL; return -EINVAL;
if (0 == INPUT(i).type)
return -EINVAL;
mutex_lock(&core->lock); mutex_lock(&core->lock);
cx88_newstation(core); cx88_newstation(core);
...@@ -898,9 +906,9 @@ static int vidioc_g_tuner (struct file *file, void *priv, ...@@ -898,9 +906,9 @@ static int vidioc_g_tuner (struct file *file, void *priv,
return -EINVAL; return -EINVAL;
strcpy(t->name, "Television"); strcpy(t->name, "Television");
t->type = V4L2_TUNER_ANALOG_TV;
t->capability = V4L2_TUNER_CAP_NORM; t->capability = V4L2_TUNER_CAP_NORM;
t->rangehigh = 0xffffffffUL; t->rangehigh = 0xffffffffUL;
call_all(core, tuner, g_tuner, t);
cx88_get_stereo(core ,t); cx88_get_stereo(core ,t);
reg = cx_read(MO_DEVICE_STATUS); reg = cx_read(MO_DEVICE_STATUS);
......
...@@ -831,7 +831,6 @@ video_poll(struct file *file, struct poll_table_struct *wait) ...@@ -831,7 +831,6 @@ video_poll(struct file *file, struct poll_table_struct *wait)
return rc | POLLERR; return rc | POLLERR;
return rc | videobuf_poll_stream(file, &fh->vbiq, wait); return rc | videobuf_poll_stream(file, &fh->vbiq, wait);
} }
mutex_lock(&fh->vidq.vb_lock); mutex_lock(&fh->vidq.vb_lock);
if (res_check(fh,RESOURCE_VIDEO)) { if (res_check(fh,RESOURCE_VIDEO)) {
/* streaming capture */ /* streaming capture */
...@@ -1222,8 +1221,8 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) ...@@ -1222,8 +1221,8 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i)
if ((CX88_VMUX_TELEVISION == INPUT(n).type) || if ((CX88_VMUX_TELEVISION == INPUT(n).type) ||
(CX88_VMUX_CABLE == INPUT(n).type)) { (CX88_VMUX_CABLE == INPUT(n).type)) {
i->type = V4L2_INPUT_TYPE_TUNER; i->type = V4L2_INPUT_TYPE_TUNER;
i->std = CX88_NORMS;
} }
i->std = CX88_NORMS;
return 0; return 0;
} }
EXPORT_SYMBOL(cx88_enum_input); EXPORT_SYMBOL(cx88_enum_input);
...@@ -1249,6 +1248,8 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) ...@@ -1249,6 +1248,8 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
if (i >= 4) if (i >= 4)
return -EINVAL; return -EINVAL;
if (0 == INPUT(i).type)
return -EINVAL;
mutex_lock(&core->lock); mutex_lock(&core->lock);
cx88_newstation(core); cx88_newstation(core);
...@@ -1269,9 +1270,9 @@ static int vidioc_g_tuner (struct file *file, void *priv, ...@@ -1269,9 +1270,9 @@ static int vidioc_g_tuner (struct file *file, void *priv,
return -EINVAL; return -EINVAL;
strcpy(t->name, "Television"); strcpy(t->name, "Television");
t->type = V4L2_TUNER_ANALOG_TV;
t->capability = V4L2_TUNER_CAP_NORM; t->capability = V4L2_TUNER_CAP_NORM;
t->rangehigh = 0xffffffffUL; t->rangehigh = 0xffffffffUL;
call_all(core, tuner, g_tuner, t);
cx88_get_stereo(core ,t); cx88_get_stereo(core ,t);
reg = cx_read(MO_DEVICE_STATUS); reg = cx_read(MO_DEVICE_STATUS);
...@@ -1301,6 +1302,8 @@ static int vidioc_g_frequency (struct file *file, void *priv, ...@@ -1301,6 +1302,8 @@ static int vidioc_g_frequency (struct file *file, void *priv,
if (unlikely(UNSET == core->board.tuner_type)) if (unlikely(UNSET == core->board.tuner_type))
return -EINVAL; return -EINVAL;
if (f->tuner)
return -EINVAL;
f->frequency = core->freq; f->frequency = core->freq;
...@@ -1318,9 +1321,10 @@ int cx88_set_freq (struct cx88_core *core, ...@@ -1318,9 +1321,10 @@ int cx88_set_freq (struct cx88_core *core,
return -EINVAL; return -EINVAL;
mutex_lock(&core->lock); mutex_lock(&core->lock);
core->freq = f->frequency;
cx88_newstation(core); cx88_newstation(core);
call_all(core, tuner, s_frequency, f); call_all(core, tuner, s_frequency, f);
call_all(core, tuner, g_frequency, f);
core->freq = f->frequency;
/* When changing channels it is required to reset TVAUDIO */ /* When changing channels it is required to reset TVAUDIO */
msleep (10); msleep (10);
...@@ -1341,6 +1345,16 @@ static int vidioc_s_frequency (struct file *file, void *priv, ...@@ -1341,6 +1345,16 @@ static int vidioc_s_frequency (struct file *file, void *priv,
return cx88_set_freq(core, f); return cx88_set_freq(core, f);
} }
static int vidioc_g_chip_ident(struct file *file, void *priv,
struct v4l2_dbg_chip_ident *chip)
{
if (!v4l2_chip_match_host(&chip->match))
return -EINVAL;
chip->revision = 0;
chip->ident = V4L2_IDENT_UNKNOWN;
return 0;
}
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
static int vidioc_g_register (struct file *file, void *fh, static int vidioc_g_register (struct file *file, void *fh,
struct v4l2_dbg_register *reg) struct v4l2_dbg_register *reg)
...@@ -1380,7 +1394,6 @@ static int radio_g_tuner (struct file *file, void *priv, ...@@ -1380,7 +1394,6 @@ static int radio_g_tuner (struct file *file, void *priv,
return -EINVAL; return -EINVAL;
strcpy(t->name, "Radio"); strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
call_all(core, tuner, g_tuner, t); call_all(core, tuner, g_tuner, t);
return 0; return 0;
...@@ -1395,6 +1408,8 @@ static int radio_s_tuner (struct file *file, void *priv, ...@@ -1395,6 +1408,8 @@ static int radio_s_tuner (struct file *file, void *priv,
if (0 != t->index) if (0 != t->index)
return -EINVAL; return -EINVAL;
if (t->audmode > V4L2_TUNER_MODE_STEREO)
t->audmode = V4L2_TUNER_MODE_STEREO;
call_all(core, tuner, s_tuner, t); call_all(core, tuner, s_tuner, t);
...@@ -1543,9 +1558,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { ...@@ -1543,9 +1558,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt,
.vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt,
.vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt,
.vidioc_reqbufs = vidioc_reqbufs, .vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf, .vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf, .vidioc_qbuf = vidioc_qbuf,
...@@ -1562,14 +1574,13 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { ...@@ -1562,14 +1574,13 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_s_frequency = vidioc_s_frequency, .vidioc_s_frequency = vidioc_s_frequency,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe, .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
.vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register, .vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register, .vidioc_s_register = vidioc_s_register,
#endif #endif
}; };
static struct video_device cx8800_vbi_template;
static const struct video_device cx8800_video_template = { static const struct video_device cx8800_video_template = {
.name = "cx8800-video", .name = "cx8800-video",
.fops = &video_fops, .fops = &video_fops,
...@@ -1578,6 +1589,40 @@ static const struct video_device cx8800_video_template = { ...@@ -1578,6 +1589,40 @@ static const struct video_device cx8800_video_template = {
.current_norm = V4L2_STD_NTSC_M, .current_norm = V4L2_STD_NTSC_M,
}; };
static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt,
.vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt,
.vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
.vidioc_s_std = vidioc_s_std,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
#endif
};
static const struct video_device cx8800_vbi_template = {
.name = "cx8800-vbi",
.fops = &video_fops,
.ioctl_ops = &vbi_ioctl_ops,
.tvnorms = CX88_NORMS,
.current_norm = V4L2_STD_NTSC_M,
};
static const struct v4l2_file_operations radio_fops = static const struct v4l2_file_operations radio_fops =
{ {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -1595,6 +1640,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { ...@@ -1595,6 +1640,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
.vidioc_s_frequency = vidioc_s_frequency, .vidioc_s_frequency = vidioc_s_frequency,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe, .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
.vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register, .vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register, .vidioc_s_register = vidioc_s_register,
...@@ -1682,11 +1728,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, ...@@ -1682,11 +1728,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
goto fail_core; goto fail_core;
} }
/* Initialize VBI template */
memcpy( &cx8800_vbi_template, &cx8800_video_template,
sizeof(cx8800_vbi_template) );
strcpy(cx8800_vbi_template.name,"cx8800-vbi");
/* initialize driver struct */ /* initialize driver struct */
spin_lock_init(&dev->slock); spin_lock_init(&dev->slock);
core->tvnorm = cx8800_video_template.current_norm; core->tvnorm = cx8800_video_template.current_norm;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment