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

📄 video_buffer.c

📁 一个嵌入式camera驱动 驱动 驱动
💻 C
字号:
/* *  drivers/char/arca/video_buffer.c *  Driver for control Video buffer and get the Finger data. * *  Copyright (C) 2003 LingFang Micro System.  * *   * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. See * the file "COPYING" in the main directory of this archive * for more details. * */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/slab.h>#include <linux/list.h>#include <linux/arca-chars.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/io.h>#include <asm/delay.h>#include <asm/hardware.h>//SCCB define.#define SCC_PORT_MASK  0x3F#define SCC_DATA_HIGH  0x80 + SCC_PORT_MASK	//PA7 -- data#define SCC_DATA_LOW   0x00 + SCC_PORT_MASK#define SCC_CLK_HIGH   0x40		//PA6 -- clock#define SCC_CLK_LOW    0x00/*#define SCC_PORT_MASK  0xCF#define SCC_DATA_HIGH  0x20 + SCC_PORT_MASK	//PA5 -- data#define SCC_DATA_LOW   0x00 + SCC_PORT_MASK#define SCC_CLK_HIGH   0x10		//PA4 -- clock#define SCC_CLK_LOW    0x00*/#define SCC_PORT       *(unsigned char volatile *)(0xE0000504)//SCCB define end.	//The driver's function define#define FIFO_RESET_DELAY 0x20//Windows defines.#define X_START 176#define Y_START 132#define X_WIDTH 296#define Y_WIDTH 300//Windows define end.static int	video_buffer_open(struct inode *, struct file *);static int	video_buffer_close(struct inode *, struct file *);static ssize_t	video_buffer_read(struct file *, char *, unsigned long , loff_t *);static ssize_t	video_buffer_write(struct file *, const char *, size_t, loff_t *);static int	video_buffer_ioctl(struct inode *, struct file *,			     unsigned int, unsigned long);static void     video_buffer_interrupt(int irq, void *dev_id, struct pt_regs *regs);//This is the address for my video buffer.static unsigned long VIDEO_BUFFER_ADDRESS;//This device's struct.struct video_buffer_dev_struct {	int opened;	char *name;	void *private;} video_buffer_dev;video_buffer_dev_minor = 0x22; //Here are the same number in the /dev/arca/video_buffer nods./*************************************************************************** **  define driver struct.   **  ***************************************************************************/static struct file_operations video_buffer_fops ={	open:	video_buffer_open,	release:video_buffer_close,	read:	video_buffer_read,	write:	video_buffer_write,	ioctl:	video_buffer_ioctl,};//SCCB function define.void sccb_write_ov_sio_data_io(unsigned char devaddress, unsigned char regaddress, unsigned char mydata);void sccb_delay(void){	unsigned long i;	for(i=0x0000;i<0xF000;i++)    {		i++;	}}//////////////////////////////////////////////////////////////////////////////////////////////////////*************************************************************************** **  driver open process. **  ***************************************************************************/void reset_7620(void){	unsigned long i;	unsigned char data;	//__gpiod_write(0xDF);	//__gpiod_as_outputs();		*(unsigned char *)(0xE0000534) = 0xD0;	*(unsigned long *)(0xE0000530) = 0x00000FF0;	*(unsigned char *)(0xE0000534) = 0x10;	for(i=0;i<FIFO_RESET_DELAY;i++)	{i++;}		data = *(unsigned char volatile *)(VIDEO_BUFFER_ADDRESS);	data = *(unsigned char volatile *)(VIDEO_BUFFER_ADDRESS + 1);	for(i=0;i<FIFO_RESET_DELAY;i++)	{i++;}	*(unsigned char *)(0xE0000534) = 0xD0;	}static int video_buffer_open(struct inode *inode, struct file *filp){	unsigned long i;	unsigned char data;	unsigned long reg;	unsigned char hstart,hend,vstart,vend;		if (video_buffer_dev.opened) {		printk(KERN_INFO "video_buffer: the device is busy\n");		return -EBUSY;	}	VIDEO_BUFFER_ADDRESS = ioremap(0x84000000,0x4B000);	*(unsigned char *)(0xE0000534) = 0xD0;	*(unsigned long *)(0xE0000530) = 0x00000FF0;	//*(unsigned long volatile *)(0xE1020008) = 0x02222200;		        *(unsigned long volatile *)(0xE1020008) = 0x04444400;			__gpioa_write(0xFF);	__gpioa_as_outputs();			hstart = 0x2F + (X_START/4);	hend = hstart + (X_WIDTH/4);	vstart = 0x06 + (Y_START/2);	vend = vstart - 1 + (Y_WIDTH/2);			sccb_write_ov_sio_data_io(0x42,0x28,0x20);	sccb_delay();	//sccb_write_ov_sio_data_io(0x42,0x17,0x57);	sccb_write_ov_sio_data_io(0x42,0x17,hstart);	sccb_delay();	//sccb_write_ov_sio_data_io(0x42,0x18,0xA7);	sccb_write_ov_sio_data_io(0x42,0x18,hend);	sccb_delay();	//sccb_write_ov_sio_data_io(0x42,0x19,0x2E);	sccb_write_ov_sio_data_io(0x42,0x19,vstart);	sccb_delay();	//sccb_write_ov_sio_data_io(0x42,0x1A,0xCD);	sccb_write_ov_sio_data_io(0x42,0x1A,vend);        sccb_delay();        /*	for(i=0;i<0x1000000;i++)	{i++;}	__gpiod_write(0x10);	for(i=0;i<0x100000;i++)	{i++;}		data = *(unsigned char volatile *)(VIDEO_BUFFER_ADDRESS);	data = *(unsigned char volatile *)(VIDEO_BUFFER_ADDRESS + 1);	for(i=0;i<0x1000000;i++)	{i++;}	__gpiod_write(0xDF);        */        reset_7620();	MOD_INC_USE_COUNT;	video_buffer_dev.opened = 1;		//printk("The ioremap result for fucking video buffer is %08X.\n",VIDEO_BUFFER_ADDRESS);	return 0;}/*************************************************************************** ** driver close process. **  ***************************************************************************/static int video_buffer_close(struct inode *inode, struct file *filp){	MOD_DEC_USE_COUNT;	video_buffer_dev.opened = 0;	return 0;}/*************************************************************************** **  Read video buffer data. **  ***************************************************************************/static ssize_t video_buffer_read(struct file *filp, char *buf,			   unsigned long count, loff_t *ppos){	unsigned char mydata;	unsigned long i;	reset_7620();	//for(i=0;i<(640*480);i++)	//for(i=0;i<(320*320);i++)	for(i=0;i<(X_WIDTH * Y_WIDTH);i++)	{		buf[i] = *(unsigned char volatile *)(VIDEO_BUFFER_ADDRESS + i);		}	return 0x01;}/*************************************************************************** ** Dummy Write data.  **  ***************************************************************************/static ssize_t video_buffer_write(struct file *filp, const char *buf,			    size_t count, loff_t *ppos){	return 0;}/*************************************************************************** **  ioctl function.  **  ***************************************************************************/static int video_buffer_ioctl(struct inode *inode, struct file *filp,			unsigned int cmd, unsigned long arg){	int val=0;	unsigned long value=0;	unsigned long flags;	switch (cmd) {	case 0:		return 0x00;	case 1:		return 0x01;	}	return -EINVAL;}/*************************************************************************** ** interrupt process routine.  **  ***************************************************************************/static void video_buffer_interrupt(int irq, void *dev_id, struct pt_regs *regs){}/*************************************************************************** **  Init routine **  ***************************************************************************/static int __init video_buffer_init(void){	int result;	int i;	unsigned long value=0;		result = arca_register_chrdev(video_buffer_dev_minor, "video_bffer",				      &video_buffer_fops);	return result;}/*************************************************************************** **  exit routine. **  ***************************************************************************/static void __exit video_buffer_exit(void){	printk(KERN_INFO "video_buffer driver exit.\n");}//This is the SCCB function.//The devaddress is the address of OV7620 sensor, it should be 0x42,and decided by the power on pull up/down set.//The regaddress is the address of OV register,//The data is the data you want to change to .void sccb_write_ov_sio_data_io(unsigned char devaddress, unsigned char regaddress, unsigned char mydata){	unsigned char i,j,k;	unsigned char data;			SCC_PORT = SCC_DATA_HIGH + SCC_CLK_HIGH; //Set data and clock high for start.	//data = *(unsigned char volatile *)(0xE0000504);	//printk("PORTA is %02X.\n",data);	SCC_PORT = SCC_DATA_LOW + SCC_CLK_HIGH; //Set data low for start signal of IIC.	//data = *(unsigned char volatile *)(0xE0000504);	//printk("PORTA is %02X.\n",data);		sccb_delay();	//send device id address.	j = 0x80;	for(i=0;i<0x08;i++)	{		k = j & devaddress;		if(j == k)		{		//Send data high when this bit is "1".				sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;				sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_HIGH;								sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;		}		else		{		//Send data low when this bit is "0".				sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_LOW;				sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_HIGH;				sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_LOW;		}		j = j>>1;	}	//send x bit.	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_HIGH;	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;	//send register address.	j = 0x80;	for(i=0;i<0x08;i++)	{		k = j & regaddress;		if(j == k)		{		//Send data high when this bit is "1".				sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;				sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_HIGH;								sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;		}		else		{		//Send data low when this bit is "0".				sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_LOW;				sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_HIGH;				sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_LOW;		}		j = j>>1;	}	//send x bit.	//*(unsigned char *)(0x60000000) = 0b10000000;	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_HIGH;	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;	//send data.	j = 0x80;	for(i=0;i<0x08;i++)	{		k = j & mydata;		if(j == k)		{		//Send data high when this bit is "1".				sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;				sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_HIGH;								sccb_delay();				SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;		}		else		{		//Send data low when this bit is "0".				sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_LOW;					sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_HIGH;				sccb_delay();				SCC_PORT = SCC_DATA_LOW + SCC_CLK_LOW;		}		j = j>>1;	}	//send x bit.	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_HIGH;	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_LOW;	sccb_delay();	sccb_delay();	SCC_PORT = SCC_DATA_LOW + SCC_CLK_HIGH;	sccb_delay();	SCC_PORT = SCC_DATA_HIGH + SCC_CLK_HIGH;}MODULE_AUTHOR ("");MODULE_DESCRIPTION ("video_buffer driver");MODULE_LICENSE("GPL");module_init(video_buffer_init);module_exit(video_buffer_exit);

⌨️ 快捷键说明

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