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

📄 i2c.c

📁 cmmb if101 linux driver sample
💻 C
字号:
#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/mm.h>#include <asm/page.h>#include <linux/poll.h>#include <linux/kdev_t.h>#include <asm/semaphore.h>#include <asm/arch/pxa-regs.h>#include <linux/slab.h>#include <linux/delay.h>#include <asm/uaccess.h>#include <linux/i2c.h>//#include <asm/arch/gpio.h>#include <asm/arch/ssp.h>//#include <asm/arch/mfp.h>#include <asm/arch/hardware.h>#include <asm/dma.h>#include <linux/dma-mapping.h>#include "IF101_Operation.h"#include "IF101_Communication.h"/************************************************************************** * *		Declaration for I2C part	 *****************************************************************************/#define ID_DRIVERID_IF101	I2C_DRIVERID_EXP3#define I2C_SLAVE_ADDR	0x10static unsigned short normal_i2c[] = {I2C_SLAVE_ADDR, I2C_CLIENT_END };I2C_CLIENT_INSMOD_1(inno);static struct i2c_client* g_client = NULL;static struct i2c_driver i2c_innodev_driver;static int i2c_innodev_detect_client(struct i2c_adapter* adapter, int address, int kind);static int i2c_innodev_attach_adapter(struct i2c_adapter* adapter);static int i2c_innodev_detach_client(struct i2c_client* client);static unsigned short ignore[] = { I2C_CLIENT_END };static unsigned short normal_addr[] = { I2C_SLAVE_ADDR, I2C_CLIENT_END };static struct i2c_client_address_data addr_data = {        .normal_i2c             = normal_addr,        .probe                  = ignore,        .ignore                 = ignore,        .force                  = ignore,};INNO_RETURN_CODE INNO_I2C_Init(int enable){	INNO_RETURN_CODE ret = INNO_GENERAL_ERROR;	unsigned char data = 0;	//printk("INNO_I2C_INIT----------");	if(enable == 1){		ret = i2c_add_driver(&i2c_innodev_driver);	//	printk("ret =======add result====== %d ", ret);		INNO_I2C_Write(0xFF, 0);		INNO_I2C_Write(0xBF, 0x55);		INNO_I2C_Read(0xBF, &data);		if(data == 0x55)			printk("i2c write read right");		else{ 			printk("i2c write read error");		}		if(ret != 0)			return INNO_GENERAL_ERROR;	}	else{		ret = i2c_del_driver(&i2c_innodev_driver);		if(ret != 0)			return INNO_GENERAL_ERROR;	}	mdelay(10);	return INNO_NO_ERROR;}int i2c_write_once(int dev_addr,unsigned char addr, unsigned char data){		int ret;		u8 buf[2] = {addr, data};		struct i2c_msg msg[1]= 	{		{dev_addr, 0, 2,buf}		};		ret = i2c_transfer(g_client->adapter,msg,1) == 1;	return ret;}INNO_RETURN_CODE INNO_I2C_Write(unsigned char addr, unsigned char data){	int ret = 0;	int count = 3;	//printk("INNO_I2C_WRITE\n");//zc#if 0	ret = i2c_smbus_write_byte_data(g_client, addr, data);	if(ret != 0){		printk("i2c_smbus_write_byte_data fail\n");		return INNO_GENERAL_ERROR;	}	udelay(10);	#endif	while((count-- > 0) && !i2c_write_once(I2C_SLAVE_ADDR,addr, data))	{				//printk("innode i2c write error");				schedule_timeout(1);		}	return INNO_NO_ERROR;}int i2c_read_once(int dev_addr, u8 reg_offset, u8 *buf, int len){		struct i2c_msg msgs[2] = {		{ dev_addr, 0,        1, &reg_offset  },		{ dev_addr, I2C_M_RD, len, buf }	};		if (i2c_transfer(g_client->adapter, msgs, 2) == 2){		return 2;	}	else 		return 0;}INNO_RETURN_CODE INNO_I2C_Read(unsigned char addr, unsigned char *data){	u8 buf;	int count;	count = 3;	while(count-- && !i2c_read_once(I2C_SLAVE_ADDR, addr, data, 1)) {		//printk("INNO_I2C_Read error!!\n");		schedule_timeout(1);	}	return INNO_NO_ERROR;#if 0	int ret = 0;	int count = 3;	while((count-- > 0) && !i2c_write_once(I2C_SLAVE_ADDR,addr, data))	{				printk("innode i2c write error");				schedule_timeout(1);		}	return INNO_NO_ERROR;#if 0	*data = i2c_smbus_read_byte_data(g_client, addr);	return INNO_NO_ERROR;#endif#endif}static struct i2c_driver i2c_innodev_driver = {	.owner      	= THIS_MODULE,   	.name       	= "IF101 i2c client driver",	.id		= ID_DRIVERID_IF101,    	.flags      	= I2C_DF_NOTIFY,    	.attach_adapter = i2c_innodev_attach_adapter,    	.detach_client  = i2c_innodev_detach_client,};static int i2c_innodev_attach_adapter(struct i2c_adapter* adapter){	return i2c_probe(adapter, &addr_data, i2c_innodev_detect_client);}static int i2c_innodev_detach_client(struct i2c_client* client){	int err = 0;	/* Try to detach the client from i2c space */	if( (err = i2c_detach_client(g_client))) {		printk(KERN_WARNING "IF101 I2C: Client deregistration failed, client not detached.\n");		return err;	}		/* Freec client data */	kfree(g_client);	g_client = NULL;	return 0;}static int i2c_innodev_detect_client(struct i2c_adapter* adapter, int address, int kind){	struct i2c_client* new_client;	int err = 0;    /* Let's see whether this adapter can support what we need.	   Please substitute the things you need here!  */#if 0	if ( !i2c_check_functionality(adapter,I2C_FUNC_SMBUS_BYTE_DATA) ) {		printk(KERN_INFO "byte op is not permited.\n");		err = -EPERM;		goto exit;	}#endif	/* OK. For now, we presume we have a valid client. We now create the	   client structure, even though we cannot fill it completely yet.	   But it allows us to access several i2c functions safely */	if(!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))){		err = -ENOMEM;		goto exit;	}	memset(new_client, 0, sizeof(struct i2c_client));		new_client->addr = address;	new_client->adapter = adapter;	new_client->driver = &i2c_innodev_driver;	new_client->flags = 0;		strcpy(new_client->name, "IF101");	//printk("i2c_innodev_detect_client");	g_client = new_client;	err = i2c_attach_client(g_client);exit:	return err;}

⌨️ 快捷键说明

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