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

📄 tw2815.c

📁 i2c配置tw2815
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************            ENI2C Client & Driver ****************************************************************************/static struct i2c_driver i2c_driver_tw2815;static int tw2815_detect_client(struct i2c_adapter *adapter, int address, int kind){    struct i2c_client *client;    struct tw2815 *decoder;    int     rv;	   printk("tw2815.c: detecting tw2815 client on address 0x%x\n", address<<1);   if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))       return 0;    client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);    if (client == 0)        return -ENOMEM;    client->addr = address;    client->adapter = adapter;     client->driver = &i2c_driver_tw2815;     strlcpy(I2C_NAME(client), tw2815_name, sizeof(I2C_NAME(client)));     decoder = kzalloc(sizeof(struct tw2815), GFP_KERNEL);    if (decoder == NULL) {        kfree(client);        return -ENOMEM;    }    decoder->norm = VIDEO_MODE_PAL;    decoder->enable = 1;    decoder->bright = 128;    decoder->contrast = 128;    decoder->hue = 128;    decoder->sat = 128;    i2c_set_clientdata(client, decoder);	    tw2815_default_vedio_write(client,TELECAST_PAL_MODE);    rv = i2c_attach_client(client);    if (rv) {        kfree(client);        kfree(decoder);        return rv;    }    return 0;}static int tw2815_attach_adapter(struct i2c_adapter *adapter){    return i2c_probe(adapter, &addr_data, &tw2815_detect_client);}static int tw2815_detach_client(struct i2c_client *client){    struct tw2815 *decoder = i2c_get_clientdata(client);    int err;    err = i2c_detach_client(client);    if (err)        return err;    kfree(decoder);    kfree(client);    return 0;}static struct i2c_driver i2c_driver_tw2815= {    .driver = {        .name = "tw2815",    },    .id = I2C_DRIVERID_TW2815,    .attach_adapter = tw2815_attach_adapter,    .detach_client = tw2815_detach_client,    .command = tw2815_command,};/*       for appl*/static ssize_t tw2815_read (struct file *file, char __user *buf, size_t count, loff_t *offset){	char *tmp;	int ret;	struct i2c_client *client = (struct i2c_client *)file->private_data;	if (count > 8192)		count = 8192;	tmp = kmalloc(count,GFP_KERNEL);	if (tmp==NULL)		return -ENOMEM;	ret = i2c_master_recv(client,tmp,count);	if (ret >= 0)		ret = copy_to_user(buf,tmp,count)?-EFAULT:ret;	kfree(tmp);	return ret;}static ssize_t tw2815_write (struct file *file, const char __user *buf, size_t count,loff_t *offset){	int ret;	char *tmp;	struct i2c_client *client = (struct i2c_client *)file->private_data;	if (count > 8192)		count = 8192;	tmp = kmalloc(count,GFP_KERNEL);	if (tmp==NULL)		return -ENOMEM;	if (copy_from_user(tmp,buf,count)) {		kfree(tmp);		return -EFAULT;	}	ret = i2c_master_send(client,tmp,count);	kfree(tmp);	return ret;}static int tw2815_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg){	struct i2c_client *client = (struct i2c_client *)file->private_data;		if(cmd>10)		return -1;	switch ( cmd ) 	{		case GET_TW2815_REG_VALUE:		{			char *tmp;			char start_addr,length;			int ret;						tmp = kmalloc(2,GFP_KERNEL);	      		if (tmp==NULL)		     		return -ENOMEM;			if (copy_from_user(tmp,(char _user *)arg,2)) 			{		        	kfree(tmp);				return -EFAULT;			}                     start_addr = *tmp++;			length = *tmp;			kfree(tmp);			tmp = kmalloc(length,GFP_KERNEL);	      		if (tmp==NULL)		     		return -ENOMEM;                     tw2815_block_read(client,start_addr,tmp,length);		      	ret = copy_to_user((char _user *)arg,tmp,length)?-EFAULT:ret;			kfree(tmp);		}		break;		case SET_TW2815_REG_VALUE:		{		 	char *tmp;			char start_addr,value;			int ret;			tmp = kmalloc(2,GFP_KERNEL);	      		if (tmp==NULL)		     		return -ENOMEM;			if (copy_from_user(tmp,(char _user *)arg,2)) 			{		        	kfree(tmp);				return -EFAULT;			}                     start_addr = *tmp++;			value = *tmp;			kfree(tmp);			tw2815_single_write(client,start_addr,value);		}		break;		case TW2815_DEFAULT_CONFIG_PAL:			tw2815_mPAL_vedio_write(client);			break;		case TW2815_DEFAULT_CONFIG_NTSC:			tw2815_mNTSC_vedio_write(client);			break;		case TW2815_HUE_CONFIG:		{			char value,ch_num;			char *tmp;			tmp = kmalloc(2,GFP_KERNEL);	      		if (tmp==NULL)		     		return -ENOMEM;			if (copy_from_user(tmp,(char _user *)arg,2)) 			{		        	kfree(tmp);				return -EFAULT;			}                     value = *tmp++;			ch_num = *tmp;			kfree(tmp);			switch(ch_num)			{				case ALL_CH:					tw2815_single_write(client,CH1_HUE_REG,value);					tw2815_single_write(client,CH2_HUE_REG,value);					tw2815_single_write(client,CH3_HUE_REG,value);					tw2815_single_write(client,CH4_HUE_REG,value);					break;				case CH_NUM1:					tw2815_single_write(client,CH1_HUE_REG,value);					break;				case CH_NUM2:					tw2815_single_write(client,CH2_HUE_REG,value);					break;				case CH_NUM3:					tw2815_single_write(client,CH3_HUE_REG,value);					break;				case CH_NUM4:					tw2815_single_write(client,CH4_HUE_REG,value);					break;			}		}		break;		case TW2815_SAT_CONFIG:		{			char value,ch_num;			char *tmp;			tmp = kmalloc(2,GFP_KERNEL);	      		if (tmp==NULL)		     		return -ENOMEM;			if (copy_from_user(tmp,(char _user *)arg,2)) 			{		        	kfree(tmp);				return -EFAULT;			}                     value = *tmp++;			ch_num = *tmp;			kfree(tmp);			switch(ch_num)			{				case ALL_CH:					tw2815_single_write(client,CH1_SAT_REG,value);					tw2815_single_write(client,CH2_SAT_REG,value);					tw2815_single_write(client,CH3_SAT_REG,value);					tw2815_single_write(client,CH4_SAT_REG,value);					break;				case CH_NUM1:					tw2815_single_write(client,CH1_SAT_REG,value);					break;				case CH_NUM2:					tw2815_single_write(client,CH2_SAT_REG,value);					break;				case CH_NUM3:					tw2815_single_write(client,CH3_SAT_REG,value);					break;				case CH_NUM4:					tw2815_single_write(client,CH4_SAT_REG,value);					break;			}		}		break;		case TW2815_CONT_CONFIG:		{			char value,ch_num;			char *tmp;			tmp = kmalloc(2,GFP_KERNEL);	      		if (tmp==NULL)		     		return -ENOMEM;			if (copy_from_user(tmp,(char _user *)arg,2)) 			{		        	kfree(tmp);				return -EFAULT;			}                     value = *tmp++;			ch_num = *tmp;			kfree(tmp);			switch(ch_num)			{				case ALL_CH:					tw2815_single_write(client,CH1_CONT_REG,value);					tw2815_single_write(client,CH2_CONT_REG,value);					tw2815_single_write(client,CH3_CONT_REG,value);					tw2815_single_write(client,CH4_CONT_REG,value);					break;				case CH_NUM1:					tw2815_single_write(client,CH1_CONT_REG,value);					break;				case CH_NUM2:					tw2815_single_write(client,CH2_CONT_REG,value);					break;				case CH_NUM3:					tw2815_single_write(client,CH3_CONT_REG,value);					break;				case CH_NUM4:					tw2815_single_write(client,CH4_CONT_REG,value);					break;			}		}		break;		case TW2815_BRT_CONFIG:		{			char value,ch_num;			char *tmp;			tmp = kmalloc(2,GFP_KERNEL);	      		if (tmp==NULL)		     		return -ENOMEM;			if (copy_from_user(tmp,(char _user *)arg,2)) 			{		        	kfree(tmp);				return -EFAULT;			}                     value = *tmp++;			ch_num = *tmp;			kfree(tmp);			switch(ch_num)			{				case ALL_CH:					tw2815_single_write(client,CH1_BRT_REG,value);					tw2815_single_write(client,CH2_BRT_REG,value);					tw2815_single_write(client,CH3_BRT_REG,value);					tw2815_single_write(client,CH4_BRT_REG,value);					break;				case CH_NUM1:					tw2815_single_write(client,CH1_BRT_REG,value);					break;				case CH_NUM2:					tw2815_single_write(client,CH2_BRT_REG,value);					break;				case CH_NUM3:					tw2815_single_write(client,CH3_BRT_REG,value);					break;				case CH_NUM4:					tw2815_single_write(client,CH4_BRT_REG,value);					break;			}		}		break;		case TW2815_UGAIN_CONFIG:			char value;			__get_user(value, (char __user *)arg);			tw2815_single_write(client,VGAIN_REG,value);			break;		case TW2815_VGAIN_CONFIG:			char value;			__get_user(value, (char __user *)arg);			tw2815_single_write(client,VGAIN_REG,value);			break;	}	return 0;}static int  tw2815_open(struct inode *inode, struct file *file){	unsigned int minor = iminor(inode);	struct i2c_client *client;	struct i2c_adapter *adap;	struct i2c_dev *i2c_dev;	i2c_dev = i2c_dev_get_by_minor(minor);	if (!i2c_dev)		return -ENODEV;	adap = i2c_get_adapter(i2c_dev->adap->nr);	if (!adap)		return -ENODEV;	client = kzalloc(sizeof(*client), GFP_KERNEL);	if (!client) {		i2c_put_adapter(adap);		return -ENOMEM;	}	snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);	client->driver = &i2c_driver_tw2815;	/* registered with adapter, passed as client to user */	client->adapter = adap;	file->private_data = client;     	return 0;}static int  tw2815_release(struct inode *inode, struct file *file){	struct i2c_client *client = file->private_data;	i2c_put_adapter(client->adapter);	kfree(client);	file->private_data = NULL;	return 0;}static struct file_operations  i2c_tw2815_fops ={    .owner   	= 	THIS_MODULE,    .llseek     	= 	NULL,    .read       	= 	tw2815_read,    .write      	= 	tw2815_write,    .ioctl       	= 	tw2815_ioctl,    .release  	=  	tw2815_release,    .open      	=  	tw2815_open,};static struct class *i2c_tw2815_class;static int __init  tw2815_init(void){	int res;	printk(KERN_INFO "i2c /dev entries driver\n");	res = register_chrdev(I2C_MAJOR, "tw2815", &i2c_tw2815_fops);	if (res)		goto out;	i2c_tw2815_class = class_create(THIS_MODULE, "tw2815-dev");	if (IS_ERR(i2c_tw2815_class))		goto out_unreg_chrdev;	res = i2c_add_driver(&i2c_driver_tw2815);	if (res)		goto out_unreg_class;	return 0;out_unreg_class:	class_destroy(i2c_tw2815_class);out_unreg_chrdev:	unregister_chrdev(I2C_MAJOR, "tw2815");out:	printk(KERN_ERR "%s: TW2815 Driver Initialisation failed\n", __FILE__);	return res;}static void __exit tw2815_exit(void){    i2c_del_driver(&i2c_driver_tw2815);    class_destroy(i2c_tw2815_class);    unregister_chrdev(I2C_MAJOR,"tw2815");}module_init(tw2815_init);module_exit(t2815_exit);MODULE_DESCRIPTION("Analog Devices TW2815 video encoder driver");MODULE_AUTHOR("Agui<Agui@163.com>");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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