diff options
| author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-03-06 13:50:07 -0300 | 
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 12:43:12 -0300 | 
| commit | 79f94878bb8013b4043d51ec241d7fdc9a6a0312 (patch) | |
| tree | fccc57dd7adbb6dbd3ac62c44ab409dd11c7c186 | |
| parent | bec2aec56561b70787ef62f070988594bd6d1b5f (diff) | |
V4L/DVB (10883): radio-gemtek-pci: convert to v4l2_device.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/radio/radio-gemtek-pci.c | 330 | 
1 files changed, 160 insertions, 170 deletions
| diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 0c96bf8525b0..dbc6097a51e5 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -45,34 +45,26 @@  #include <linux/init.h>  #include <linux/pci.h>  #include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h>  #include <linux/errno.h> -  #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */ -#define RADIO_VERSION KERNEL_VERSION(0,0,2) - -static struct v4l2_queryctrl radio_qctrl[] = { -	{ -		.id            = V4L2_CID_AUDIO_MUTE, -		.name          = "Mute", -		.minimum       = 0, -		.maximum       = 1, -		.default_value = 1, -		.type          = V4L2_CTRL_TYPE_BOOLEAN, -	},{ -		.id            = V4L2_CID_AUDIO_VOLUME, -		.name          = "Volume", -		.minimum       = 0, -		.maximum       = 65535, -		.step          = 65535, -		.default_value = 0xff, -		.type          = V4L2_CTRL_TYPE_INTEGER, -	} -}; +#include <linux/io.h> +#include <linux/uaccess.h> +#include <media/v4l2-device.h> +#include <media/v4l2-ioctl.h> -#include <asm/io.h> -#include <asm/uaccess.h> +MODULE_AUTHOR("Vladimir Shebordaev <vshebordaev@mail.ru>"); +MODULE_DESCRIPTION("The video4linux driver for the Gemtek PCI Radio Card"); +MODULE_LICENSE("GPL"); + +static int nr_radio = -1; +static int mx = 1; + +module_param(mx, bool, 0); +MODULE_PARM_DESC(mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not"); +module_param(nr_radio, int, 0); +MODULE_PARM_DESC(nr_radio, "video4linux device number to use"); + +#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)  #ifndef PCI_VENDOR_ID_GEMTEK  #define PCI_VENDOR_ID_GEMTEK 0x5046 @@ -90,8 +82,11 @@ static struct v4l2_queryctrl radio_qctrl[] = {  #define GEMTEK_PCI_RANGE_HIGH (108*16000)  #endif -struct gemtek_pci_card { -	struct video_device *videodev; +struct gemtek_pci { +	struct v4l2_device v4l2_dev; +	struct video_device vdev; +	struct mutex lock; +	struct pci_dev *pdev;  	u32 iobase;  	u32 length; @@ -100,116 +95,133 @@ struct gemtek_pci_card {  	u8  mute;  }; -static int nr_radio = -1; -static unsigned long in_use; +static inline struct gemtek_pci *to_gemtek_pci(struct v4l2_device *v4l2_dev) +{ +	return container_of(v4l2_dev, struct gemtek_pci, v4l2_dev); +} -static inline u8 gemtek_pci_out( u16 value, u32 port ) +static inline u8 gemtek_pci_out(u16 value, u32 port)  { -	outw( value, port ); +	outw(value, port);  	return (u8)value;  } -#define _b0( v ) *((u8 *)&v) -static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) +#define _b0(v) (*((u8 *)&v)) + +static void __gemtek_pci_cmd(u16 value, u32 port, u8 *last_byte, int keep)  { -	register u8 byte = *last_byte; +	u8 byte = *last_byte; -	if ( !value ) { -		if ( !keep ) +	if (!value) { +		if (!keep)  			value = (u16)port;  		byte &= 0xfd;  	} else  		byte |= 2; -	_b0( value ) = byte; -	outw( value, port ); +	_b0(value) = byte; +	outw(value, port);  	byte |= 1; -	_b0( value ) = byte; -	outw( value, port ); +	_b0(value) = byte; +	outw(value, port);  	byte &= 0xfe; -	_b0( value ) = byte; -	outw( value, port ); +	_b0(value) = byte; +	outw(value, port);  	*last_byte = byte;  } -static inline void gemtek_pci_nil( u32 port, u8 *last_byte ) +static inline void gemtek_pci_nil(u32 port, u8 *last_byte)  { -	__gemtek_pci_cmd( 0x00, port, last_byte, false ); +	__gemtek_pci_cmd(0x00, port, last_byte, false);  } -static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte ) +static inline void gemtek_pci_cmd(u16 cmd, u32 port, u8 *last_byte)  { -	__gemtek_pci_cmd( cmd, port, last_byte, true ); +	__gemtek_pci_cmd(cmd, port, last_byte, true);  } -static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency ) +static void gemtek_pci_setfrequency(struct gemtek_pci *card, unsigned long frequency)  { -	register int i; -	register u32 value = frequency / 200 + 856; -	register u16 mask = 0x8000; +	int i; +	u32 value = frequency / 200 + 856; +	u16 mask = 0x8000;  	u8 last_byte;  	u32 port = card->iobase; -	last_byte = gemtek_pci_out( 0x06, port ); +	mutex_lock(&card->lock); +	card->current_frequency = frequency; +	last_byte = gemtek_pci_out(0x06, port);  	i = 0;  	do { -		gemtek_pci_nil( port, &last_byte ); +		gemtek_pci_nil(port, &last_byte);  		i++; -	} while ( i < 9 ); +	} while (i < 9);  	i = 0;  	do { -		gemtek_pci_cmd( value & mask, port, &last_byte ); +		gemtek_pci_cmd(value & mask, port, &last_byte);  		mask >>= 1;  		i++; -	} while ( i < 16 ); +	} while (i < 16); -	outw( 0x10, port ); +	outw(0x10, port); +	mutex_unlock(&card->lock);  } -static inline void gemtek_pci_mute( struct gemtek_pci_card *card ) +static void gemtek_pci_mute(struct gemtek_pci *card)  { -	outb( 0x1f, card->iobase ); +	mutex_lock(&card->lock); +	outb(0x1f, card->iobase);  	card->mute = true; +	mutex_unlock(&card->lock);  } -static inline void gemtek_pci_unmute( struct gemtek_pci_card *card ) +static void gemtek_pci_unmute(struct gemtek_pci *card)  { -	if ( card->mute ) { -		gemtek_pci_setfrequency( card, card->current_frequency ); +	mutex_lock(&card->lock); +	if (card->mute) { +		gemtek_pci_setfrequency(card, card->current_frequency);  		card->mute = false;  	} +	mutex_unlock(&card->lock);  } -static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card ) +static int gemtek_pci_getsignal(struct gemtek_pci *card)  { -	return ( inb( card->iobase ) & 0x08 ) ? 0 : 1; +	int sig; + +	mutex_lock(&card->lock); +	sig = (inb(card->iobase) & 0x08) ? 0 : 1; +	mutex_unlock(&card->lock); +	return sig;  }  static int vidioc_querycap(struct file *file, void *priv,  					struct v4l2_capability *v)  { +	struct gemtek_pci *card = video_drvdata(file); +  	strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));  	strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card)); -	sprintf(v->bus_info, "ISA"); +	snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(card->pdev));  	v->version = RADIO_VERSION; -	v->capabilities = V4L2_CAP_TUNER; +	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;  	return 0;  }  static int vidioc_g_tuner(struct file *file, void *priv,  					struct v4l2_tuner *v)  { -	struct gemtek_pci_card *card = video_drvdata(file); +	struct gemtek_pci *card = video_drvdata(file);  	if (v->index > 0)  		return -EINVAL; -	strcpy(v->name, "FM"); +	strlcpy(v->name, "FM", sizeof(v->name));  	v->type = V4L2_TUNER_RADIO;  	v->rangelow = GEMTEK_PCI_RANGE_LOW;  	v->rangehigh = GEMTEK_PCI_RANGE_HIGH; @@ -223,21 +235,18 @@ static int vidioc_g_tuner(struct file *file, void *priv,  static int vidioc_s_tuner(struct file *file, void *priv,  					struct v4l2_tuner *v)  { -	if (v->index > 0) -		return -EINVAL; -	return 0; +	return v->index ? -EINVAL : 0;  }  static int vidioc_s_frequency(struct file *file, void *priv,  					struct v4l2_frequency *f)  { -	struct gemtek_pci_card *card = video_drvdata(file); +	struct gemtek_pci *card = video_drvdata(file); -	if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) || -			(f->frequency > GEMTEK_PCI_RANGE_HIGH) ) +	if (f->frequency < GEMTEK_PCI_RANGE_LOW || +	    f->frequency > GEMTEK_PCI_RANGE_HIGH)  		return -EINVAL;  	gemtek_pci_setfrequency(card, f->frequency); -	card->current_frequency = f->frequency;  	card->mute = false;  	return 0;  } @@ -245,7 +254,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,  static int vidioc_g_frequency(struct file *file, void *priv,  					struct v4l2_frequency *f)  { -	struct gemtek_pci_card *card = video_drvdata(file); +	struct gemtek_pci *card = video_drvdata(file);  	f->type = V4L2_TUNER_RADIO;  	f->frequency = card->current_frequency; @@ -255,13 +264,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,  static int vidioc_queryctrl(struct file *file, void *priv,  					struct v4l2_queryctrl *qc)  { -	int i; -	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { -		if (qc->id && qc->id == radio_qctrl[i].id) { -			memcpy(qc, &(radio_qctrl[i]), -						sizeof(*qc)); -			return 0; -		} +	switch (qc->id) { +	case V4L2_CID_AUDIO_MUTE: +		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); +	case V4L2_CID_AUDIO_VOLUME: +		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);  	}  	return -EINVAL;  } @@ -269,7 +276,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,  static int vidioc_g_ctrl(struct file *file, void *priv,  					struct v4l2_control *ctrl)  { -	struct gemtek_pci_card *card = video_drvdata(file); +	struct gemtek_pci *card = video_drvdata(file);  	switch (ctrl->id) {  	case V4L2_CID_AUDIO_MUTE: @@ -288,7 +295,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,  static int vidioc_s_ctrl(struct file *file, void *priv,  					struct v4l2_control *ctrl)  { -	struct gemtek_pci_card *card = video_drvdata(file); +	struct gemtek_pci *card = video_drvdata(file);  	switch (ctrl->id) {  	case V4L2_CID_AUDIO_MUTE: @@ -307,17 +314,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,  	return -EINVAL;  } -static int vidioc_g_audio(struct file *file, void *priv, -					struct v4l2_audio *a) -{ -	if (a->index > 1) -		return -EINVAL; - -	strcpy(a->name, "Radio"); -	a->capability = V4L2_AUDCAP_STEREO; -	return 0; -} -  static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)  {  	*i = 0; @@ -326,17 +322,22 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)  static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)  { -	if (i != 0) -		return -EINVAL; +	return i ? -EINVAL : 0; +} + +static int vidioc_g_audio(struct file *file, void *priv, +					struct v4l2_audio *a) +{ +	a->index = 0; +	strlcpy(a->name, "Radio", sizeof(a->name)); +	a->capability = V4L2_AUDCAP_STEREO;  	return 0;  }  static int vidioc_s_audio(struct file *file, void *priv,  					struct v4l2_audio *a)  { -	if (a->index != 0) -		return -EINVAL; -	return 0; +	return a->index ? -EINVAL : 0;  }  enum { @@ -354,25 +355,22 @@ static struct pci_device_id gemtek_pci_id[] =  	{ 0 }  }; -MODULE_DEVICE_TABLE( pci, gemtek_pci_id ); - -static int mx = 1; +MODULE_DEVICE_TABLE(pci, gemtek_pci_id); -static int gemtek_pci_exclusive_open(struct file *file) +static int gemtek_pci_open(struct file *file)  { -	return test_and_set_bit(0, &in_use) ? -EBUSY : 0; +	return 0;  } -static int gemtek_pci_exclusive_release(struct file *file) +static int gemtek_pci_release(struct file *file)  { -	clear_bit(0, &in_use);  	return 0;  }  static const struct v4l2_file_operations gemtek_pci_fops = {  	.owner		= THIS_MODULE, -	.open           = gemtek_pci_exclusive_open, -	.release        = gemtek_pci_exclusive_release, +	.open           = gemtek_pci_open, +	.release        = gemtek_pci_release,  	.ioctl		= video_ioctl2,  }; @@ -391,108 +389,100 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {  	.vidioc_s_ctrl      = vidioc_s_ctrl,  }; -static struct video_device vdev_template = { -	.name          	= "Gemtek PCI Radio", -	.fops          	= &gemtek_pci_fops, -	.ioctl_ops 	= &gemtek_pci_ioctl_ops, -	.release	= video_device_release_empty, -}; - -static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) +static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)  { -	struct gemtek_pci_card *card; -	struct video_device *devradio; +	struct gemtek_pci *card; +	struct v4l2_device *v4l2_dev; +	int res; -	if ( (card = kzalloc( sizeof( struct gemtek_pci_card ), GFP_KERNEL )) == NULL ) { -		printk( KERN_ERR "gemtek_pci: out of memory\n" ); +	card = kzalloc(sizeof(struct gemtek_pci), GFP_KERNEL); +	if (card == NULL) { +		dev_err(&pdev->dev, "out of memory\n");  		return -ENOMEM;  	} -	if ( pci_enable_device( pci_dev ) ) -		goto err_pci; +	v4l2_dev = &card->v4l2_dev; +	mutex_init(&card->lock); +	card->pdev = pdev; -	card->iobase = pci_resource_start( pci_dev, 0 ); -	card->length = pci_resource_len( pci_dev, 0 ); +	strlcpy(v4l2_dev->name, "gemtek_pci", sizeof(v4l2_dev->name)); -	if ( request_region( card->iobase, card->length, card_names[pci_id->driver_data] ) == NULL ) { -		printk( KERN_ERR "gemtek_pci: i/o port already in use\n" ); -		goto err_pci; +	res = v4l2_device_register(&pdev->dev, v4l2_dev); +	if (res < 0) { +		v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); +		kfree(card); +		return res;  	} -	pci_set_drvdata( pci_dev, card ); +	if (pci_enable_device(pdev)) +		goto err_pci; -	if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) { -		printk( KERN_ERR "gemtek_pci: out of memory\n" ); -		goto err_video; +	card->iobase = pci_resource_start(pdev, 0); +	card->length = pci_resource_len(pdev, 0); + +	if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) { +		v4l2_err(v4l2_dev, "i/o port already in use\n"); +		goto err_pci;  	} -	*devradio = vdev_template; -	if (video_register_device(devradio, VFL_TYPE_RADIO, nr_radio) < 0) { -		kfree( devradio ); +	strlcpy(card->vdev.name, v4l2_dev->name, sizeof(card->vdev.name)); +	card->vdev.v4l2_dev = v4l2_dev; +	card->vdev.fops = &gemtek_pci_fops; +	card->vdev.ioctl_ops = &gemtek_pci_ioctl_ops; +	card->vdev.release = video_device_release_empty; +	video_set_drvdata(&card->vdev, card); + +	if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)  		goto err_video; -	} -	card->videodev = devradio; -	video_set_drvdata(devradio, card); -	gemtek_pci_mute( card ); +	gemtek_pci_mute(card); -	printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", -		pci_dev->revision, card->iobase, card->iobase + card->length - 1 ); +	v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", +		pdev->revision, card->iobase, card->iobase + card->length - 1);  	return 0;  err_video: -	release_region( card->iobase, card->length ); +	release_region(card->iobase, card->length);  err_pci: -	kfree( card ); +	v4l2_device_unregister(v4l2_dev); +	kfree(card);  	return -ENODEV;  } -static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) +static void __devexit gemtek_pci_remove(struct pci_dev *pdev)  { -	struct gemtek_pci_card *card = pci_get_drvdata( pci_dev ); +	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); +	struct gemtek_pci *card = to_gemtek_pci(v4l2_dev); -	video_unregister_device( card->videodev ); -	kfree( card->videodev ); +	video_unregister_device(&card->vdev); +	v4l2_device_unregister(v4l2_dev); -	release_region( card->iobase, card->length ); +	release_region(card->iobase, card->length); -	if ( mx ) -		gemtek_pci_mute( card ); +	if (mx) +		gemtek_pci_mute(card); -	kfree( card ); - -	pci_set_drvdata( pci_dev, NULL ); +	kfree(card);  } -static struct pci_driver gemtek_pci_driver = -{ +static struct pci_driver gemtek_pci_driver = {  	.name		= "gemtek_pci",  	.id_table	= gemtek_pci_id,  	.probe		= gemtek_pci_probe,  	.remove		= __devexit_p(gemtek_pci_remove),  }; -static int __init gemtek_pci_init_module( void ) +static int __init gemtek_pci_init(void)  { -	return pci_register_driver( &gemtek_pci_driver ); +	return pci_register_driver(&gemtek_pci_driver);  } -static void __exit gemtek_pci_cleanup_module( void ) +static void __exit gemtek_pci_exit(void)  {  	pci_unregister_driver(&gemtek_pci_driver);  } -MODULE_AUTHOR( "Vladimir Shebordaev <vshebordaev@mail.ru>" ); -MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" ); -MODULE_LICENSE("GPL"); - -module_param(mx, bool, 0); -MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" ); -module_param(nr_radio, int, 0); -MODULE_PARM_DESC( nr_radio, "video4linux device number to use"); - -module_init( gemtek_pci_init_module ); -module_exit( gemtek_pci_cleanup_module ); - +module_init(gemtek_pci_init); +module_exit(gemtek_pci_exit); | 
