diff options
Diffstat (limited to 'drivers/media/pci/saa7134/saa7134-video.c')
| -rw-r--r-- | drivers/media/pci/saa7134/saa7134-video.c | 189 | 
1 files changed, 61 insertions, 128 deletions
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 7c503fb6852..cc409380ee1 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -1176,14 +1176,6 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev,  struct saa7134_fh *fh, str  	int restart_overlay = 0;  	int err; -	/* When called from the empress code fh == NULL. -	   That needs to be fixed somehow, but for now this is -	   good enough. */ -	if (fh) { -		err = v4l2_prio_check(&dev->prio, fh->prio); -		if (0 != err) -			return err; -	}  	err = -EINVAL;  	mutex_lock(&dev->lock); @@ -1352,6 +1344,7 @@ static int video_open(struct file *file)  	if (NULL == fh)  		return -ENOMEM; +	v4l2_fh_init(&fh->fh, vdev);  	file->private_data = fh;  	fh->dev      = dev;  	fh->radio    = radio; @@ -1359,7 +1352,6 @@ static int video_open(struct file *file)  	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);  	fh->width    = 720;  	fh->height   = 576; -	v4l2_prio_open(&dev->prio, &fh->prio);  	videobuf_queue_sg_init(&fh->cap, &video_qops,  			    &dev->pci->dev, &dev->slock, @@ -1384,6 +1376,8 @@ static int video_open(struct file *file)  		/* switch to video/vbi mode */  		video_mux(dev,dev->ctl_input);  	} +	v4l2_fh_add(&fh->fh); +  	return 0;  } @@ -1504,7 +1498,8 @@ static int video_release(struct file *file)  	saa7134_pgtable_free(dev->pci,&fh->pt_cap);  	saa7134_pgtable_free(dev->pci,&fh->pt_vbi); -	v4l2_prio_close(&dev->prio, fh->prio); +	v4l2_fh_del(&fh->fh); +	v4l2_fh_exit(&fh->fh);  	file->private_data = NULL;  	kfree(fh);  	return 0; @@ -1557,6 +1552,7 @@ static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,  	struct saa7134_dev *dev = fh->dev;  	struct saa7134_tvnorm *norm = dev->tvnorm; +	memset(&f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved));  	f->fmt.vbi.sampling_rate = 6750000 * 4;  	f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;  	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; @@ -1755,7 +1751,6 @@ static int saa7134_enum_input(struct file *file, void *priv,  	strcpy(i->name, card_in(dev, n).name);  	if (card_in(dev, n).tv)  		i->type = V4L2_INPUT_TYPE_TUNER; -	i->audioset = 1;  	if (n == dev->ctl_input) {  		int v1 = saa_readb(SAA7134_STATUS_VIDEO1);  		int v2 = saa_readb(SAA7134_STATUS_VIDEO2); @@ -1784,11 +1779,6 @@ static int saa7134_s_input(struct file *file, void *priv, unsigned int i)  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; -	int err; - -	err = v4l2_prio_check(&dev->prio, fh->prio); -	if (0 != err) -		return err;  	if (i >= SAA7134_INPUT_MAX)  		return -EINVAL; @@ -1805,6 +1795,8 @@ static int saa7134_querycap(struct file *file, void  *priv,  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; +	struct video_device *vdev = video_devdata(file); +	u32 radio_caps, video_caps, vbi_caps;  	unsigned int tuner_type = dev->tuner_type; @@ -1812,54 +1804,67 @@ static int saa7134_querycap(struct file *file, void  *priv,  	strlcpy(cap->card, saa7134_boards[dev->board].name,  		sizeof(cap->card));  	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); -	cap->capabilities = -		V4L2_CAP_VIDEO_CAPTURE | -		V4L2_CAP_VBI_CAPTURE | -		V4L2_CAP_READWRITE | -		V4L2_CAP_STREAMING | -		V4L2_CAP_TUNER; + +	cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; +	if ((tuner_type != TUNER_ABSENT) && (tuner_type != UNSET)) +		cap->device_caps |= V4L2_CAP_TUNER; + +	radio_caps = V4L2_CAP_RADIO;  	if (dev->has_rds) -		cap->capabilities |= V4L2_CAP_RDS_CAPTURE; +		radio_caps |= V4L2_CAP_RDS_CAPTURE; + +	video_caps = V4L2_CAP_VIDEO_CAPTURE;  	if (saa7134_no_overlay <= 0) -		cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; +		video_caps |= V4L2_CAP_VIDEO_OVERLAY; + +	vbi_caps = V4L2_CAP_VBI_CAPTURE; + +	switch (vdev->vfl_type) { +	case VFL_TYPE_RADIO: +		cap->device_caps |= radio_caps; +		break; +	case VFL_TYPE_GRABBER: +		cap->device_caps |= video_caps; +		break; +	case VFL_TYPE_VBI: +		cap->device_caps |= vbi_caps; +		break; +	} +	cap->capabilities = radio_caps | video_caps | vbi_caps | +		cap->device_caps | V4L2_CAP_DEVICE_CAPS; +	if (vdev->vfl_type == VFL_TYPE_RADIO) { +		cap->device_caps &= ~V4L2_CAP_STREAMING; +		if (!dev->has_rds) +			cap->device_caps &= ~V4L2_CAP_READWRITE; +	} -	if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) -		cap->capabilities &= ~V4L2_CAP_TUNER;  	return 0;  } -int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id) +int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id id)  {  	unsigned long flags;  	unsigned int i;  	v4l2_std_id fixup; -	int err; -	/* When called from the empress code fh == NULL. -	   That needs to be fixed somehow, but for now this is -	   good enough. */ -	if (fh) { -		err = v4l2_prio_check(&dev->prio, fh->prio); -		if (0 != err) -			return err; -	} else if (res_locked(dev, RESOURCE_OVERLAY)) { +	if (!fh && res_locked(dev, RESOURCE_OVERLAY)) {  		/* Don't change the std from the mpeg device  		   if overlay is active. */  		return -EBUSY;  	}  	for (i = 0; i < TVNORMS; i++) -		if (*id == tvnorms[i].id) +		if (id == tvnorms[i].id)  			break;  	if (i == TVNORMS)  		for (i = 0; i < TVNORMS; i++) -			if (*id & tvnorms[i].id) +			if (id & tvnorms[i].id)  				break;  	if (i == TVNORMS)  		return -EINVAL; -	if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) { +	if ((id & V4L2_STD_SECAM) && (secam[0] != '-')) {  		if (secam[0] == 'L' || secam[0] == 'l') {  			if (secam[1] == 'C' || secam[1] == 'c')  				fixup = V4L2_STD_SECAM_LC; @@ -1879,7 +1884,7 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_  			return -EINVAL;  	} -	*id = tvnorms[i].id; +	id = tvnorms[i].id;  	mutex_lock(&dev->lock);  	if (fh && res_check(fh, RESOURCE_OVERLAY)) { @@ -1901,7 +1906,7 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_  }  EXPORT_SYMBOL_GPL(saa7134_s_std_internal); -static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) +static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id)  {  	struct saa7134_fh *fh = priv; @@ -2009,11 +2014,11 @@ static int saa7134_g_tuner(struct file *file, void *priv,  	if (NULL != card_in(dev, n).name) {  		strcpy(t->name, "Television");  		t->type = V4L2_TUNER_ANALOG_TV; +		saa_call_all(dev, tuner, g_tuner, t);  		t->capability = V4L2_TUNER_CAP_NORM |  			V4L2_TUNER_CAP_STEREO |  			V4L2_TUNER_CAP_LANG1 |  			V4L2_TUNER_CAP_LANG2; -		t->rangehigh = 0xffffffffUL;  		t->rxsubchans = saa7134_tvaudio_getstereo(dev);  		t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);  	} @@ -2023,15 +2028,14 @@ static int saa7134_g_tuner(struct file *file, void *priv,  }  static int saa7134_s_tuner(struct file *file, void *priv, -					struct v4l2_tuner *t) +					const struct v4l2_tuner *t)  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; -	int rx, mode, err; +	int rx, mode; -	err = v4l2_prio_check(&dev->prio, fh->prio); -	if (0 != err) -		return err; +	if (0 != t->index) +		return -EINVAL;  	mode = dev->thread.mode;  	if (UNSET == mode) { @@ -2050,22 +2054,20 @@ static int saa7134_g_frequency(struct file *file, void *priv,  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; +	if (0 != f->tuner) +		return -EINVAL; +  	f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; -	f->frequency = dev->ctl_freq; +	saa_call_all(dev, tuner, g_frequency, f);  	return 0;  }  static int saa7134_s_frequency(struct file *file, void *priv, -					struct v4l2_frequency *f) +					const struct v4l2_frequency *f)  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; -	int err; - -	err = v4l2_prio_check(&dev->prio, fh->prio); -	if (0 != err) -		return err;  	if (0 != f->tuner)  		return -EINVAL; @@ -2074,7 +2076,6 @@ static int saa7134_s_frequency(struct file *file, void *priv,  	if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)  		return -EINVAL;  	mutex_lock(&dev->lock); -	dev->ctl_freq = f->frequency;  	saa_call_all(dev, tuner, s_frequency, f); @@ -2083,35 +2084,6 @@ static int saa7134_s_frequency(struct file *file, void *priv,  	return 0;  } -static int saa7134_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ -	strcpy(a->name, "audio"); -	return 0; -} - -static int saa7134_s_audio(struct file *file, void *priv, const struct v4l2_audio *a) -{ -	return 0; -} - -static int saa7134_g_priority(struct file *file, void *f, enum v4l2_priority *p) -{ -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; - -	*p = v4l2_prio_max(&dev->prio); -	return 0; -} - -static int saa7134_s_priority(struct file *file, void *f, -					enum v4l2_priority prio) -{ -	struct saa7134_fh *fh = f; -	struct saa7134_dev *dev = fh->dev; - -	return v4l2_prio_change(&dev->prio, &fh->prio, prio); -} -  static int saa7134_enum_fmt_vid_cap(struct file *file, void  *priv,  					struct v4l2_fmtdesc *f)  { @@ -2279,12 +2251,6 @@ static int saa7134_streamoff(struct file *file, void *priv,  	return 0;  } -static int saa7134_g_parm(struct file *file, void *fh, -				struct v4l2_streamparm *parm) -{ -	return 0; -} -  #ifdef CONFIG_VIDEO_ADV_DEBUG  static int vidioc_g_register (struct file *file, void *priv,  			      struct v4l2_dbg_register *reg) @@ -2300,7 +2266,7 @@ static int vidioc_g_register (struct file *file, void *priv,  }  static int vidioc_s_register (struct file *file, void *priv, -				struct v4l2_dbg_register *reg) +				const struct v4l2_dbg_register *reg)  {  	struct saa7134_fh *fh = priv;  	struct saa7134_dev *dev = fh->dev; @@ -2312,19 +2278,6 @@ static int vidioc_s_register (struct file *file, void *priv,  }  #endif -static int radio_querycap(struct file *file, void *priv, -					struct v4l2_capability *cap) -{ -	struct saa7134_fh *fh = file->private_data; -	struct saa7134_dev *dev = fh->dev; - -	strcpy(cap->driver, "saa7134"); -	strlcpy(cap->card, saa7134_boards[dev->board].name, sizeof(cap->card)); -	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); -	cap->capabilities = V4L2_CAP_TUNER; -	return 0; -} -  static int radio_g_tuner(struct file *file, void *priv,  					struct v4l2_tuner *t)  { @@ -2339,6 +2292,7 @@ static int radio_g_tuner(struct file *file, void *priv,  	t->type = V4L2_TUNER_RADIO;  	saa_call_all(dev, tuner, g_tuner, t); +	t->audmode &= V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO;  	if (dev->input->amux == TV) {  		t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);  		t->rxsubchans = (saa_readb(0x529) & 0x08) ? @@ -2347,7 +2301,7 @@ static int radio_g_tuner(struct file *file, void *priv,  	return 0;  }  static int radio_s_tuner(struct file *file, void *priv, -					struct v4l2_tuner *t) +					const struct v4l2_tuner *t)  {  	struct saa7134_fh *fh = file->private_data;  	struct saa7134_dev *dev = fh->dev; @@ -2377,26 +2331,12 @@ static int radio_g_input(struct file *filp, void *priv, unsigned int *i)  	return 0;  } -static int radio_g_audio(struct file *file, void *priv, -					struct v4l2_audio *a) -{ -	memset(a, 0, sizeof(*a)); -	strcpy(a->name, "Radio"); -	return 0; -} - -static int radio_s_audio(struct file *file, void *priv, -					const struct v4l2_audio *a) -{ -	return 0; -} -  static int radio_s_input(struct file *filp, void *priv, unsigned int i)  {  	return 0;  } -static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) +static int radio_s_std(struct file *file, void *fh, v4l2_std_id norm)  {  	return 0;  } @@ -2441,8 +2381,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {  	.vidioc_g_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap,  	.vidioc_try_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap,  	.vidioc_s_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap, -	.vidioc_g_audio			= saa7134_g_audio, -	.vidioc_s_audio			= saa7134_s_audio,  	.vidioc_cropcap			= saa7134_cropcap,  	.vidioc_reqbufs			= saa7134_reqbufs,  	.vidioc_querybuf		= saa7134_querybuf, @@ -2465,9 +2403,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {  	.vidioc_g_fbuf			= saa7134_g_fbuf,  	.vidioc_s_fbuf			= saa7134_s_fbuf,  	.vidioc_overlay			= saa7134_overlay, -	.vidioc_g_priority		= saa7134_g_priority, -	.vidioc_s_priority		= saa7134_s_priority, -	.vidioc_g_parm			= saa7134_g_parm,  	.vidioc_g_frequency		= saa7134_g_frequency,  	.vidioc_s_frequency		= saa7134_s_frequency,  #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -2486,12 +2421,10 @@ static const struct v4l2_file_operations radio_fops = {  };  static const struct v4l2_ioctl_ops radio_ioctl_ops = { -	.vidioc_querycap	= radio_querycap, +	.vidioc_querycap	= saa7134_querycap,  	.vidioc_g_tuner		= radio_g_tuner,  	.vidioc_enum_input	= radio_enum_input, -	.vidioc_g_audio		= radio_g_audio,  	.vidioc_s_tuner		= radio_s_tuner, -	.vidioc_s_audio		= radio_s_audio,  	.vidioc_s_input		= radio_s_input,  	.vidioc_s_std		= radio_s_std,  	.vidioc_queryctrl	= radio_queryctrl,  |