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

📄 arv.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
			ar->line_bytes = AR_LINE_BYTES_VGA;			if (vga_interlace)				ar->mode = AR_MODE_INTERLACE;			else				ar->mode = AR_MODE_NORMAL;		} else {			ar->size = AR_SIZE_QVGA;			ar->frame_bytes = AR_FRAME_BYTES_QVGA;			ar->line_bytes = AR_LINE_BYTES_QVGA;			ar->mode = AR_MODE_INTERLACE;		}		mutex_unlock(&ar->lock);		return 0;	}	case VIDIOCGFBUF:		DEBUG(1, "VIDIOCGFBUF:\n");		return -EINVAL;	case VIDIOCSFBUF:		DEBUG(1, "VIDIOCSFBUF:\n");		return -EINVAL;	case VIDIOCKEY:		DEBUG(1, "VIDIOCKEY:\n");		return 0;	case VIDIOCGFREQ:		DEBUG(1, "VIDIOCGFREQ:\n");		return -EINVAL;	case VIDIOCSFREQ:		DEBUG(1, "VIDIOCSFREQ:\n");		return -EINVAL;	case VIDIOCGAUDIO:		DEBUG(1, "VIDIOCGAUDIO:\n");		return -EINVAL;	case VIDIOCSAUDIO:		DEBUG(1, "VIDIOCSAUDIO:\n");		return -EINVAL;	case VIDIOCSYNC:		DEBUG(1, "VIDIOCSYNC:\n");		return -EINVAL;	case VIDIOCMCAPTURE:		DEBUG(1, "VIDIOCMCAPTURE:\n");		return -EINVAL;	case VIDIOCGMBUF:		DEBUG(1, "VIDIOCGMBUF:\n");		return -EINVAL;	case VIDIOCGUNIT:		DEBUG(1, "VIDIOCGUNIT:\n");		return -EINVAL;	case VIDIOCGCAPTURE:		DEBUG(1, "VIDIOCGCAPTURE:\n");		return -EINVAL;	case VIDIOCSCAPTURE:		DEBUG(1, "VIDIOCSCAPTURE:\n");		return -EINVAL;	case VIDIOCSPLAYMODE:		DEBUG(1, "VIDIOCSPLAYMODE:\n");		return -EINVAL;	case VIDIOCSWRITEMODE:		DEBUG(1, "VIDIOCSWRITEMODE:\n");		return -EINVAL;	case VIDIOCGPLAYINFO:		DEBUG(1, "VIDIOCGPLAYINFO:\n");		return -EINVAL;	case VIDIOCSMICROCODE:		DEBUG(1, "VIDIOCSMICROCODE:\n");		return -EINVAL;	case VIDIOCGVBIFMT:		DEBUG(1, "VIDIOCGVBIFMT:\n");		return -EINVAL;	case VIDIOCSVBIFMT:		DEBUG(1, "VIDIOCSVBIFMT:\n");		return -EINVAL;	default:		DEBUG(1, "Unknown ioctl(0x%08x)\n", cmd);		return -ENOIOCTLCMD;	}	return 0;}static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd,		    unsigned long arg){	return video_usercopy(inode, file, cmd, arg, ar_do_ioctl);}#if USE_INT/* * Interrupt handler */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)#elsestatic void ar_interrupt(int irq, void *dev)#endif{	struct ar_device *ar = dev;	unsigned int line_count;	unsigned int line_number;	unsigned int arvcr1;	line_count = ar_inl(ARVHCOUNT);			/* line number */	if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {		/* operations for interlace mode */		if ( line_count < (AR_HEIGHT_VGA/2) ) 	/* even line */			line_number = (line_count << 1);		else 					/* odd line */			line_number =			(((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1);	} else {		line_number = line_count;	}	if (line_number == 0) {		/*		 * It is an interrupt for line 0.		 * we have to start capture.		 */		disable_dma();#if 0 /* keep */		ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);	/* needless? */#endif		memcpy(ar->frame[0], ar->line_buff, ar->line_bytes);#if 0 /* keep */		ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);#endif		enable_dma();		ar->start_capture = 1;			/* during capture */		return;	}	if (ar->start_capture == 1 && line_number <= (ar->height - 1)) {		disable_dma();		memcpy(ar->frame[line_number], ar->line_buff, ar->line_bytes);		/*		 * if captured all line of a frame, disable AR interrupt		 * and wake a process up.		 */		if (line_number == (ar->height - 1)) { 	/* end  of line */			ar->start_capture = 0;			/* disable AR interrupt request */			arvcr1 = ar_inl(ARVCR1);			arvcr1 &= ~ARVCR1_HIEN;		/* clear int. flag */			ar_outl(arvcr1, ARVCR1);	/* disable */			wake_up_interruptible(&ar->wait);		} else {#if 0 /* keep */			ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);			ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);#endif			enable_dma();		}	}}#endif/* * ar_initialize() * 	ar_initialize() is called by video_register_device() and *	initializes AR LSI and peripherals. * *	-1 is returned in all failures. *	0 is returned in success. * */static int ar_initialize(struct video_device *dev){	struct ar_device *ar = video_get_drvdata(dev);	unsigned long cr = 0;	int i,found=0;	DEBUG(1, "ar_initialize:\n");	/*	 * initialize AR LSI	 */	ar_outl(0, ARVCR0);		/* assert reset of AR LSI */	for (i = 0; i < 0x18; i++)	/* wait for over 10 cycles @ 27MHz */		cpu_relax();	ar_outl(ARVCR0_RST, ARVCR0);	/* negate reset of AR LSI (enable) */	for (i = 0; i < 0x40d; i++)	/* wait for over 420 cycles @ 27MHz */		cpu_relax();	/* AR uses INT3 of CPU as interrupt pin. */	ar_outl(ARINTSEL_INT3, ARINTSEL);	if (ar->size == AR_SIZE_QVGA)		cr |= ARVCR1_QVGA;	if (ar->mode == AR_MODE_NORMAL)		cr |= ARVCR1_NORMAL;	ar_outl(cr, ARVCR1);	/*	 * Initialize IIC so that CPU can communicate with AR LSI,	 * and send boot commands to AR LSI.	 */	init_iic();	for (i = 0; i < 0x100000; i++) {	/* > 0xa1d10,  56ms */		if ((ar_inl(ARVCR0) & ARVCR0_VDS)) {	/* VSYNC */			found = 1;			break;		}	}	if (found == 0)		return -ENODEV;	printk("arv: Initializing ");	iic(2,0x78,0x11,0x01,0x00);	/* start */	iic(3,0x78,0x12,0x00,0x06);	iic(3,0x78,0x12,0x12,0x30);	iic(3,0x78,0x12,0x15,0x58);	iic(3,0x78,0x12,0x17,0x30);	printk(".");	iic(3,0x78,0x12,0x1a,0x97);	iic(3,0x78,0x12,0x1b,0xff);	iic(3,0x78,0x12,0x1c,0xff);	iic(3,0x78,0x12,0x26,0x10);	iic(3,0x78,0x12,0x27,0x00);	printk(".");	iic(2,0x78,0x34,0x02,0x00);	iic(2,0x78,0x7a,0x10,0x00);	iic(2,0x78,0x80,0x39,0x00);	iic(2,0x78,0x81,0xe6,0x00);	iic(2,0x78,0x8d,0x00,0x00);	printk(".");	iic(2,0x78,0x8e,0x0c,0x00);	iic(2,0x78,0x8f,0x00,0x00);#if 0 /* keep */	iic(2,0x78,0x90,0x00,0x00);	/* AWB on=1 off=0 */#endif	iic(2,0x78,0x93,0x01,0x00);	iic(2,0x78,0x94,0xcd,0x00);	iic(2,0x78,0x95,0x00,0x00);	printk(".");	iic(2,0x78,0x96,0xa0,0x00);	iic(2,0x78,0x97,0x00,0x00);	iic(2,0x78,0x98,0x60,0x00);	iic(2,0x78,0x99,0x01,0x00);	iic(2,0x78,0x9a,0x19,0x00);	printk(".");	iic(2,0x78,0x9b,0x02,0x00);	iic(2,0x78,0x9c,0xe8,0x00);	iic(2,0x78,0x9d,0x02,0x00);	iic(2,0x78,0x9e,0x2e,0x00);	iic(2,0x78,0xb8,0x78,0x00);	iic(2,0x78,0xba,0x05,0x00);#if 0 /* keep */	iic(2,0x78,0x83,0x8c,0x00);	/* brightness */#endif	printk(".");	/* color correction */	iic(3,0x78,0x49,0x00,0x95);	/* a		*/	iic(3,0x78,0x49,0x01,0x96);	/* b		*/	iic(3,0x78,0x49,0x03,0x85);	/* c		*/	iic(3,0x78,0x49,0x04,0x97);	/* d		*/	iic(3,0x78,0x49,0x02,0x7e);	/* e(Lo)	*/	iic(3,0x78,0x49,0x05,0xa4);	/* f(Lo)	*/	iic(3,0x78,0x49,0x06,0x04);	/* e(Hi)	*/	iic(3,0x78,0x49,0x07,0x04);	/* e(Hi)	*/	iic(2,0x78,0x48,0x01,0x00);	/* on=1 off=0	*/	printk(".");	iic(2,0x78,0x11,0x00,0x00);	/* end */	printk(" done\n");	return 0;}void ar_release(struct video_device *vfd){	struct ar_device *ar = video_get_drvdata(vfd);	mutex_lock(&ar->lock);	video_device_release(vfd);}/**************************************************************************** * * Video4Linux Module functions * ****************************************************************************/static struct ar_device ardev;static int ar_exclusive_open(struct inode *inode, struct file *file){	return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0;}static int ar_exclusive_release(struct inode *inode, struct file *file){	clear_bit(0, &ardev.in_use);	return 0;}static const struct file_operations ar_fops = {	.owner		= THIS_MODULE,	.open		= ar_exclusive_open,	.release	= ar_exclusive_release,	.read		= ar_read,	.ioctl		= ar_ioctl,#ifdef CONFIG_COMPAT	.compat_ioctl	= v4l_compat_ioctl32,#endif	.llseek		= no_llseek,};static struct video_device ar_template = {	.name		= "Colour AR VGA",	.fops		= &ar_fops,	.release	= ar_release,	.minor		= -1,};#define ALIGN4(x)	((((int)(x)) & 0x3) == 0)static int __init ar_init(void){	struct ar_device *ar;	int ret;	int i;	DEBUG(1, "ar_init:\n");	ret = -EIO;	printk(KERN_INFO "arv: Colour AR VGA driver %s\n", VERSION);	ar = &ardev;	memset(ar, 0, sizeof(struct ar_device));#if USE_INT	/* allocate a DMA buffer for 1 line.  */	ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);	if (ar->line_buff == NULL || ! ALIGN4(ar->line_buff)) {		printk("arv: buffer allocation failed for DMA.\n");		ret = -ENOMEM;		goto out_end;	}#endif	/* allocate buffers for a frame */	for (i = 0; i < MAX_AR_HEIGHT; i++) {		ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);		if (ar->frame[i] == NULL || ! ALIGN4(ar->frame[i])) {			printk("arv: buffer allocation failed for frame.\n");			ret = -ENOMEM;			goto out_line_buff;		}	}	ar->vdev = video_device_alloc();	if (!ar->vdev) {		printk(KERN_ERR "arv: video_device_alloc() failed\n");		return -ENOMEM;	}	memcpy(ar->vdev, &ar_template, sizeof(ar_template));	video_set_drvdata(ar->vdev, ar);	if (vga) {		ar->width 	= AR_WIDTH_VGA;		ar->height 	= AR_HEIGHT_VGA;		ar->size 	= AR_SIZE_VGA;		ar->frame_bytes = AR_FRAME_BYTES_VGA;		ar->line_bytes	= AR_LINE_BYTES_VGA;		if (vga_interlace)			ar->mode = AR_MODE_INTERLACE;		else			ar->mode = AR_MODE_NORMAL;	} else {		ar->width 	= AR_WIDTH_QVGA;		ar->height 	= AR_HEIGHT_QVGA;		ar->size 	= AR_SIZE_QVGA;		ar->frame_bytes = AR_FRAME_BYTES_QVGA;		ar->line_bytes	= AR_LINE_BYTES_QVGA;		ar->mode	= AR_MODE_INTERLACE;	}	mutex_init(&ar->lock);	init_waitqueue_head(&ar->wait);#if USE_INT	if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {		printk("arv: request_irq(%d) failed.\n", M32R_IRQ_INT3);		ret = -EIO;		goto out_irq;	}#endif	if (ar_initialize(ar->vdev) != 0) {		printk("arv: M64278 not found.\n");		ret = -ENODEV;		goto out_dev;	}	/*	 * ok, we can initialize h/w according to parameters,	 * so register video device as a frame grabber type.	 * device is named "video[0-64]".	 * video_register_device() initializes h/w using ar_initialize().	 */	if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {		/* return -1, -ENFILE(full) or others */		printk("arv: register video (Colour AR) failed.\n");		ret = -ENODEV;		goto out_dev;	}	printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",		ar->vdev->num, M32R_IRQ_INT3, freq);	return 0;out_dev:#if USE_INT	free_irq(M32R_IRQ_INT3, ar);out_irq:#endif	for (i = 0; i < MAX_AR_HEIGHT; i++)		kfree(ar->frame[i]);out_line_buff:#if USE_INT	kfree(ar->line_buff);out_end:#endif	return ret;}static int __init ar_init_module(void){	freq = (boot_cpu_data.bus_clock / 1000000);	printk("arv: Bus clock %d\n", freq);	if (freq != 50 && freq != 75)		freq = DEFAULT_FREQ;	return ar_init();}static void __exit ar_cleanup_module(void){	struct ar_device *ar;	int i;	ar = &ardev;	video_unregister_device(ar->vdev);#if USE_INT	free_irq(M32R_IRQ_INT3, ar);#endif	for (i = 0; i < MAX_AR_HEIGHT; i++)		kfree(ar->frame[i]);#if USE_INT	kfree(ar->line_buff);#endif}module_init(ar_init_module);module_exit(ar_cleanup_module);MODULE_AUTHOR("Takeo Takahashi <takahashi.takeo@renesas.com>");MODULE_DESCRIPTION("Colour AR M64278(VGA) for Video4Linux");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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