⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radio-gemtek.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	return 1;}/* * Automatic probing for card. */static int gemtek_probe(void){	int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };	int i;	if (!probe) {		printk(KERN_INFO "Automatic device probing disabled.\n");		return -1;	}	printk(KERN_INFO "Automatic device probing enabled.\n");	for (i = 0; i < ARRAY_SIZE(ioports); ++i) {		printk(KERN_INFO "Trying I/O port 0x%x...\n", ioports[i]);		if (!request_region(ioports[i], 1, "gemtek-probe")) {			printk(KERN_WARNING "I/O port 0x%x busy!\n",			       ioports[i]);			continue;		}		if (gemtek_verify(ioports[i])) {			printk(KERN_INFO "Card found from I/O port "			       "0x%x!\n", ioports[i]);			release_region(ioports[i], 1);			io = ioports[i];			return io;		}		release_region(ioports[i], 1);	}	printk(KERN_ERR "Automatic probing failed!\n");	return -1;}/* * Video 4 Linux stuff. */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,	}};static int gemtek_exclusive_open(struct inode *inode, struct file *file){	return test_and_set_bit(0, &in_use) ? -EBUSY : 0;}static int gemtek_exclusive_release(struct inode *inode, struct file *file){	clear_bit(0, &in_use);	return 0;}static const struct file_operations gemtek_fops = {	.owner		= THIS_MODULE,	.open		= gemtek_exclusive_open,	.release	= gemtek_exclusive_release,	.ioctl		= video_ioctl2,#ifdef CONFIG_COMPAT	.compat_ioctl	= v4l_compat_ioctl32,#endif	.llseek		= no_llseek};static int vidioc_querycap(struct file *file, void *priv,			   struct v4l2_capability *v){	strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));	strlcpy(v->card, "GemTek", sizeof(v->card));	sprintf(v->bus_info, "ISA");	v->version = RADIO_VERSION;	v->capabilities = V4L2_CAP_TUNER;	return 0;}static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v){	if (v->index > 0)		return -EINVAL;	strcpy(v->name, "FM");	v->type = V4L2_TUNER_RADIO;	v->rangelow = GEMTEK_LOWFREQ;	v->rangehigh = GEMTEK_HIGHFREQ;	v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;	v->signal = 0xffff * gemtek_getsigstr();	if (v->signal) {		v->audmode = V4L2_TUNER_MODE_STEREO;		v->rxsubchans = V4L2_TUNER_SUB_STEREO;	} else {		v->audmode = V4L2_TUNER_MODE_MONO;		v->rxsubchans = V4L2_TUNER_SUB_MONO;	}	return 0;}static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v){	if (v->index > 0)		return -EINVAL;	return 0;}static int vidioc_s_frequency(struct file *file, void *priv,			      struct v4l2_frequency *f){	struct gemtek_device *rt = video_drvdata(file);	gemtek_setfreq(rt, f->frequency);	return 0;}static int vidioc_g_frequency(struct file *file, void *priv,			      struct v4l2_frequency *f){	struct gemtek_device *rt = video_drvdata(file);	f->type = V4L2_TUNER_RADIO;	f->frequency = rt->lastfreq;	return 0;}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;		}	}	return -EINVAL;}static int vidioc_g_ctrl(struct file *file, void *priv,			 struct v4l2_control *ctrl){	struct gemtek_device *rt = video_drvdata(file);	switch (ctrl->id) {	case V4L2_CID_AUDIO_MUTE:		ctrl->value = rt->muted;		return 0;	case V4L2_CID_AUDIO_VOLUME:		if (rt->muted)			ctrl->value = 0;		else			ctrl->value = 65535;		return 0;	}	return -EINVAL;}static int vidioc_s_ctrl(struct file *file, void *priv,			 struct v4l2_control *ctrl){	struct gemtek_device *rt = video_drvdata(file);	switch (ctrl->id) {	case V4L2_CID_AUDIO_MUTE:		if (ctrl->value)			gemtek_mute(rt);		else			gemtek_unmute(rt);		return 0;	case V4L2_CID_AUDIO_VOLUME:		if (ctrl->value)			gemtek_unmute(rt);		else			gemtek_mute(rt);		return 0;	}	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;	return 0;}static int vidioc_s_input(struct file *filp, void *priv, unsigned int i){	if (i != 0)		return -EINVAL;	return 0;}static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a){	if (a->index != 0)		return -EINVAL;	return 0;}static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {	.vidioc_querycap	= vidioc_querycap,	.vidioc_g_tuner		= vidioc_g_tuner,	.vidioc_s_tuner		= vidioc_s_tuner,	.vidioc_g_audio		= vidioc_g_audio,	.vidioc_s_audio		= vidioc_s_audio,	.vidioc_g_input		= vidioc_g_input,	.vidioc_s_input		= vidioc_s_input,	.vidioc_g_frequency	= vidioc_g_frequency,	.vidioc_s_frequency	= vidioc_s_frequency,	.vidioc_queryctrl	= vidioc_queryctrl,	.vidioc_g_ctrl		= vidioc_g_ctrl,	.vidioc_s_ctrl		= vidioc_s_ctrl};static struct video_device gemtek_radio = {	.name		= "GemTek Radio card",	.fops		= &gemtek_fops,	.ioctl_ops 	= &gemtek_ioctl_ops,	.release	= video_device_release_empty,};/* * Initialization / cleanup related stuff. *//* * Initilize card. */static int __init gemtek_init(void){	printk(KERN_INFO RADIO_BANNER "\n");	spin_lock_init(&lock);	gemtek_probe();	if (io) {		if (!request_region(io, 1, "gemtek")) {			printk(KERN_ERR "I/O port 0x%x already in use.\n", io);			return -EBUSY;		}		if (!gemtek_verify(io))			printk(KERN_WARNING "Card at I/O port 0x%x does not "			       "respond properly, check your "			       "configuration.\n", io);		else			printk(KERN_INFO "Using I/O port 0x%x.\n", io);	} else if (probe) {		printk(KERN_ERR "Automatic probing failed and no "		       "fixed I/O port defined.\n");		return -ENODEV;	} else {		printk(KERN_ERR "Automatic probing disabled but no fixed "		       "I/O port defined.");		return -EINVAL;	}	video_set_drvdata(&gemtek_radio, &gemtek_unit);	if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) {		release_region(io, 1);		return -EBUSY;	}	/* Set defaults */	gemtek_unit.lastfreq = GEMTEK_LOWFREQ;	gemtek_unit.bu2614data = 0;	if (initmute)		gemtek_mute(&gemtek_unit);	return 0;}/* * Module cleanup */static void __exit gemtek_exit(void){	if (shutdown) {		hardmute = 1;	/* Turn off PLL */		gemtek_mute(&gemtek_unit);	} else {		printk(KERN_INFO "Module unloaded but card not muted!\n");	}	video_unregister_device(&gemtek_radio);	release_region(io, 1);}module_init(gemtek_init);module_exit(gemtek_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -