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

📄 saa7121.c

📁 SAA7121 Linux 驱动源码,此设备驱动依赖于Linux总线驱动。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/drivers/video/saa7121.c *  *//* History  *  1     */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/device.h>#include <linux/errno.h>#include <linux/fs.h>#include <asm/io.h>#include <linux/types.h>#include <linux/string.h>#include <linux/major.h>#include <linux/miscdevice.h>#include <asm/uaccess.h>#include <linux/i2c.h>#include <linux/i2c-dev.h>#include <linux/videodev.h>#include <linux/video_encoder.h>#include "saa7121.h"#define I2C_NAME(s) (s)->name#define MODULE_NAME "SAA7121 DRIVER"#define VER_NO 0.0.1#define DEBUG 1#define MMIO_BASE 	0x1be00000#define QVCP5L_BASE 	0x10e000#define QVCP5L_OUT_CTRL_OFFSET	0x3c#define QVCP5L_ONSH_CTRL_OFFSET		0x70#define QVCP5L_OUT_CTRL	MMIO_BASE + QVCP5L_BASE + QVCP5L_OUT_CTRL_OFFSET#define QVCP5L_ONSH_CTRL	MMIO_BASE + QVCP5L_BASE + QVCP5L_ONSH_CTRL_OFFSET#define QVCP5L_OUT_CTRL_MSK  0xfffc9888#define QVCP5L_OUT_CTRL_SET  0x00003644#define ENCODER_SET_REG		_IOW('e', 10, int)#define ENCODER_GET_REG		_IOW('e', 11, int)#define ENCODER_SET_LEFT_RIGHT	_IOW('e', 12, int)#define ENCODER_SET_TOP_BOTTOM	_IOW('e', 13, int)static ulong  out_ctrl_value;static int debug = 8;#define dprintk(num, format, args...) \	do { \		if (debug >= num) \			printk(format, ##args); \	} while (0)/* ----------------------------------------------------------------------- *//* Initialization Sequence */	 static char *mode_option = "pal";module_param(mode_option,charp,0);struct saa7121 {	unsigned char reg[128];	int norm;     //PAL or NTSC	int enable;	int bright;	int contrast;	int hue;	int sat;};static struct i2c_client *saa7121_client;#define   DEVNAME "saa7121"#define   I2C_SAA7121        			0x8cstatic inline int saa7121_read (struct i2c_client *client,u8 reg);static int saa7121_write (struct i2c_client *client, u8 reg, u8 value);static int saa7121_command (struct i2c_client *client, unsigned int cmd, void  *arg);static int saa7121_ioctl( struct inode  *inode, struct file   *file, unsigned int   cmd,   unsigned long  arg);static const unsigned char init_common[] = {	0x26, 0x00,	0x27, 0x00,};/*PAL 输出模式配置*/static const unsigned char init_pal[] = {	0x26, 0x0,	0x27, 0x0,	0x28, 0x21,	0x29, 0x1d,	0x2a, 0x0,	0x2b, 0x0,	0x2c, 0x0,	0x2d, 0x0,	0x2e, 0x0,	0x2f, 0x0,	0x30, 0x0,	0x31, 0x0,	0x32, 0x0,	0x33, 0x0,	0x34, 0x0,	0x35, 0x0,	0x36, 0x0,	0x37, 0x0,	0x38, 0x0,	0x39, 0x0,	0x3a, 0x13,	0x3b, 0x0,	0x3c, 0x0,	0x3d, 0x0,	0x3e, 0x0,	0x3f, 0x0,	0x40, 0x0,	0x41, 0x0,	0x42, 0x0,	0x43, 0x0,	0x44, 0x0,	0x45, 0x0,	0x46, 0x0,	0x47, 0x0,	0x48, 0x0,	0x49, 0x0,	0x4a, 0x0,	0x4b, 0x0,	0x4c, 0x0,	0x4d, 0x0,	0x4e, 0x0,	0x4f, 0x0,	0x50, 0x0,	0x51, 0x0,	0x52, 0x0,	0x53, 0x0,	0x54, 0x0,	0x55, 0x0,	0x56, 0x0,	0x57, 0x0,	0x58, 0x0,	0x59, 0x0,	0x5a, 0x3f,	0x5b, 0xa0,	0x5c, 0xd8,	0x5d, 0x30,	0x5e, 0x3b,	0x5f, 0x75,	0x60, 0x0,	0x61, 0x06,	0x62, 0x40,	0x63, 0xcb,	0x64, 0x8a,	0x65, 0x09,	0x66, 0x2a,	0x67, 0x0,	0x68, 0x0,	0x69, 0x0,	0x6a, 0x0,	0x6b, 0x20,	0x6c, 0x01,	0x6d, 0x30,	0x6e, 0xa0,	0x6f, 0x00,	0x70, 0x00,	0x71, 0x00,	0x72, 0x00,	0x73, 0x0,	0x74, 0x0,	0x75, 0x0,	0x76, 0x0,	0x77, 0x0,	0x78, 0x0,	0x79, 0x0,	0x7a, 0x00,	0x7b, 0x00,	0x7c, 0x00,	0x7d, 0x0,	0x7e, 0x0,	0x7f, 0x0};/*NTSC 输出模式配置*/static const unsigned char init_ntsc[] = {	0x26, 0x0,	0x27, 0x0,	0x28, 0x19,	0x29, 0x1d,	0x2a, 0x0,	0x2b, 0x0,	0x2c, 0x0,	0x2d, 0x0,	0x2e, 0x0,	0x2f, 0x0,	0x30, 0x0,	0x31, 0x0,	0x32, 0x0,	0x33, 0x0,	0x34, 0x0,	0x35, 0x0,	0x36, 0x0,	0x37, 0x0,	0x38, 0x0,	0x39, 0x0,	0x3a, 0x13,	0x3b, 0x0,	0x3c, 0x0,	0x3d, 0x0,	0x3e, 0x0,	0x3f, 0x0,	0x40, 0x0,	0x41, 0x0,	0x42, 0x0,	0x43, 0x0,	0x44, 0x0,	0x45, 0x0,	0x46, 0x0,	0x47, 0x0,	0x48, 0x0,	0x49, 0x0,	0x4a, 0x0,	0x4b, 0x0,	0x4c, 0x0,	0x4d, 0x0,	0x4e, 0x0,	0x4f, 0x0,	0x50, 0x0,	0x51, 0x0,	0x52, 0x0,	0x53, 0x0,	0x54, 0x0,	0x55, 0x0,	0x56, 0x0,	0x57, 0x0,	0x58, 0x0,	0x59, 0x0,	0x5a, 0x67,	0x5b, 0x76,	0x5c, 0xa5,	0x5d, 0x2a,	0x5e, 0x2e,	0x5f, 0x6e,	0x60, 0x0,	0x61, 0x15,	0x62, 0x3f,	0x63, 0x1f,	0x64, 0x7c,	0x65, 0xf0,	0x66, 0x21,	0x67, 0x0,	0x68, 0x0,	0x69, 0x0,	0x6a, 0x80,		0x6b, 0x20,	0x6c, 0x01,	0x6d, 0x31,	0x6e, 0x80,	0x6f, 0x00,	0x70, 0x00,	0x71, 0x00,	0x72, 0x00,	0x73, 0x0,	0x74, 0x0,	0x75, 0x0,	0x76, 0x0,	0x77, 0x0,	0x78, 0x0,	0x79, 0x0,	0x7a, 0x00,	0x7b, 0x00,	0x7c, 0x00,	0x7d, 0x0,	0x7e, 0x0,	0x7f, 0x0};static int saa7121_ioctl( struct inode  *inode, struct file   *file,                              unsigned int   cmd,   unsigned long  arg){	u8 reg;	u8 value;	ulong setting;	int readval=0;	struct saa7121 *encoder = i2c_get_clientdata(saa7121_client);		switch (cmd) {	/*写寄存器的值*/	 case ENCODER_SET_LEFT_RIGHT:					/* 0x6c from 0x01 to 0xf1,not low four bits */		if( get_user(setting, (ulong *)arg) == 0)		{			reg =0x6c;			value =(u8) (setting & 0x000f);			value =(value<<4)|0x01;			//printk("set register 0x%02x = 0x%02x\n",reg, value);			if (saa7121_write(saa7121_client, reg, value)<0)	/* set register  */				return  -EINVAL;		}		break;		 case ENCODER_SET_TOP_BOTTOM:				/* 0x6d,from 0x20 to 0x3f  */		if( get_user(setting, (ulong *)arg) == 0)		{			reg =0x6d;			value =(u8) (setting & 0x001f);			value =value|0x20;			//printk("set register 0x%02x = 0x%02x\n",reg, value);			if (saa7121_write(saa7121_client, reg, value)<0)	/* set register  */				return  -EINVAL;		}		break;		 	case ENCODER_SET_REG:		if( get_user(setting, (ulong *)arg) == 0)		{			reg =(u8) ((setting & 0xff00) >> 8);			value =(u8) (setting & 0x00ff);			printk("set register 0x%02x = 0x%02x\n",reg, value);			if (saa7121_write(saa7121_client, reg, value)<0)	/* set register  */				return  -EINVAL;		}		break;	/*读取寄存器的值(全返回第一个寄存器的值,saa7121只有第一寄存器可读)*/	case ENCODER_GET_REG:		if( get_user(setting, (ulong *)arg) == 0){			reg = (u8)(setting & 0x00ff);			if ((readval = saa7121_read(saa7121_client, reg))<0)	/* get register  */				return  -EINVAL;			printk("Read register 0x%02x, value = 0x%x\n",reg,readval);			put_user(readval, (ulong *)arg );		}		break;	/*获取encorder 的能力*/	case ENCODER_GET_CAPABILITIES:	{		struct video_encoder_capability cap;				cap.flags = VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC;		cap.inputs = 1;		cap.outputs = 1;		if (copy_to_user((struct video_encoder_capability*)arg, &cap, sizeof(struct video_encoder_capability)) )			return -EINVAL; 	}		break;	/*设置输出格式*/	case ENCODER_SET_NORM:	{		ulong iarg ;		if( get_user(iarg, (ulong *)arg) == 0){			saa7121_write_block(saa7121_client, init_common, sizeof(init_common));			switch (iarg) {							case VIDEO_MODE_NTSC:				saa7121_write_block(saa7121_client, init_ntsc,						    sizeof(init_ntsc));				printk("saa7121 set output mode : NTSC\n");				break;							case VIDEO_MODE_PAL:				saa7121_write_block(saa7121_client, init_pal,						    sizeof(init_pal));				printk("saa7121 set output mode : PAL\n");				break;			default:				return -EINVAL;			}		}		encoder->norm = iarg;	}		break;	/*使能输出*/	case ENCODER_ENABLE_OUTPUT:	{		ulong iarg ;		if( get_user(iarg, (ulong *)arg) == 0){			encoder->enable = !!iarg;			saa7121_write(saa7121_client, 0x61,				      (encoder->reg[0x61] & 0xbf) |				      (encoder->enable ? 0x00 : 0x40));			printk("saa7121 enable output :  %c\n", encoder->enable ? 'Y':'N');		}	}		break;	default:		return -EINVAL;    	}	return 0;}/* ----------------------------------------------------------------------- */static struct file_operations   saa7121_fops    =   {    .owner          =   THIS_MODULE,    .read           =   NULL,    .open           =   NULL,    .release        =   NULL,    .ioctl          =   saa7121_ioctl,};

⌨️ 快捷键说明

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