diff options
Diffstat (limited to 'drivers/media/pci/saa7164')
-rw-r--r-- | drivers/media/pci/saa7164/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/pci/saa7164/saa7164-core.c | 4 | ||||
-rw-r--r-- | drivers/media/pci/saa7164/saa7164-encoder.c | 653 | ||||
-rw-r--r-- | drivers/media/pci/saa7164/saa7164-vbi.c | 629 | ||||
-rw-r--r-- | drivers/media/pci/saa7164/saa7164.h | 26 |
5 files changed, 219 insertions, 1094 deletions
diff --git a/drivers/media/pci/saa7164/Kconfig b/drivers/media/pci/saa7164/Kconfig index a53db7d1c..9098ef5fe 100644 --- a/drivers/media/pci/saa7164/Kconfig +++ b/drivers/media/pci/saa7164/Kconfig @@ -5,7 +5,6 @@ config VIDEO_SAA7164 select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM - select VIDEOBUF_DVB select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 3206a826b..8bbd092fb 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -1264,9 +1264,9 @@ static int saa7164_initdev(struct pci_dev *pci_dev, pci_set_master(pci_dev); /* TODO */ - if (!pci_dma_supported(pci_dev, 0xffffffff)) { + err = pci_set_dma_mask(pci_dev, 0xffffffff); + if (err) { printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); - err = -EIO; goto fail_irq; } diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c index 4434e0f28..1b184c39b 100644 --- a/drivers/media/pci/saa7164/saa7164-encoder.c +++ b/drivers/media/pci/saa7164/saa7164-encoder.c @@ -25,6 +25,18 @@ #define ENCODER_MIN_BITRATE 1000000 #define ENCODER_DEF_BITRATE 5000000 +/* + * This is a dummy non-zero value for the sizeimage field of v4l2_pix_format. + * It is not actually used for anything since this driver does not support + * stream I/O, only read(), and because this driver produces an MPEG stream + * and not discrete frames. But the V4L2 spec doesn't allow for this value + * to be 0, so set it to 0x10000 instead. + * + * If we ever change this driver to support stream I/O, then this field + * will be the size of the streaming buffers. + */ +#define SAA7164_SIZEIMAGE (0x10000) + static struct saa7164_tvnorm saa7164_tvnorms[] = { { .name = "NTSC-M", @@ -35,24 +47,6 @@ static struct saa7164_tvnorm saa7164_tvnorms[] = { } }; -static const u32 saa7164_v4l2_ctrls[] = { - V4L2_CID_BRIGHTNESS, - V4L2_CID_CONTRAST, - V4L2_CID_SATURATION, - V4L2_CID_HUE, - V4L2_CID_AUDIO_VOLUME, - V4L2_CID_SHARPNESS, - V4L2_CID_MPEG_STREAM_TYPE, - V4L2_CID_MPEG_VIDEO_ASPECT, - V4L2_CID_MPEG_VIDEO_B_FRAMES, - V4L2_CID_MPEG_VIDEO_GOP_SIZE, - V4L2_CID_MPEG_AUDIO_MUTE, - V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - V4L2_CID_MPEG_VIDEO_BITRATE, - V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, - 0 -}; - /* Take the encoder configuration form the port struct and * flush it to the hardware. */ @@ -211,10 +205,8 @@ static int saa7164_encoder_initialize(struct saa7164_port *port) } /* -- V4L2 --------------------------------------------------------- */ -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) +int saa7164_s_std(struct saa7164_port *port, v4l2_std_id id) { - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; struct saa7164_dev *dev = port->dev; unsigned int i; @@ -240,22 +232,33 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) return 0; } -static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) { struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; + return saa7164_s_std(fh->port, id); +} + +int saa7164_g_std(struct saa7164_port *port, v4l2_std_id *id) +{ *id = port->std; return 0; } -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) +static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) { - int n; + struct saa7164_encoder_fh *fh = file->private_data; + + return saa7164_g_std(fh->port, id); +} - char *inputs[] = { "tuner", "composite", "svideo", "aux", - "composite 2", "svideo 2", "aux 2" }; +int saa7164_enum_input(struct file *file, void *priv, struct v4l2_input *i) +{ + static const char * const inputs[] = { + "tuner", "composite", "svideo", "aux", + "composite 2", "svideo 2", "aux 2" + }; + int n; if (i->index >= 7) return -EINVAL; @@ -273,10 +276,8 @@ static int vidioc_enum_input(struct file *file, void *priv, return 0; } -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) +int saa7164_g_input(struct saa7164_port *port, unsigned int *i) { - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; struct saa7164_dev *dev = port->dev; if (saa7164_api_get_videomux(port) != SAA_OK) @@ -289,10 +290,15 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) return 0; } -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; + + return saa7164_g_input(fh->port, i); +} + +int saa7164_s_input(struct saa7164_port *port, unsigned int i) +{ struct saa7164_dev *dev = port->dev; dprintk(DBGLVL_ENC, "%s() input=%d\n", __func__, i); @@ -308,8 +314,14 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; } -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + struct saa7164_encoder_fh *fh = file->private_data; + + return saa7164_s_input(fh->port, i); +} + +int saa7164_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct saa7164_encoder_fh *fh = file->private_data; struct saa7164_port *port = fh->port; @@ -319,38 +331,45 @@ static int vidioc_g_tuner(struct file *file, void *priv, return -EINVAL; strcpy(t->name, "tuner"); - t->type = V4L2_TUNER_ANALOG_TV; t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO; + t->rangelow = SAA7164_TV_MIN_FREQ; + t->rangehigh = SAA7164_TV_MAX_FREQ; dprintk(DBGLVL_ENC, "VIDIOC_G_TUNER: tuner type %d\n", t->type); return 0; } -static int vidioc_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *t) +int saa7164_s_tuner(struct file *file, void *priv, + const struct v4l2_tuner *t) { + if (0 != t->index) + return -EINVAL; + /* Update the A/V core */ return 0; } -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) +int saa7164_g_frequency(struct saa7164_port *port, struct v4l2_frequency *f) { - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; + if (f->tuner) + return -EINVAL; - f->type = V4L2_TUNER_ANALOG_TV; f->frequency = port->freq; - return 0; } -static int vidioc_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *f) +static int vidioc_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) { struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; + + return saa7164_g_frequency(fh->port, f); +} + +int saa7164_s_frequency(struct saa7164_port *port, + const struct v4l2_frequency *f) +{ struct saa7164_dev *dev = port->dev; struct saa7164_port *tsport; struct dvb_frontend *fe; @@ -370,16 +389,13 @@ static int vidioc_s_frequency(struct file *file, void *priv, if (f->tuner != 0) return -EINVAL; - if (f->type != V4L2_TUNER_ANALOG_TV) - return -EINVAL; - - port->freq = f->frequency; + port->freq = clamp(f->frequency, + SAA7164_TV_MIN_FREQ, SAA7164_TV_MAX_FREQ); /* Update the hardware */ if (port->nr == SAA7164_PORT_ENC1) tsport = &dev->ports[SAA7164_PORT_TS1]; - else - if (port->nr == SAA7164_PORT_ENC2) + else if (port->nr == SAA7164_PORT_ENC2) tsport = &dev->ports[SAA7164_PORT_TS2]; else BUG(); @@ -396,253 +412,54 @@ static int vidioc_s_frequency(struct file *file, void *priv, return 0; } -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) +static int vidioc_s_frequency(struct file *file, void *priv, + const struct v4l2_frequency *f) { struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__, - ctl->id, ctl->value); - - switch (ctl->id) { - case V4L2_CID_BRIGHTNESS: - ctl->value = port->ctl_brightness; - break; - case V4L2_CID_CONTRAST: - ctl->value = port->ctl_contrast; - break; - case V4L2_CID_SATURATION: - ctl->value = port->ctl_saturation; - break; - case V4L2_CID_HUE: - ctl->value = port->ctl_hue; - break; - case V4L2_CID_SHARPNESS: - ctl->value = port->ctl_sharpness; - break; - case V4L2_CID_AUDIO_VOLUME: - ctl->value = port->ctl_volume; - break; - default: - return -EINVAL; - } - return 0; + return saa7164_s_frequency(fh->port, f); } -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) +static int saa7164_s_ctrl(struct v4l2_ctrl *ctrl) { - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; + struct saa7164_port *port = + container_of(ctrl->handler, struct saa7164_port, ctrl_handler); + struct saa7164_encoder_params *params = &port->encoder_params; int ret = 0; - dprintk(DBGLVL_ENC, "%s(id=%d, value=%d)\n", __func__, - ctl->id, ctl->value); - - switch (ctl->id) { + switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_brightness = ctl->value; - saa7164_api_set_usercontrol(port, - PU_BRIGHTNESS_CONTROL); - } else - ret = -EINVAL; + port->ctl_brightness = ctrl->val; + saa7164_api_set_usercontrol(port, PU_BRIGHTNESS_CONTROL); break; case V4L2_CID_CONTRAST: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_contrast = ctl->value; - saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); - } else - ret = -EINVAL; + port->ctl_contrast = ctrl->val; + saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); break; case V4L2_CID_SATURATION: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_saturation = ctl->value; - saa7164_api_set_usercontrol(port, - PU_SATURATION_CONTROL); - } else - ret = -EINVAL; + port->ctl_saturation = ctrl->val; + saa7164_api_set_usercontrol(port, PU_SATURATION_CONTROL); break; case V4L2_CID_HUE: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_hue = ctl->value; - saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); - } else - ret = -EINVAL; + port->ctl_hue = ctrl->val; + saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); break; case V4L2_CID_SHARPNESS: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_sharpness = ctl->value; - saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); - } else - ret = -EINVAL; + port->ctl_sharpness = ctrl->val; + saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); break; case V4L2_CID_AUDIO_VOLUME: - if ((ctl->value >= -83) && (ctl->value <= 24)) { - port->ctl_volume = ctl->value; - saa7164_api_set_audio_volume(port, port->ctl_volume); - } else - ret = -EINVAL; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int saa7164_get_ctrl(struct saa7164_port *port, - struct v4l2_ext_control *ctrl) -{ - struct saa7164_encoder_params *params = &port->encoder_params; - - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_BITRATE: - ctrl->value = params->bitrate; - break; - case V4L2_CID_MPEG_STREAM_TYPE: - ctrl->value = params->stream_type; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - ctrl->value = params->ctl_mute; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - ctrl->value = params->ctl_aspect; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - ctrl->value = params->bitrate_mode; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - ctrl->value = params->refdist; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - ctrl->value = params->bitrate_peak; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - ctrl->value = params->gop_size; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_get_ctrl(port, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - -static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) -{ - int ret = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_BITRATE: - if ((ctrl->value >= ENCODER_MIN_BITRATE) && - (ctrl->value <= ENCODER_MAX_BITRATE)) - ret = 0; + port->ctl_volume = ctrl->val; + saa7164_api_set_audio_volume(port, port->ctl_volume); break; - case V4L2_CID_MPEG_STREAM_TYPE: - if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) || - (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)) - ret = 0; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - if ((ctrl->value >= 0) && - (ctrl->value <= 1)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) && - (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - if ((ctrl->value >= 0) && - (ctrl->value <= 255)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - if ((ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) || - (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - if ((ctrl->value >= 1) && - (ctrl->value <= 3)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - if ((ctrl->value >= ENCODER_MIN_BITRATE) && - (ctrl->value <= ENCODER_MAX_BITRATE)) - ret = 0; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_try_ctrl(ctrl, 0); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - } - - return -EINVAL; -} - -static int saa7164_set_ctrl(struct saa7164_port *port, - struct v4l2_ext_control *ctrl) -{ - struct saa7164_encoder_params *params = &port->encoder_params; - int ret = 0; - - switch (ctrl->id) { case V4L2_CID_MPEG_VIDEO_BITRATE: - params->bitrate = ctrl->value; + params->bitrate = ctrl->val; break; case V4L2_CID_MPEG_STREAM_TYPE: - params->stream_type = ctrl->value; + params->stream_type = ctrl->val; break; case V4L2_CID_MPEG_AUDIO_MUTE: - params->ctl_mute = ctrl->value; + params->ctl_mute = ctrl->val; ret = saa7164_api_audio_mute(port, params->ctl_mute); if (ret != SAA_OK) { printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, @@ -651,7 +468,7 @@ static int saa7164_set_ctrl(struct saa7164_port *port, } break; case V4L2_CID_MPEG_VIDEO_ASPECT: - params->ctl_aspect = ctrl->value; + params->ctl_aspect = ctrl->val; ret = saa7164_api_set_aspect_ratio(port); if (ret != SAA_OK) { printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, @@ -660,55 +477,24 @@ static int saa7164_set_ctrl(struct saa7164_port *port, } break; case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - params->bitrate_mode = ctrl->value; + params->bitrate_mode = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_B_FRAMES: - params->refdist = ctrl->value; + params->refdist = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - params->bitrate_peak = ctrl->value; + params->bitrate_peak = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - params->gop_size = ctrl->value; + params->gop_size = ctrl->val; break; default: - return -EINVAL; + ret = -EINVAL; } - /* TODO: Update the hardware */ - return ret; } -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_try_ctrl(ctrl, 0); - if (err) { - ctrls->error_idx = i; - break; - } - err = saa7164_set_ctrl(port, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -745,145 +531,22 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, +static int vidioc_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7164_encoder_fh *fh = file->private_data; struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; + f->fmt.pix.sizeimage = SAA7164_SIZEIMAGE; + f->fmt.pix.field = V4L2_FIELD_INTERLACED; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; f->fmt.pix.width = port->width; f->fmt.pix.height = port->height; - - dprintk(DBGLVL_ENC, "VIDIOC_G_FMT: w: %d, h: %d\n", - port->width, port->height); - - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(DBGLVL_ENC, "VIDIOC_TRY_FMT: w: %d, h: %d\n", - port->width, port->height); return 0; } -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - - dprintk(DBGLVL_ENC, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); - - return 0; -} - -static int fill_queryctrl(struct saa7164_encoder_params *params, - struct v4l2_queryctrl *c) -{ - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128); - case V4L2_CID_SHARPNESS: - return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8); - case V4L2_CID_MPEG_AUDIO_MUTE: - return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(c, -83, 24, 1, 20); - case V4L2_CID_MPEG_VIDEO_BITRATE: - return v4l2_ctrl_query_fill(c, - ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE, - 100000, ENCODER_DEF_BITRATE); - case V4L2_CID_MPEG_STREAM_TYPE: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - V4L2_MPEG_STREAM_TYPE_MPEG2_TS, - 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS); - case V4L2_CID_MPEG_VIDEO_ASPECT: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_VIDEO_ASPECT_1x1, - V4L2_MPEG_VIDEO_ASPECT_221x100, - 1, V4L2_MPEG_VIDEO_ASPECT_4x3); - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - return v4l2_ctrl_query_fill(c, 1, 255, 1, 15); - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, - 1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - return v4l2_ctrl_query_fill(c, - 1, 3, 1, 1); - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - return v4l2_ctrl_query_fill(c, - ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE, - 100000, ENCODER_DEF_BITRATE); - default: - return -EINVAL; - } -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct saa7164_encoder_fh *fh = priv; - struct saa7164_port *port = fh->port; - int i, next; - u32 id = c->id; - - memset(c, 0, sizeof(*c)); - - next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); - c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; - - for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) { - if (next) { - if (c->id < saa7164_v4l2_ctrls[i]) - c->id = saa7164_v4l2_ctrls[i]; - else - continue; - } - - if (c->id == saa7164_v4l2_ctrls[i]) - return fill_queryctrl(&port->encoder_params, c); - - if (c->id < saa7164_v4l2_ctrls[i]) - break; - } - - return -EINVAL; -} - static int saa7164_encoder_stop_port(struct saa7164_port *port) { struct saa7164_dev *dev = port->dev; @@ -1084,8 +747,10 @@ static int fops_open(struct file *file) if (NULL == fh) return -ENOMEM; - file->private_data = fh; fh->port = port; + v4l2_fh_init(&fh->fh, video_devdata(file)); + v4l2_fh_add(&fh->fh); + file->private_data = fh; return 0; } @@ -1106,7 +771,8 @@ static int fops_release(struct file *file) } } - file->private_data = NULL; + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); kfree(fh); return 0; @@ -1250,10 +916,11 @@ err: static unsigned int fops_poll(struct file *file, poll_table *wait) { + unsigned long req_events = poll_requested_events(wait); struct saa7164_encoder_fh *fh = (struct saa7164_encoder_fh *)file->private_data; struct saa7164_port *port = fh->port; - unsigned int mask = 0; + unsigned int mask = v4l2_ctrl_poll(file, wait); port->last_poll_msecs_diff = port->last_poll_msecs; port->last_poll_msecs = jiffies_to_msecs(jiffies); @@ -1263,26 +930,18 @@ static unsigned int fops_poll(struct file *file, poll_table *wait) saa7164_histogram_update(&port->poll_interval, port->last_poll_msecs_diff); - if (!video_is_registered(port->v4l_device)) - return -EIO; + if (!(req_events & (POLLIN | POLLRDNORM))) + return mask; if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { if (atomic_inc_return(&port->v4l_reader_count) == 1) { if (saa7164_encoder_initialize(port) < 0) - return -EINVAL; + return mask | POLLERR; saa7164_encoder_start_streaming(port); msleep(200); } } - /* blocking wait for buffer */ - if ((file->f_flags & O_NONBLOCK) == 0) { - if (wait_event_interruptible(port->wait_read, - saa7164_enc_next_buf(port))) { - return -ERESTARTSYS; - } - } - /* Pull the first buffer from the used list */ if (!list_empty(&port->list_buf_used.list)) mask |= POLLIN | POLLRDNORM; @@ -1290,6 +949,10 @@ static unsigned int fops_poll(struct file *file, poll_table *wait) return mask; } +static const struct v4l2_ctrl_ops saa7164_ctrl_ops = { + .s_ctrl = saa7164_s_ctrl, +}; + static const struct v4l2_file_operations mpeg_fops = { .owner = THIS_MODULE, .open = fops_open, @@ -1302,24 +965,21 @@ static const struct v4l2_file_operations mpeg_fops = { static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_s_std = vidioc_s_std, .vidioc_g_std = vidioc_g_std, - .vidioc_enum_input = vidioc_enum_input, + .vidioc_enum_input = saa7164_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_tuner = saa7164_g_tuner, + .vidioc_s_tuner = saa7164_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, - .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_fmt_vid_cap = vidioc_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_fmt_vid_cap, + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device saa7164_mpeg_template = { @@ -1357,6 +1017,7 @@ static struct video_device *saa7164_encoder_alloc( int saa7164_encoder_register(struct saa7164_port *port) { struct saa7164_dev *dev = port->dev; + struct v4l2_ctrl_handler *hdl = &port->ctrl_handler; int result = -ENODEV; dprintk(DBGLVL_ENC, "%s()\n", __func__); @@ -1381,19 +1042,52 @@ int saa7164_encoder_register(struct saa7164_port *port) port->video_format = EU_VIDEO_FORMAT_MPEG_2; port->audio_format = 0; port->video_resolution = 0; - port->ctl_brightness = 127; - port->ctl_contrast = 66; - port->ctl_hue = 128; - port->ctl_saturation = 62; - port->ctl_sharpness = 8; - port->encoder_params.bitrate = ENCODER_DEF_BITRATE; - port->encoder_params.bitrate_peak = ENCODER_DEF_BITRATE; - port->encoder_params.bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; - port->encoder_params.stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS; - port->encoder_params.ctl_mute = 0; - port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3; - port->encoder_params.refdist = 1; - port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE; + port->freq = SAA7164_TV_MIN_FREQ; + + v4l2_ctrl_handler_init(hdl, 14); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_CONTRAST, 0, 255, 1, 66); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_SATURATION, 0, 255, 1, 62); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_HUE, 0, 255, 1, 128); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_SHARPNESS, 0x0, 0x0f, 1, 8); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_MPEG_AUDIO_MUTE, 0x0, 0x01, 1, 0); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_AUDIO_VOLUME, -83, 24, 1, 20); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_MPEG_VIDEO_BITRATE, + ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE, + 100000, ENCODER_DEF_BITRATE); + v4l2_ctrl_new_std_menu(hdl, &saa7164_ctrl_ops, + V4L2_CID_MPEG_STREAM_TYPE, + V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 0, + V4L2_MPEG_STREAM_TYPE_MPEG2_PS); + v4l2_ctrl_new_std_menu(hdl, &saa7164_ctrl_ops, + V4L2_CID_MPEG_VIDEO_ASPECT, + V4L2_MPEG_VIDEO_ASPECT_221x100, 0, + V4L2_MPEG_VIDEO_ASPECT_4x3); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 255, 1, 15); + v4l2_ctrl_new_std_menu(hdl, &saa7164_ctrl_ops, + V4L2_CID_MPEG_VIDEO_BITRATE_MODE, + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0, + V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_MPEG_VIDEO_B_FRAMES, 1, 3, 1, 1); + v4l2_ctrl_new_std(hdl, &saa7164_ctrl_ops, + V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, + ENCODER_MIN_BITRATE, ENCODER_MAX_BITRATE, + 100000, ENCODER_DEF_BITRATE); + if (hdl->error) { + result = hdl->error; + goto failed; + } + port->std = V4L2_STD_NTSC_M; if (port->encodernorm.id & V4L2_STD_525_60) @@ -1412,6 +1106,8 @@ int saa7164_encoder_register(struct saa7164_port *port) goto failed; } + port->v4l_device->ctrl_handler = hdl; + v4l2_ctrl_handler_setup(hdl); video_set_drvdata(port->v4l_device, port); result = video_register_device(port->v4l_device, VFL_TYPE_GRABBER, -1); @@ -1466,6 +1162,7 @@ void saa7164_encoder_unregister(struct saa7164_port *port) port->v4l_device = NULL; } + v4l2_ctrl_handler_free(&port->ctrl_handler); dprintk(DBGLVL_ENC, "%s(port=%d) done\n", __func__, port->nr); } diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c index 859fd03d8..ee5449145 100644 --- a/drivers/media/pci/saa7164/saa7164-vbi.c +++ b/drivers/media/pci/saa7164/saa7164-vbi.c @@ -21,20 +21,6 @@ #include "saa7164.h" -static struct saa7164_tvnorm saa7164_tvnorms[] = { - { - .name = "NTSC-M", - .id = V4L2_STD_NTSC_M, - }, { - .name = "NTSC-JP", - .id = V4L2_STD_NTSC_M_JP, - } -}; - -static const u32 saa7164_v4l2_ctrls[] = { - 0 -}; - /* Take the encoder configuration from the port struct and * flush it to the hardware. */ @@ -43,23 +29,13 @@ static void saa7164_vbi_configure(struct saa7164_port *port) struct saa7164_dev *dev = port->dev; dprintk(DBGLVL_VBI, "%s()\n", __func__); - port->vbi_params.width = port->width; - port->vbi_params.height = port->height; + port->vbi_params.width = port->enc_port->width; + port->vbi_params.height = port->enc_port->height; port->vbi_params.is_50hz = - (port->encodernorm.id & V4L2_STD_625_50) != 0; + (port->enc_port->encodernorm.id & V4L2_STD_625_50) != 0; /* Set up the DIF (enable it) for analog mode by default */ saa7164_api_initialize_dif(port); - - /* Configure the correct video standard */ -#if 0 - saa7164_api_configure_dif(port, port->encodernorm.id); -#endif - -#if 0 - /* Ensure the audio decoder is correct configured */ - saa7164_api_set_audio_std(port); -#endif dprintk(DBGLVL_VBI, "%s() ends\n", __func__); } @@ -186,468 +162,50 @@ static int saa7164_vbi_initialize(struct saa7164_port *port) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) { struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - unsigned int i; - dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)id); - - for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) { - if (id & saa7164_tvnorms[i].id) - break; - } - if (i == ARRAY_SIZE(saa7164_tvnorms)) - return -EINVAL; - - port->encodernorm = saa7164_tvnorms[i]; - port->std = id; - - /* Update the audio decoder while is not running in - * auto detect mode. - */ - saa7164_api_set_audio_std(port); - - dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)id); - - return 0; + return saa7164_s_std(fh->port->enc_port, id); } static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) { struct saa7164_encoder_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - *id = port->std; - return 0; -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - int n; - - char *inputs[] = { "tuner", "composite", "svideo", "aux", - "composite 2", "svideo 2", "aux 2" }; - - if (i->index >= 7) - return -EINVAL; - - strcpy(i->name, inputs[i->index]); - - if (i->index == 0) - i->type = V4L2_INPUT_TYPE_TUNER; - else - i->type = V4L2_INPUT_TYPE_CAMERA; - - for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++) - i->std |= saa7164_tvnorms[n].id; - - return 0; + return saa7164_g_std(fh->port->enc_port, id); } static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - if (saa7164_api_get_videomux(port) != SAA_OK) - return -EIO; - - *i = (port->mux_input - 1); - - dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i); - return 0; + return saa7164_g_input(fh->port->enc_port, i); } static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i); - - if (i >= 7) - return -EINVAL; - - port->mux_input = i + 1; - if (saa7164_api_set_videomux(port) != SAA_OK) - return -EIO; - - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - if (0 != t->index) - return -EINVAL; - - strcpy(t->name, "tuner"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO; - - dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type); - - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *t) -{ - /* Update the A/V core */ - return 0; + return saa7164_s_input(fh->port->enc_port, i); } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = port->freq; - - return 0; + return saa7164_g_frequency(fh->port->enc_port, f); } static int vidioc_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *f) { struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - struct saa7164_port *tsport; - struct dvb_frontend *fe; - - /* TODO: Pull this for the std */ - struct analog_parameters params = { - .mode = V4L2_TUNER_ANALOG_TV, - .audmode = V4L2_TUNER_MODE_STEREO, - .std = port->encodernorm.id, - .frequency = f->frequency - }; - - /* Stop the encoder */ - dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__, - f->frequency, f->tuner); - - if (f->tuner != 0) - return -EINVAL; - - if (f->type != V4L2_TUNER_ANALOG_TV) - return -EINVAL; - - port->freq = f->frequency; - - /* Update the hardware */ - if (port->nr == SAA7164_PORT_VBI1) - tsport = &dev->ports[SAA7164_PORT_TS1]; - else - if (port->nr == SAA7164_PORT_VBI2) - tsport = &dev->ports[SAA7164_PORT_TS2]; - else - BUG(); - - fe = tsport->dvb.frontend; - - if (fe && fe->ops.tuner_ops.set_analog_params) - fe->ops.tuner_ops.set_analog_params(fe, ¶ms); - else - printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__); - - saa7164_vbi_initialize(port); - - return 0; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__, - ctl->id, ctl->value); - - switch (ctl->id) { - case V4L2_CID_BRIGHTNESS: - ctl->value = port->ctl_brightness; - break; - case V4L2_CID_CONTRAST: - ctl->value = port->ctl_contrast; - break; - case V4L2_CID_SATURATION: - ctl->value = port->ctl_saturation; - break; - case V4L2_CID_HUE: - ctl->value = port->ctl_hue; - break; - case V4L2_CID_SHARPNESS: - ctl->value = port->ctl_sharpness; - break; - case V4L2_CID_AUDIO_VOLUME: - ctl->value = port->ctl_volume; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - int ret = 0; - - dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__, - ctl->id, ctl->value); - - switch (ctl->id) { - case V4L2_CID_BRIGHTNESS: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_brightness = ctl->value; - saa7164_api_set_usercontrol(port, - PU_BRIGHTNESS_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_CONTRAST: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_contrast = ctl->value; - saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_SATURATION: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_saturation = ctl->value; - saa7164_api_set_usercontrol(port, - PU_SATURATION_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_HUE: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_hue = ctl->value; - saa7164_api_set_usercontrol(port, PU_HUE_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_SHARPNESS: - if ((ctl->value >= 0) && (ctl->value <= 255)) { - port->ctl_sharpness = ctl->value; - saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL); - } else - ret = -EINVAL; - break; - case V4L2_CID_AUDIO_VOLUME: - if ((ctl->value >= -83) && (ctl->value <= 24)) { - port->ctl_volume = ctl->value; - saa7164_api_set_audio_volume(port, port->ctl_volume); - } else - ret = -EINVAL; - break; - default: - ret = -EINVAL; - } + int ret = saa7164_s_frequency(fh->port->enc_port, f); + if (ret == 0) + saa7164_vbi_initialize(fh->port); return ret; } -static int saa7164_get_ctrl(struct saa7164_port *port, - struct v4l2_ext_control *ctrl) -{ - struct saa7164_vbi_params *params = &port->vbi_params; - - switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - ctrl->value = params->stream_type; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - ctrl->value = params->ctl_mute; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - ctrl->value = params->ctl_aspect; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - ctrl->value = params->refdist; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - ctrl->value = params->gop_size; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_get_ctrl(port, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - -static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) -{ - int ret = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) || - (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)) - ret = 0; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - if ((ctrl->value >= 0) && - (ctrl->value <= 1)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) && - (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - if ((ctrl->value >= 0) && - (ctrl->value <= 255)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - if ((ctrl->value >= 1) && - (ctrl->value <= 3)) - ret = 0; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_try_ctrl(ctrl, 0); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - } - - return -EINVAL; -} - -static int saa7164_set_ctrl(struct saa7164_port *port, - struct v4l2_ext_control *ctrl) -{ - struct saa7164_vbi_params *params = &port->vbi_params; - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - params->stream_type = ctrl->value; - break; - case V4L2_CID_MPEG_AUDIO_MUTE: - params->ctl_mute = ctrl->value; - ret = saa7164_api_audio_mute(port, params->ctl_mute); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, - ret); - ret = -EIO; - } - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - params->ctl_aspect = ctrl->value; - ret = saa7164_api_set_aspect_ratio(port); - if (ret != SAA_OK) { - printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, - ret); - ret = -EIO; - } - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - params->refdist = ctrl->value; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - params->gop_size = ctrl->value; - break; - default: - return -EINVAL; - } - - /* TODO: Update the hardware */ - - return ret; -} - -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = saa7164_try_ctrl(ctrl, 0); - if (err) { - ctrls->error_idx = i; - break; - } - err = saa7164_set_ctrl(port, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -672,144 +230,6 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (f->index != 0) - return -EINVAL; - - strlcpy(f->description, "VBI", sizeof(f->description)); - f->pixelformat = V4L2_PIX_FMT_MPEG; - - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - f->fmt.pix.width = port->width; - f->fmt.pix.height = port->height; - - dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n", - port->width, port->height); - - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n", - port->width, port->height); - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7164_vbi_fh *fh = file->private_data; - struct saa7164_port *port = fh->port; - struct saa7164_dev *dev = port->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - port->ts_packet_size * port->ts_packet_count; - f->fmt.pix.colorspace = 0; - - dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); - - return 0; -} - -static int fill_queryctrl(struct saa7164_vbi_params *params, - struct v4l2_queryctrl *c) -{ - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128); - case V4L2_CID_SHARPNESS: - return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8); - case V4L2_CID_MPEG_AUDIO_MUTE: - return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(c, -83, 24, 1, 20); - case V4L2_CID_MPEG_STREAM_TYPE: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - V4L2_MPEG_STREAM_TYPE_MPEG2_TS, - 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS); - case V4L2_CID_MPEG_VIDEO_ASPECT: - return v4l2_ctrl_query_fill(c, - V4L2_MPEG_VIDEO_ASPECT_1x1, - V4L2_MPEG_VIDEO_ASPECT_221x100, - 1, V4L2_MPEG_VIDEO_ASPECT_4x3); - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - return v4l2_ctrl_query_fill(c, 1, 255, 1, 15); - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - return v4l2_ctrl_query_fill(c, - 1, 3, 1, 1); - default: - return -EINVAL; - } -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct saa7164_vbi_fh *fh = priv; - struct saa7164_port *port = fh->port; - int i, next; - u32 id = c->id; - - memset(c, 0, sizeof(*c)); - - next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); - c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; - - for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) { - if (next) { - if (c->id < saa7164_v4l2_ctrls[i]) - c->id = saa7164_v4l2_ctrls[i]; - else - continue; - } - - if (c->id == saa7164_v4l2_ctrls[i]) - return fill_queryctrl(&port->vbi_params, c); - - if (c->id < saa7164_v4l2_ctrls[i]) - break; - } - - return -EINVAL; -} - static int saa7164_vbi_stop_port(struct saa7164_port *port) { struct saa7164_dev *dev = port->dev; @@ -999,7 +419,6 @@ static int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f) { /* ntsc */ - f->fmt.vbi.samples_per_line = 1600; f->fmt.vbi.samples_per_line = 1440; f->fmt.vbi.sampling_rate = 27000000; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; @@ -1009,6 +428,7 @@ static int saa7164_vbi_fmt(struct file *file, void *priv, f->fmt.vbi.count[0] = 18; f->fmt.vbi.start[1] = 263 + 10 + 1; f->fmt.vbi.count[1] = 18; + memset(f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved)); return 0; } @@ -1031,8 +451,10 @@ static int fops_open(struct file *file) if (NULL == fh) return -ENOMEM; - file->private_data = fh; fh->port = port; + v4l2_fh_init(&fh->fh, video_devdata(file)); + v4l2_fh_add(&fh->fh); + file->private_data = fh; return 0; } @@ -1053,7 +475,8 @@ static int fops_release(struct file *file) } } - file->private_data = NULL; + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); kfree(fh); return 0; @@ -1248,24 +671,14 @@ static const struct v4l2_file_operations vbi_fops = { static const struct v4l2_ioctl_ops vbi_ioctl_ops = { .vidioc_s_std = vidioc_s_std, .vidioc_g_std = vidioc_g_std, - .vidioc_enum_input = vidioc_enum_input, + .vidioc_enum_input = saa7164_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_tuner = saa7164_g_tuner, + .vidioc_s_tuner = saa7164_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, - .vidioc_queryctrl = vidioc_queryctrl, .vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt, .vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt, .vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt, @@ -1335,7 +748,7 @@ int saa7164_vbi_register(struct saa7164_port *port) goto failed; } - port->std = V4L2_STD_NTSC_M; + port->enc_port = &dev->ports[port->nr - 2]; video_set_drvdata(port->v4l_device, port); result = video_register_device(port->v4l_device, VFL_TYPE_VBI, -1); diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h index 18906e0c8..8337524bf 100644 --- a/drivers/media/pci/saa7164/saa7164.h +++ b/drivers/media/pci/saa7164/saa7164.h @@ -54,8 +54,6 @@ #include <media/tuner.h> #include <media/tveeprom.h> -#include <media/videobuf-dma-sg.h> -#include <media/videobuf-dvb.h> #include <dvb_demux.h> #include <dvb_frontend.h> #include <dvb_net.h> @@ -64,6 +62,8 @@ #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-device.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-event.h> #include "saa7164-reg.h" #include "saa7164-types.h" @@ -117,7 +117,11 @@ #define DBGLVL_CPU 8192 #define SAA7164_NORMS \ - (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443) + (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP) + +/* TV frequency range copied from tuner-core.c */ +#define SAA7164_TV_MIN_FREQ (44U * 16U) +#define SAA7164_TV_MAX_FREQ (958U * 16U) enum port_t { SAA7164_MPEG_UNDEFINED = 0, @@ -185,11 +189,13 @@ struct saa7164_subid { }; struct saa7164_encoder_fh { + struct v4l2_fh fh; struct saa7164_port *port; atomic_t v4l_reading; }; struct saa7164_vbi_fh { + struct v4l2_fh fh; struct saa7164_port *port; atomic_t v4l_reading; }; @@ -381,12 +387,11 @@ struct saa7164_port { /* Encoder */ /* Defaults established in saa7164-encoder.c */ struct saa7164_tvnorm encodernorm; + struct v4l2_ctrl_handler ctrl_handler; v4l2_std_id std; u32 height; u32 width; u32 freq; - u32 ts_packet_size; - u32 ts_packet_count; u8 mux_input; u8 encoder_profile; u8 video_format; @@ -419,6 +424,7 @@ struct saa7164_port { /* V4L VBI */ struct tmComResVBIFormatDescrHeader vbi_fmt_ntsc; struct saa7164_vbi_params vbi_params; + struct saa7164_port *enc_port; /* Debug */ u32 sync_errors; @@ -594,6 +600,16 @@ extern int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i); /* ----------------------------------------------------------- */ /* saa7164-encoder.c */ +int saa7164_s_std(struct saa7164_port *port, v4l2_std_id id); +int saa7164_g_std(struct saa7164_port *port, v4l2_std_id *id); +int saa7164_enum_input(struct file *file, void *priv, struct v4l2_input *i); +int saa7164_g_input(struct saa7164_port *port, unsigned int *i); +int saa7164_s_input(struct saa7164_port *port, unsigned int i); +int saa7164_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t); +int saa7164_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t); +int saa7164_g_frequency(struct saa7164_port *port, struct v4l2_frequency *f); +int saa7164_s_frequency(struct saa7164_port *port, + const struct v4l2_frequency *f); int saa7164_encoder_register(struct saa7164_port *port); void saa7164_encoder_unregister(struct saa7164_port *port); |