📄 i2c.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, ®_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 + -