i2c--test .

硬件
http://www.i2c-bus.org/how-i2c-hardware-works/
http://www.xinqi.cn/pdf/cun/at24cxx.pdf
http://download.csdn.net/detail/songqqnew/4438714
http://download.csdn.net/detail/songqqnew/4438746
测试
***********************************************************************************************使用ioctl( ,I2C_SMBUS, )操作iic
板子的文件系统里已经有一个/usr/bin/i2c的程序,用于测试i2c,比如
i2c -r
i2c -w
源码如下
  1. //24cxx.h   
  2.   
  3. #ifndef _24CXX_H_   
  4. #define _24CXX_H_   
  5. #include <linux/i2c-dev.h>   
  6. #include <linux/i2c.h>   
  7.   
  8. #define EEPROM_TYPE_UNKNOWN 0   
  9. #define EEPROM_TYPE_8BIT_ADDR   1   
  10. #define EEPROM_TYPE_16BIT_ADDR  2   
  11.   
  12. struct eeprom  
  13. {  
  14.     char *dev;  // device file i.e. /dev/i2c-N   
  15.     int addr;   // i2c address   
  16.     int fd;     // file descriptor   
  17.     int type;   // eeprom type   
  18. };  
  19.   
  20. int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom*);  
  21. int eeprom_close(struct eeprom *e);  
  22. int eeprom_read_byte(struct eeprom* e, __u16 mem_addr);  
  23. int eeprom_read_current_byte(struct eeprom *e);  
  24. int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data);  
  25. #endif  
//24cxx.h

#ifndef _24CXX_H_
#define _24CXX_H_
#include <linux/i2c-dev.h>
#include <linux/i2c.h>

#define EEPROM_TYPE_UNKNOWN	0
#define EEPROM_TYPE_8BIT_ADDR	1
#define EEPROM_TYPE_16BIT_ADDR 	2

struct eeprom
{
	char *dev; 	// device file i.e. /dev/i2c-N
	int addr;	// i2c address
	int fd;		// file descriptor
	int type; 	// eeprom type
};

int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom*);
int eeprom_close(struct eeprom *e);
int eeprom_read_byte(struct eeprom* e, __u16 mem_addr);
int eeprom_read_current_byte(struct eeprom *e);
int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data);
#endif

  1. //eeprog.c   
  2.   
  3. #include <stdio.h>   
  4. #include <fcntl.h>   
  5. #include <getopt.h>   
  6. #include <unistd.h>   
  7. #include <stdlib.h>   
  8. #include <errno.h>   
  9. #include <string.h>   
  10. #include <sys/types.h>   
  11. #include <sys/stat.h>   
  12. #include "24cXX.h"   
  13.   
  14. #define usage_if(a) do { do_usage_if( a , __LINE__); } while(0);   
  15. void do_usage_if(int b, int line)  
  16. {  
  17.     const static char *eeprog_usage =   
  18.         "I2C-24C08(256 bytes) Read/Write Program, ONLY FOR TEST!\n"  
  19.         "FriendlyARM Computer Tech. 2009\n";  
  20.     if(!b)  
  21.         return;  
  22.     fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line);  
  23.     exit(1);  
  24. }  
  25.   
  26.   
  27. #define die_if(a, msg) do { do_die_if( a , msg, __LINE__); } while(0);   
  28. void do_die_if(int b, char* msg, int line)  
  29. {  
  30.     if(!b)  
  31.         return;  
  32.     fprintf(stderr, "Error at line %d: %s\n", line, msg);  
  33.     fprintf(stderr, "   sysmsg: %s\n", strerror(errno));  
  34.     exit(1);  
  35. }  
  36.   
  37.   
  38. static int read_from_eeprom(struct eeprom *e, int addr, int size)  
  39. {  
  40.     int ch, i;  
  41.     for(i = 0; i < size; ++i, ++addr)  
  42.     {  
  43.         die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error");  
  44.         if( (i % 16) == 0 )   
  45.             printf("\n %.4x|  ", addr);  
  46.         else if( (i % 8) == 0 )   
  47.             printf("  ");  
  48.         printf("%.2x ", ch);  
  49.         fflush(stdout);  
  50.     }  
  51.     fprintf(stderr, "\n\n");  
  52.     return 0;  
  53. }  
  54.   
  55. static int write_to_eeprom(struct eeprom *e, int addr)  
  56. {  
  57.     int i;  
  58.     for(i=0, /*addr=0*/; i<256; i++, addr++)  
  59.     {  
  60.         if( (i % 16) == 0 )   
  61.             printf("\n %.4x|  ", addr);  
  62.         else if( (i % 8) == 0 )   
  63.             printf("  ");  
  64.         printf("%.2x ", i);  
  65.         fflush(stdout);  
  66.         die_if(eeprom_write_byte(e, addr, i), "write error");  
  67.     }  
  68.     fprintf(stderr, "\n\n");  
  69.     return 0;  
  70. }  
  71.   
  72. int main(int argc, char** argv)  
  73. {  
  74.     struct eeprom e;  
  75.     int op;  
  76.   
  77.     op = 0;  
  78.   
  79.     usage_if(argc != 2 || argv[1][0] != '-' || argv[1][2] != '\0');  
  80.     op = argv[1][1];  
  81.   
  82.     fprintf(stderr, "Open /dev/i2c/0 with 8bit mode\n");  
  83.     die_if(eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e) < 0,   
  84.             "unable to open eeprom device file "  
  85.             "(check that the file exists and that it's readable)");  
  86.     switch(op)  
  87.     {  
  88.     case 'r':  
  89.         fprintf(stderr, "  Reading 256 bytes from 0x0\n");  
  90.         read_from_eeprom(&e, 0, 256);  
  91.         break;  
  92.     case 'w':  
  93.         fprintf(stderr, "  Writing 0x00-0xff into 24C08 \n");  
  94.         write_to_eeprom(&e, 0);  
  95.         break;  
  96.     default:  
  97.         usage_if(1);  
  98.         exit(1);  
  99.     }  
  100.     eeprom_close(&e);  
  101.   
  102.     return 0;  
  103. }  
//eeprog.c

#include <stdio.h>
#include <fcntl.h>
#include <getopt.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "24cXX.h"

#define usage_if(a) do { do_usage_if( a , __LINE__); } while(0);
void do_usage_if(int b, int line)
{
	const static char *eeprog_usage = 
		"I2C-24C08(256 bytes) Read/Write Program, ONLY FOR TEST!\n"
		"FriendlyARM Computer Tech. 2009\n";
	if(!b)
		return;
	fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line);
	exit(1);
}


#define die_if(a, msg) do { do_die_if( a , msg, __LINE__); } while(0);
void do_die_if(int b, char* msg, int line)
{
	if(!b)
		return;
	fprintf(stderr, "Error at line %d: %s\n", line, msg);
	fprintf(stderr, "	sysmsg: %s\n", strerror(errno));
	exit(1);
}


static int read_from_eeprom(struct eeprom *e, int addr, int size)
{
	int ch, i;
	for(i = 0; i < size; ++i, ++addr)
	{
		die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error");
		if( (i % 16) == 0 ) 
			printf("\n %.4x|  ", addr);
		else if( (i % 8) == 0 ) 
			printf("  ");
		printf("%.2x ", ch);
		fflush(stdout);
	}
	fprintf(stderr, "\n\n");
	return 0;
}

static int write_to_eeprom(struct eeprom *e, int addr)
{
	int i;
	for(i=0, /*addr=0*/; i<256; i++, addr++)
	{
		if( (i % 16) == 0 ) 
			printf("\n %.4x|  ", addr);
		else if( (i % 8) == 0 ) 
			printf("  ");
		printf("%.2x ", i);
		fflush(stdout);
		die_if(eeprom_write_byte(e, addr, i), "write error");
	}
	fprintf(stderr, "\n\n");
	return 0;
}

int main(int argc, char** argv)
{
	struct eeprom e;
	int op;

	op = 0;

	usage_if(argc != 2 || argv[1][0] != '-' || argv[1][2] != '\0');
	op = argv[1][1];

	fprintf(stderr, "Open /dev/i2c/0 with 8bit mode\n");
	die_if(eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e) < 0, 
			"unable to open eeprom device file "
			"(check that the file exists and that it's readable)");
	switch(op)
	{
	case 'r':
		fprintf(stderr, "  Reading 256 bytes from 0x0\n");
		read_from_eeprom(&e, 0, 256);
		break;
	case 'w':
		fprintf(stderr, "  Writing 0x00-0xff into 24C08 \n");
		write_to_eeprom(&e, 0);
		break;
	default:
		usage_if(1);
		exit(1);
	}
	eeprom_close(&e);

	return 0;
}
1.定义结构体变量struct eeprom e;
2.打开设备文件/dev/i2c/0,读取数据
read_from_eeprom(&e, 0, 256);----->eeprom_read_byte
write_to_eeprom(&e, 0);--------->eeprom_write_byte
而读和写最终都是通过ioctl(file,I2C_SMBUS,&args);方法实现的。如下
  1. static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,   
  2.                                      int size, union i2c_smbus_data *data)  
  3. {  
  4.     struct i2c_smbus_ioctl_data args;  
  5.   
  6.     args.read_write = read_write;  
  7.     args.command = command;  
  8.     args.size = size;  
  9.     args.data = data;  
  10.     return ioctl(file,I2C_SMBUS,&args);  
  11. }  
static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, 
                                     int size, union i2c_smbus_data *data)
{
	struct i2c_smbus_ioctl_data args;

	args.read_write = read_write;
	args.command = command;
	args.size = size;
	args.data = data;
	return ioctl(file,I2C_SMBUS,&args);
}

***********************************************************************************************使用ioctl( ,I2C_RDWR, )操作iic
如下的测试代码很直观,借来贴上了。
refer to  http://blog.csdn.net/cjok376240497/article/details/6982883
  1.     #include <stdio.h>      
  2.     #include <linux/types.h>      
  3.     #include <fcntl.h>      
  4.     #include <unistd.h>      
  5.     #include <stdlib.h>      
  6.     #include <sys/types.h>      
  7.     #include <sys/ioctl.h>      
  8.     #include <errno.h>      
  9.     #include <assert.h>      
  10.     #include <string.h>      
  11.     #include <linux/i2c.h>      
  12.     #include <linux/i2c-dev.h>      
  13.            
  14.     int main()      
  15.     {      
  16.              int fd, ret;      
  17.              unsigned char rdwr_addr = 0x66;   /* e2prom 读写地址 */      
  18.              unsigned char device_addr = 0x50; /* e2prom 设备地址 */      
  19.              unsigned char data = 0x7;  /* 向e2prom写的数据 */      
  20.              struct i2c_rdwr_ioctl_data e2prom_data;      
  21.            
  22.              fd= open("/dev/i2c/0", O_RDWR);      
  23.              if(fd < 0) {      
  24.                        perror("openerror");      
  25.                        exit(1);      
  26.              }      
  27.            
  28.              e2prom_data.msgs= (struct i2c_msg *)malloc(e2prom_data.nmsgs * \      
  29.                                                    sizeof(struct i2c_msg));      
  30.              if(e2prom_data.msgs == NULL) {      
  31.                        perror("mallocerror");      
  32.                        exit(1);      
  33.              }      
  34.            
  35.              ioctl(fd,I2C_TIMEOUT, 1); /* 设置超时 */      
  36.              ioctl(fd,I2C_RETRIES, 2); /* 设置重试次数 */      
  37.            
  38.     //向指定地址写入1字节数据               
  39.              /*向e2prom的rdwr_addr地址写入数据data*/      
  40.              e2prom_data.nmsgs= 1;  //http://blog.csdn.net/hongtao_liu/article/details/4964244     
  41.              e2prom_data.msgs[0].len= 2;      
  42.              e2prom_data.msgs[0].addr= device_addr;      
  43.              e2prom_data.msgs[0].flags= 0;     /* write */      
  44.            
  45.                   
  46.              e2prom_data.msgs[0].buf= (unsigned char *)malloc(2);      
  47.              e2prom_data.msgs[0].buf[0]= rdwr_addr;    /* write address */      
  48.              e2prom_data.msgs[0].buf[1]= data;      /* write data */      
  49.            
  50.              ret= ioctl(fd, I2C_RDWR, (unsigned long)&e2prom_data);      
  51.              if(ret < 0) {      
  52.                        perror("writedata error");      
  53.                        exit(1);      
  54.              }      
  55.              //printf("writedata: %d to address: %#x\n", data, rdwr_addr);       
  56.              data= 0;  /* be zero*/      
  57.     //从指定地址读        
  58.     #if 1   
  59.          /*从e2prom的rdwr_addr地址读取数据存入buf*/      
  60.          e2prom_data.nmsgs= 2;      
  61.          e2prom_data.msgs[0].len= 1;      
  62.          e2prom_data.msgs[0].addr= device_addr;      
  63.         e2prom_data.msgs[0].flags= 0;     /* write */      
  64.          e2prom_data.msgs[0].buf= &rdwr_addr;      
  65.        
  66.          e2prom_data.msgs[1].len= 1;      
  67.          e2prom_data.msgs[1].addr= device_addr;      
  68.          e2prom_data.msgs[1].flags= 1;     /* read */      
  69.          e2prom_data.msgs[1].buf= &data;      
  70.     #endif   
  71.     //从当前地址读   
  72.     #if 0  
  73.              /*从e2prom的当前地址读取数据存入buf*/      
  74.              e2prom_data.nmsgs= 1;      
  75.              e2prom_data.msgs[0].len= 5;      
  76.              e2prom_data.msgs[0].addr= device_addr;      
  77.              e2prom_data.msgs[0].flags= 1;     /* read */   
  78.              e2prom_data.msgs[0].buf=(unsigned char *)malloc(5);     
  79.     #endif   
  80.              ret= ioctl(fd, I2C_RDWR, (unsigned long)&e2prom_data);      
  81.              if(ret < 0) {      
  82.                        perror("readerror");      
  83.                        exit(1);      
  84.              }      
  85.              //printf("read  data: %d from address: %#x\n", e2prom_data.msgs[0].buf[0],rdwr_addr);       
  86.                   
  87.              free(e2prom_data.msgs);      
  88.              close(fd);      
  89.              return 0;      
  90.     }  
    #include <stdio.h>    
    #include <linux/types.h>    
    #include <fcntl.h>    
    #include <unistd.h>    
    #include <stdlib.h>    
    #include <sys/types.h>    
    #include <sys/ioctl.h>    
    #include <errno.h>    
    #include <assert.h>    
    #include <string.h>    
    #include <linux/i2c.h>    
    #include <linux/i2c-dev.h>    
         
    int main()    
    {    
             int fd, ret;    
             unsigned char rdwr_addr = 0x66;   /* e2prom 读写地址 */    
             unsigned char device_addr = 0x50; /* e2prom 设备地址 */    
             unsigned char data = 0x7;  /* 向e2prom写的数据 */    
             struct i2c_rdwr_ioctl_data e2prom_data;    
         
             fd= open("/dev/i2c/0", O_RDWR);    
             if(fd < 0) {    
                       perror("openerror");    
                       exit(1);    
             }    
         
             e2prom_data.msgs= (struct i2c_msg *)malloc(e2prom_data.nmsgs * \    
                                                   sizeof(struct i2c_msg));    
             if(e2prom_data.msgs == NULL) {    
                       perror("mallocerror");    
                       exit(1);    
             }    
         
             ioctl(fd,I2C_TIMEOUT, 1); /* 设置超时 */    
             ioctl(fd,I2C_RETRIES, 2); /* 设置重试次数 */    
         
    //向指定地址写入1字节数据            
             /*向e2prom的rdwr_addr地址写入数据data*/    
             e2prom_data.nmsgs= 1;  //http://blog.csdn.net/hongtao_liu/article/details/4964244  
             e2prom_data.msgs[0].len= 2;    
             e2prom_data.msgs[0].addr= device_addr;    
             e2prom_data.msgs[0].flags= 0;     /* write */    
         
                
             e2prom_data.msgs[0].buf= (unsigned char *)malloc(2);    
             e2prom_data.msgs[0].buf[0]= rdwr_addr;    /* write address */    
             e2prom_data.msgs[0].buf[1]= data;      /* write data */    
         
             ret= ioctl(fd, I2C_RDWR, (unsigned long)&e2prom_data);    
             if(ret < 0) {    
                       perror("writedata error");    
                       exit(1);    
             }    
             //printf("writedata: %d to address: %#x\n", data, rdwr_addr);    
             data= 0;  /* be zero*/    
    //从指定地址读     
    #if 1 
         /*从e2prom的rdwr_addr地址读取数据存入buf*/    
         e2prom_data.nmsgs= 2;    
         e2prom_data.msgs[0].len= 1;    
         e2prom_data.msgs[0].addr= device_addr;    
        e2prom_data.msgs[0].flags= 0;     /* write */    
         e2prom_data.msgs[0].buf= &rdwr_addr;    
     
         e2prom_data.msgs[1].len= 1;    
         e2prom_data.msgs[1].addr= device_addr;    
         e2prom_data.msgs[1].flags= 1;     /* read */    
         e2prom_data.msgs[1].buf= &data;    
    #endif 
    //从当前地址读
    #if 0
             /*从e2prom的当前地址读取数据存入buf*/    
             e2prom_data.nmsgs= 1;    
             e2prom_data.msgs[0].len= 5;    
             e2prom_data.msgs[0].addr= device_addr;    
             e2prom_data.msgs[0].flags= 1;     /* read */ 
             e2prom_data.msgs[0].buf=(unsigned char *)malloc(5);   
    #endif 
             ret= ioctl(fd, I2C_RDWR, (unsigned long)&e2prom_data);    
             if(ret < 0) {    
                       perror("readerror");    
                       exit(1);    
             }    
             //printf("read  data: %d from address: %#x\n", e2prom_data.msgs[0].buf[0],rdwr_addr);    
                
             free(e2prom_data.msgs);    
             close(fd);    
             return 0;    
    }
从指定地址读,驱动执行如下动作
  1. [root@FORLINX6410]#  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 338):   
  2.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 339): rdwr_arg.nmsgs=1  
  3.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[0].addr=0x50//设备地址   
  4.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[0].len=2  
  5.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[0]=0x66//要写的内存地址   
  6.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[1]=0x7//要写的数据   
  7.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 338):   
  8.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 339): rdwr_arg.nmsgs=2  
  9.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[0].addr=0x50//设备地址   
  10.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[0].len=1  
  11.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[0]=0x66//要读的内存地址   
  12.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[1].addr=0x50//设备地址   
  13.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[1].len=1  
  14.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[1].buf[0]=0x7//读到的数据  
[root@FORLINX6410]#  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 338): 
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 339): rdwr_arg.nmsgs=1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[0].addr=0x50//设备地址
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[0].len=2
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[0]=0x66//要写的内存地址
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[1]=0x7//要写的数据
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 338): 
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 339): rdwr_arg.nmsgs=2
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[0].addr=0x50//设备地址
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[0].len=1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[0]=0x66//要读的内存地址
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[1].addr=0x50//设备地址
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[1].len=1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[1].buf[0]=0x7//读到的数据
从当前地址读,驱动执行如下动作
  1. [root@FORLINX6410]#  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 338):   
  2.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 339): rdwr_arg.nmsgs=1  
  3.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[0].addr=0x50  
  4.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[0].len=2  
  5.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[0]=0x66  
  6.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[1]=0x7  
  7.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 338):   
  8.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 339): rdwr_arg.nmsgs=1  
  9.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[0].addr=0x50//设备地址   
  10.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[0].len=5//要读的数据个数   
  11.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[0]=0x67//读到的数据,以下均是   
  12.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[1]=0x68  
  13.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[2]=0x69  
  14.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[3]=0x6a  
  15.  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[4]=0x6b  
[root@FORLINX6410]#  DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 338): 
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 339): rdwr_arg.nmsgs=1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[0].addr=0x50
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[0].len=2
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[0]=0x66
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[1]=0x7
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 338): 
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 339): rdwr_arg.nmsgs=1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 343): rdwr_pa[0].addr=0x50//设备地址
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 344): rdwr_pa[0].len=5//要读的数据个数
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[0]=0x67//读到的数据,以下均是
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[1]=0x68
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[2]=0x69
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[3]=0x6a
 DBG(drivers/i2c/i2c-dev.c, i2cdev_ioctl_rdrw(), 347): rdwr_pa[0].buf[4]=0x6b

分析:
根据24cxx手册,
写字节操作如下


即步骤为
start---设备地址(7位)+写标志0(1位)---要写入的内存地址----要写入的数据
注意:设备地址是0x50=101 0000,这个地址的确定见下图,由于a0a1a2接地了,所以设备地址是0x50(只算前7位,不算最后一位的r/w位,所以一条总线最多可以辨别127个设 备)。在驱动中会根据读写要求自动将地址左移一位然后加上读写标志位组成一个字节发送到sda引脚。
i2c-s3c2410.c

static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
                      struct i2c_msg *msg)
{
    unsigned int addr = (msg->addr & 0x7f) << 1;

...}



从指定地址读操作如下:

即步骤为:
start---设备地址(7位)+写标志0(1位)---要读的内存地址---start---设备地址(7位)+读标志1(1位)---读出的数据

注意:这个操作有允许多个start信号,所以程序中使用了两个msg---每个msg都会发送一个start信号

从当前地址读操作如下:


即步骤为:
start---设备地址(7位)+读标志1(1位)---读出的数据
注意:此处可以读一个字节,也可以读多个字节,只要arm在读到第一个字节之后接着去读IICDS寄存器,24cx就会满足arm把下一个地址的数据也发出

************************************************************************************************使用read,write操作iic
如果使用read write操作i2c比如下
  1. ioctl(fd,I2C_SLAVE,0x33);//设置从机地址   
  2. write(fd,buf,num1);//向iic从机写入数据   
  3. memset(buf, 0, sizeof(buf));  
  4. read(fd,buf,num2);//从iic从机接收数据    
ioctl(fd,I2C_SLAVE,0x33);//设置从机地址
write(fd,buf,num1);//向iic从机写入数据
memset(buf, 0, sizeof(buf));
read(fd,buf,num2);//从iic从机接收数据  

则上面的驱动会打印类似如下
  1. DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 203): 发送 1 条写msg,写入的数据如下:  
  2.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 208): msg.flags=0x0  
  3.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 209): msg.addr=0x33  
  4.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 210): msg.len=7  
  5.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[0]=0x1  
  6.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[1]=0x38  
  7.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[2]=0x0  
  8.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[3]=0x0  
  9.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[4]=0xc7  
  10.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[5]=0xff  
  11.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[6]=0x17  
  12.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 165): 发送 1 条读msg,读到的数据如下:  
  13.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 170): msg.flags=0x0  
  14.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 171): msg.addr=0x33  
  15.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 172): msg.len=15  
  16.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[0]=0x1  
  17.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[1]=0x0  
  18.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[2]=0x8  
  19.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[3]=0x0  
  20.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[4]=0x69  
  21.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[5]=0x80  
  22.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[6]=0x2  
  23.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[7]=0x1e  
  24.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[8]=0x3  
  25.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[9]=0x15  
  26.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[10]=0x2  
  27.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[11]=0x1  
  28.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[12]=0xd3  
  29.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[13]=0xfe  
  30.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[14]=0x17  
  31.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 203): 发送 1 条写msg,写入的数据如下:  
  32.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 208): msg.flags=0x0  
  33.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 209): msg.addr=0x33  
  34.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 210): msg.len=8  
  35.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[0]=0x1  
  36.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[1]=0x32  
  37.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[2]=0x1  
  38.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[3]=0x0  
  39.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[4]=0x0  
  40.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[5]=0xcc  
  41.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[6]=0xff  
  42.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[7]=0x17  
  43.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 165): 发送 1 条读msg,读到的数据如下:  
  44.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 170): msg.flags=0x0  
  45.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 171): msg.addr=0x33  
  46.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 172): msg.len=11  
  47.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[0]=0x1  
  48.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[1]=0x0  
  49.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[2]=0x4  
  50.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[3]=0x0  
  51.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[4]=0x26  
  52.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[5]=0x0  
  53.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[6]=0xff  
  54.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[7]=0x0  
  55.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[8]=0xd6  
  56.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[9]=0xfe  
  57.  DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[10]=0x17  
  58.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 203): 发送 1 条写msg,写入的数据如下:  
  59.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 208): msg.flags=0x0  
  60.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 209): msg.addr=0x33  
  61.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 210): msg.len=60  
  62.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[0]=0x1  
  63.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[1]=0x37  
  64.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[2]=0x35  
  65.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[3]=0x0  
  66.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[4]=0x2  
  67.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[5]=0x66  
  68.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[6]=0x70  
  69.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[7]=0x0  
  70.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[8]=0x8f  
  71.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[9]=0x82  
  72.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[10]=0x8e  
  73.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[11]=0x83  
  74.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[12]=0xe0  
  75.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[13]=0x54  
  76.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[14]=0x1  
  77.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[15]=0x0  
  78.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[16]=0x0  
  79.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[17]=0x0  
  80.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[18]=0x70  
  81.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[19]=0xf8  
  82.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[20]=0x22  
  83.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[21]=0x78  
  84.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[22]=0xff  
  85.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[23]=0xe4  
  86.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[24]=0xf6  
  87.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[25]=0xd8  
  88.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[26]=0xfd  
  89.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[27]=0x2  
  90.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[28]=0x67  
  91.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[29]=0x1  
  92.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[30]=0x41  
  93.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[31]=0x13  
  94.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[32]=0x9  
  95.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[33]=0xff  
  96.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[34]=0x63  
  97.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[35]=0x9c  
  98.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[36]=0xe  
  99.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[37]=0xf6  
  100.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[38]=0x75  
  101.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[39]=0x30  
  102.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[40]=0x47  
  103.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[41]=0x35  
  104.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[42]=0x39  
  105.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[43]=0xa5  
  106.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[44]=0x32  
  107.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[45]=0x1  
  108.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[46]=0x2c  
  109.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[47]=0xe3  
  110.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[48]=0x29  
  111.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[49]=0x21  
  112.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[50]=0x26  
  113.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[51]=0x38  
  114.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[52]=0x23  
  115.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[53]=0xdf  
  116.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[54]=0x21  
  117.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[55]=0xed  
  118.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[56]=0x20  
  119.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[57]=0xd2  
  120.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[58]=0xea  
  121.  DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[59]=0x17  
DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 203): 发送 1 条写msg,写入的数据如下:
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 208): msg.flags=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 209): msg.addr=0x33
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 210): msg.len=7
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[0]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[1]=0x38
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[2]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[3]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[4]=0xc7
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[5]=0xff
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[6]=0x17
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 165): 发送 1 条读msg,读到的数据如下:
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 170): msg.flags=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 171): msg.addr=0x33
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 172): msg.len=15
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[0]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[1]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[2]=0x8
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[3]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[4]=0x69
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[5]=0x80
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[6]=0x2
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[7]=0x1e
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[8]=0x3
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[9]=0x15
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[10]=0x2
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[11]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[12]=0xd3
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[13]=0xfe
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[14]=0x17
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 203): 发送 1 条写msg,写入的数据如下:
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 208): msg.flags=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 209): msg.addr=0x33
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 210): msg.len=8
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[0]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[1]=0x32
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[2]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[3]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[4]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[5]=0xcc
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[6]=0xff
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[7]=0x17
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 165): 发送 1 条读msg,读到的数据如下:
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 170): msg.flags=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 171): msg.addr=0x33
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 172): msg.len=11
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[0]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[1]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[2]=0x4
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[3]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[4]=0x26
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[5]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[6]=0xff
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[7]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[8]=0xd6
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[9]=0xfe
 DBG(drivers/i2c/i2c-dev.c, i2cdev_read(), 175): msg.buf[10]=0x17
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 203): 发送 1 条写msg,写入的数据如下:
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 208): msg.flags=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 209): msg.addr=0x33
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 210): msg.len=60
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[0]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[1]=0x37
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[2]=0x35
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[3]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[4]=0x2
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[5]=0x66
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[6]=0x70
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[7]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[8]=0x8f
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[9]=0x82
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[10]=0x8e
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[11]=0x83
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[12]=0xe0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[13]=0x54
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[14]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[15]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[16]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[17]=0x0
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[18]=0x70
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[19]=0xf8
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[20]=0x22
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[21]=0x78
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[22]=0xff
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[23]=0xe4
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[24]=0xf6
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[25]=0xd8
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[26]=0xfd
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[27]=0x2
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[28]=0x67
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[29]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[30]=0x41
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[31]=0x13
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[32]=0x9
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[33]=0xff
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[34]=0x63
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[35]=0x9c
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[36]=0xe
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[37]=0xf6
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[38]=0x75
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[39]=0x30
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[40]=0x47
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[41]=0x35
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[42]=0x39
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[43]=0xa5
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[44]=0x32
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[45]=0x1
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[46]=0x2c
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[47]=0xe3
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[48]=0x29
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[49]=0x21
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[50]=0x26
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[51]=0x38
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[52]=0x23
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[53]=0xdf
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[54]=0x21
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[55]=0xed
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[56]=0x20
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[57]=0xd2
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[58]=0xea
 DBG(drivers/i2c/i2c-dev.c, i2cdev_write(), 213): msg.buf[59]=0x17
很明显,read和write每次只能发送一个msg,对应一个start信号。完全可以用ioctl( ,I2C_RDWR,1)代替。
************************************************************************************************
总之,如下

使用write,read之前,需要使用ioctl(fd,I2C_SLAVE,addr)设置地址,然后直接write或read真正的数据即可
使用ioctl(fd, I2C_RDWR, (unsigned long)&e2prom_data);
时,不必事先使用ioctl设置从机地址,因为 e2prom_data结构中包括地址了,如下
struct i2c_msg {
    __u16 addr;    /* slave address            */
    __u16 flags;
    __u16 len;        /* msg length                */
    __u8 *buf;        /* pointer to msg data            */
};


************************************************************************************************消息第一个字节的发送

master_xfer最终调用i2c-s3c2410.c的s3c24xx_i2c_message_start发送消息,具体发送的仅是消息的地址如下
  1. static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,  
  2.                       struct i2c_msg *msg)  
  3. {  
  4.     unsigned int addr = (msg->addr & 0x7f) << 1;  
  5.     unsigned long stat;  
  6.     unsigned long iiccon;  
  7.   
  8.     stat = 0;  
  9.     stat |=  S3C2410_IICSTAT_TXRXEN;  
  10.   
  11.     if (msg->flags & I2C_M_RD) {  
  12.         stat |= S3C2410_IICSTAT_MASTER_RX;  
  13.         addr |= 1;  
  14.     } else  
  15.         stat |= S3C2410_IICSTAT_MASTER_TX;  
  16.   
  17.     if (msg->flags & I2C_M_REV_DIR_ADDR)  
  18.         addr ^= 1;  
  19.   
  20.     /* todo - check for wether ack wanted or not */  
  21.     s3c24xx_i2c_enable_ack(i2c);//使能ack   
  22.   
  23.     iiccon = readl(i2c->regs + S3C2410_IICCON);  
  24.     writel(stat, i2c->regs + S3C2410_IICSTAT);  
  25.   
  26.     dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);  
  27.     writeb(addr, i2c->regs + S3C2410_IICDS);//写从机地址到IICDS移位寄存器,包含一个读写标志位----第一个发送的字节总是地址   
  28.   
  29.     /* delay here to ensure the data byte has gotten onto the bus 
  30.      * before the transaction is started */  
  31.   
  32.     ndelay(i2c->tx_setup);  
  33.   
  34.     dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);  
  35.     writel(iiccon, i2c->regs + S3C2410_IICCON);  
  36.   
  37.     stat |= S3C2410_IICSTAT_START;  
  38.     writel(stat, i2c->regs + S3C2410_IICSTAT);//开始发送   
  39. #if 0   
  40.     int i;  
  41.     printk("msg->addr=0x%x\n",msg->addr);  
  42.     printk("msg->flags=0x%x\n",msg->flags);  
  43.     printk("msg->len=%d\n",msg->len);  
  44.   
  45.     for(i=0;i<msg->len;i++)  
  46.     {  
  47.     printk("msg->buf[%d]=0x%x\n",i,msg->buf[i]);  
  48.     }  
  49.   
  50.     printk("--\n");  
  51. #endif   
  52. }  
static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
				      struct i2c_msg *msg)
{
	unsigned int addr = (msg->addr & 0x7f) << 1;
	unsigned long stat;
	unsigned long iiccon;

	stat = 0;
	stat |=  S3C2410_IICSTAT_TXRXEN;

	if (msg->flags & I2C_M_RD) {
		stat |= S3C2410_IICSTAT_MASTER_RX;
		addr |= 1;
	} else
		stat |= S3C2410_IICSTAT_MASTER_TX;

	if (msg->flags & I2C_M_REV_DIR_ADDR)
		addr ^= 1;

	/* todo - check for wether ack wanted or not */
	s3c24xx_i2c_enable_ack(i2c);//使能ack

	iiccon = readl(i2c->regs + S3C2410_IICCON);
	writel(stat, i2c->regs + S3C2410_IICSTAT);

	dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
	writeb(addr, i2c->regs + S3C2410_IICDS);//写从机地址到IICDS移位寄存器,包含一个读写标志位----第一个发送的字节总是地址

	/* delay here to ensure the data byte has gotten onto the bus
	 * before the transaction is started */

	ndelay(i2c->tx_setup);

	dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);
	writel(iiccon, i2c->regs + S3C2410_IICCON);

	stat |= S3C2410_IICSTAT_START;
	writel(stat, i2c->regs + S3C2410_IICSTAT);//开始发送
#if 0
	int i;
	printk("msg->addr=0x%x\n",msg->addr);
	printk("msg->flags=0x%x\n",msg->flags);
	printk("msg->len=%d\n",msg->len);

	for(i=0;i<msg->len;i++)
	{
	printk("msg->buf[%d]=0x%x\n",i,msg->buf[i]);
	}

	printk("--\n");
#endif
}

根据6410手册,不同操作模式下的读写顺序为
主机发送

主机接收

下面的从机发送或接收暂时没用到,但也贴出来吧
从机发送


从机接收

其中IICSTAT寄存器

************************************************************************************************消息其他字节的发送或接收

函数s3c24xx_i2c_message_start是作为iic主机读或写时,用于发送消息的第一个字节(即要寻址的从机地址)-----那么消息的其他字节什么时候发送呢??在读消息时,就是其他字节什么时候读呢---在中断函数里面去读或继续发送。
  1. static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)  
  2. {  
  3.     struct s3c24xx_i2c *i2c = dev_id;  
  4.     unsigned long status;  
  5.     unsigned long tmp;  
  6.   
  7.     status = readl(i2c->regs + S3C2410_IICSTAT);  
  8.   
  9.     if (status & S3C2410_IICSTAT_ARBITR) {  
  10.         /* deal with arbitration loss */  
  11.         dev_err(i2c->dev, "deal with arbitration loss\n");  
  12.     }  
  13.   
  14.     if (i2c->state == STATE_IDLE) {  
  15.         dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");  
  16.   
  17.         tmp = readl(i2c->regs + S3C2410_IICCON);  
  18.         tmp &= ~S3C2410_IICCON_IRQPEND;  
  19.         writel(tmp, i2c->regs +  S3C2410_IICCON);  
  20.         goto out;  
  21.     }  
  22.   
  23.     /* pretty much this leaves us with the fact that we've 
  24.      * transmitted or received whatever byte we last sent */  
  25.   
  26.     i2s_s3c_irq_nextbyte(i2c, status);//见下面   
  27.   
  28.  out:  
  29.     return IRQ_HANDLED;  
  30. }  
static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
{
	struct s3c24xx_i2c *i2c = dev_id;
	unsigned long status;
	unsigned long tmp;

	status = readl(i2c->regs + S3C2410_IICSTAT);

	if (status & S3C2410_IICSTAT_ARBITR) {
		/* deal with arbitration loss */
		dev_err(i2c->dev, "deal with arbitration loss\n");
	}

	if (i2c->state == STATE_IDLE) {
		dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");

		tmp = readl(i2c->regs + S3C2410_IICCON);
		tmp &= ~S3C2410_IICCON_IRQPEND;
		writel(tmp, i2c->regs +  S3C2410_IICCON);
		goto out;
	}

	/* pretty much this leaves us with the fact that we've
	 * transmitted or received whatever byte we last sent */

	i2s_s3c_irq_nextbyte(i2c, status);//见下面

 out:
	return IRQ_HANDLED;
}

  1. /* i2s_s3c_irq_nextbyte 
  2.  * 
  3.  * process an interrupt and work out what to do 
  4.  */  
  5.   
  6. static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)  
  7. {  
  8.     unsigned long tmp;  
  9.     unsigned char byte;  
  10.     int ret = 0;  
  11.   
  12.     switch (i2c->state) {  
  13.   
  14.     case STATE_IDLE:  
  15.         dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);  
  16.         goto out;  
  17.         break;  
  18.   
  19.     case STATE_STOP:  
  20.         dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);  
  21.         s3c24xx_i2c_disable_irq(i2c);  
  22.         goto out_ack;  
  23.   
  24.     case STATE_START:  
  25.         /* last thing we did was send a start condition on the 
  26.          * bus, or started a new i2c message 
  27.          */  
  28.   
  29.         if (iicstat & S3C2410_IICSTAT_LASTBIT &&  
  30.             !(i2c->msg->flags & I2C_M_IGNORE_NAK)) {  
  31.             /* ack was not received... */  
  32.   
  33.             dev_dbg(i2c->dev, "ack was not received\n");  
  34.             s3c24xx_i2c_stop(i2c, -ENXIO);  
  35.             goto out_ack;  
  36.         }  
  37.   
  38.         if (i2c->msg->flags & I2C_M_RD)  
  39.             i2c->state = STATE_READ;  
  40.         else  
  41.             i2c->state = STATE_WRITE;  
  42.   
  43.         /* terminate the transfer if there is nothing to do 
  44.          * as this is used by the i2c probe to find devices. */  
  45.   
  46.         if (is_lastmsg(i2c) && i2c->msg->len == 0) {  
  47.             s3c24xx_i2c_stop(i2c, 0);  
  48.             goto out_ack;  
  49.         }  
  50.   
  51.         if (i2c->state == STATE_READ)  
  52.             goto prepare_read;  
  53.   
  54.         /* fall through to the write state, as we will need to 
  55.          * send a byte as well */  
  56.   
  57.     case STATE_WRITE://如果此消息是写标志   
  58.         /* we are writing data to the device... check for the 
  59.          * end of the message, and if so, work out what to do 
  60.          */  
  61.   
  62.         if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {  
  63.             if (iicstat & S3C2410_IICSTAT_LASTBIT) {  
  64.                 dev_dbg(i2c->dev, "WRITE: No Ack\n");  
  65.   
  66.                 s3c24xx_i2c_stop(i2c, -ECONNREFUSED);  
  67.                 goto out_ack;  
  68.             }  
  69.         }  
  70.   
  71.  retry_write:  
  72.   
  73.         if (!is_msgend(i2c)) {//如果不是此消息的buf没有发完   
  74.             byte = i2c->msg->buf[i2c->msg_ptr++];  
  75.             writeb(byte, i2c->regs + S3C2410_IICDS);//写消息的其他字节依次写入IICDS寄存器   
  76.   
  77.             /* delay after writing the byte to allow the 
  78.              * data setup time on the bus, as writing the 
  79.              * data to the register causes the first bit 
  80.              * to appear on SDA, and SCL will change as 
  81.              * soon as the interrupt is acknowledged */  
  82.   
  83.             ndelay(i2c->tx_setup);  
  84.   
  85.         } else if (!is_lastmsg(i2c)) {//如果是消息的最后一个字节   
  86.             /* we need to go to the next i2c message */  
  87.   
  88.             dev_dbg(i2c->dev, "WRITE: Next Message\n");  
  89.   
  90.             i2c->msg_ptr = 0;  
  91.             i2c->msg_idx++;  
  92.             i2c->msg++;  
  93.   
  94.             /* check to see if we need to do another message */  
  95.             if (i2c->msg->flags & I2C_M_NOSTART) {  
  96.   
  97.                 if (i2c->msg->flags & I2C_M_RD) {  
  98.                     /* cannot do this, the controller 
  99.                      * forces us to send a new START 
  100.                      * when we change direction */  
  101.   
  102.                     s3c24xx_i2c_stop(i2c, -EINVAL);  
  103.                 }  
  104.   
  105.                 goto retry_write;  
  106.             } else {  
  107.                 /* send the new start */  
  108.                 s3c24xx_i2c_message_start(i2c, i2c->msg);  
  109.                 i2c->state = STATE_START;  
  110.             }  
  111.   
  112.         } else {  
  113.             /* send stop */  
  114.   
  115.             s3c24xx_i2c_stop(i2c, 0);  
  116.         }  
  117.         break;  
  118.   
  119.     case STATE_READ://如果此消息为读标志   
  120.         /* we have a byte of data in the data register, do 
  121.          * something with it, and then work out wether we are 
  122.          * going to do any more read/write 
  123.          */  
  124.   
  125.         byte = readb(i2c->regs + S3C2410_IICDS);//从IICDS移位寄存器中读出数据   
  126.         i2c->msg->buf[i2c->msg_ptr++] = byte;//数据依次写入消息的buf   
  127.   
  128.  prepare_read:  
  129.         if (is_msglast(i2c)) {  
  130.             /* last byte of buffer */  
  131.   
  132.             if (is_lastmsg(i2c))  
  133.                 s3c24xx_i2c_disable_ack(i2c);  
  134.   
  135.         } else if (is_msgend(i2c)) {  
  136.             /* ok, we've read the entire buffer, see if there 
  137.              * is anything else we need to do */  
  138.   
  139.             if (is_lastmsg(i2c)) {  
  140.                 /* last message, send stop and complete */  
  141.                 dev_dbg(i2c->dev, "READ: Send Stop\n");  
  142.   
  143.                 s3c24xx_i2c_stop(i2c, 0);  
  144.             } else {  
  145.                 /* go to the next transfer */  
  146.                 dev_dbg(i2c->dev, "READ: Next Transfer\n");  
  147.   
  148.                 i2c->msg_ptr = 0;  
  149.                 i2c->msg_idx++;  
  150.                 i2c->msg++;  
  151.             }  
  152.         }  
  153.   
  154.         break;  
  155.     }  
  156.   
  157.     /* acknowlegde the IRQ and get back on with the work */  
  158.   
  159.  out_ack:  
  160.     tmp = readl(i2c->regs + S3C2410_IICCON);  
  161.     tmp &= ~S3C2410_IICCON_IRQPEND;  
  162.     writel(tmp, i2c->regs + S3C2410_IICCON);  
  163.  out:  
  164.     return ret;  
  165. }  
/* i2s_s3c_irq_nextbyte
 *
 * process an interrupt and work out what to do
 */

static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
{
	unsigned long tmp;
	unsigned char byte;
	int ret = 0;

	switch (i2c->state) {

	case STATE_IDLE:
		dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
		goto out;
		break;

	case STATE_STOP:
		dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
		s3c24xx_i2c_disable_irq(i2c);
		goto out_ack;

	case STATE_START:
		/* last thing we did was send a start condition on the
		 * bus, or started a new i2c message
		 */

		if (iicstat & S3C2410_IICSTAT_LASTBIT &&
		    !(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
			/* ack was not received... */

			dev_dbg(i2c->dev, "ack was not received\n");
			s3c24xx_i2c_stop(i2c, -ENXIO);
			goto out_ack;
		}

		if (i2c->msg->flags & I2C_M_RD)
			i2c->state = STATE_READ;
		else
			i2c->state = STATE_WRITE;

		/* terminate the transfer if there is nothing to do
		 * as this is used by the i2c probe to find devices. */

		if (is_lastmsg(i2c) && i2c->msg->len == 0) {
			s3c24xx_i2c_stop(i2c, 0);
			goto out_ack;
		}

		if (i2c->state == STATE_READ)
			goto prepare_read;

		/* fall through to the write state, as we will need to
		 * send a byte as well */

	case STATE_WRITE://如果此消息是写标志
		/* we are writing data to the device... check for the
		 * end of the message, and if so, work out what to do
		 */

		if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
			if (iicstat & S3C2410_IICSTAT_LASTBIT) {
				dev_dbg(i2c->dev, "WRITE: No Ack\n");

				s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
				goto out_ack;
			}
		}

 retry_write:

		if (!is_msgend(i2c)) {//如果不是此消息的buf没有发完
			byte = i2c->msg->buf[i2c->msg_ptr++];
			writeb(byte, i2c->regs + S3C2410_IICDS);//写消息的其他字节依次写入IICDS寄存器

			/* delay after writing the byte to allow the
			 * data setup time on the bus, as writing the
			 * data to the register causes the first bit
			 * to appear on SDA, and SCL will change as
			 * soon as the interrupt is acknowledged */

			ndelay(i2c->tx_setup);

		} else if (!is_lastmsg(i2c)) {//如果是消息的最后一个字节
			/* we need to go to the next i2c message */

			dev_dbg(i2c->dev, "WRITE: Next Message\n");

			i2c->msg_ptr = 0;
			i2c->msg_idx++;
			i2c->msg++;

			/* check to see if we need to do another message */
			if (i2c->msg->flags & I2C_M_NOSTART) {

				if (i2c->msg->flags & I2C_M_RD) {
					/* cannot do this, the controller
					 * forces us to send a new START
					 * when we change direction */

					s3c24xx_i2c_stop(i2c, -EINVAL);
				}

				goto retry_write;
			} else {
				/* send the new start */
				s3c24xx_i2c_message_start(i2c, i2c->msg);
				i2c->state = STATE_START;
			}

		} else {
			/* send stop */

			s3c24xx_i2c_stop(i2c, 0);
		}
		break;

	case STATE_READ://如果此消息为读标志
		/* we have a byte of data in the data register, do
		 * something with it, and then work out wether we are
		 * going to do any more read/write
		 */

		byte = readb(i2c->regs + S3C2410_IICDS);//从IICDS移位寄存器中读出数据
		i2c->msg->buf[i2c->msg_ptr++] = byte;//数据依次写入消息的buf

 prepare_read:
		if (is_msglast(i2c)) {
			/* last byte of buffer */

			if (is_lastmsg(i2c))
				s3c24xx_i2c_disable_ack(i2c);

		} else if (is_msgend(i2c)) {
			/* ok, we've read the entire buffer, see if there
			 * is anything else we need to do */

			if (is_lastmsg(i2c)) {
				/* last message, send stop and complete */
				dev_dbg(i2c->dev, "READ: Send Stop\n");

				s3c24xx_i2c_stop(i2c, 0);
			} else {
				/* go to the next transfer */
				dev_dbg(i2c->dev, "READ: Next Transfer\n");

				i2c->msg_ptr = 0;
				i2c->msg_idx++;
				i2c->msg++;
			}
		}

		break;
	}

	/* acknowlegde the IRQ and get back on with the work */

 out_ack:
	tmp = readl(i2c->regs + S3C2410_IICCON);
	tmp &= ~S3C2410_IICCON_IRQPEND;
	writel(tmp, i2c->regs + S3C2410_IICCON);
 out:
	return ret;
}
************************************************************************************************
附i2c-dev.c源码
  1. /* 
  2.     i2c-dev.c - i2c-bus driver, char device interface 
  3.  
  4.     Copyright (C) 1995-97 Simon G. Vogl 
  5.     Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl> 
  6.     Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com> 
  7.  
  8.     This program is free software; you can redistribute it and/or modify 
  9.     it under the terms of the GNU General Public License as published by 
  10.     the Free Software Foundation; either version 2 of the License, or 
  11.     (at your option) any later version. 
  12.  
  13.     This program is distributed in the hope that it will be useful, 
  14.     but WITHOUT ANY WARRANTY; without even the implied warranty of 
  15.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  16.     GNU General Public License for more details. 
  17.  
  18.     You should have received a copy of the GNU General Public License 
  19.     along with this program; if not, write to the Free Software 
  20.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  21. */  
  22.   
  23. /* Note that this is a complete rewrite of Simon Vogl's i2c-dev module. 
  24.    But I have used so much of his original code and ideas that it seems 
  25.    only fair to recognize him as co-author -- Frodo */  
  26.   
  27. /* The I2C_RDWR ioctl code is written by Kolja Waschk <waschk@telos.de> */  
  28.   
  29. #define DEBUG   
  30. #ifdef DEBUG       
  31. #define DBG(...) printk(" DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); printk(__VA_ARGS__)       
  32. #else       
  33. #define DBG(...)       
  34. #endif       
  35.   
  36. #include <linux/kernel.h>   
  37. #include <linux/module.h>   
  38. #include <linux/fs.h>   
  39. #include <linux/slab.h>   
  40. #include <linux/init.h>   
  41. #include <linux/list.h>   
  42. #include <linux/i2c.h>   
  43. #include <linux/i2c-dev.h>   
  44. #include <linux/jiffies.h>   
  45. #include <linux/uaccess.h>   
  46.   
  47. static struct i2c_driver i2cdev_driver;  
  48.   
  49. /* 
  50.  * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a 
  51.  * slave (i2c_client) with which messages will be exchanged.  It's coupled 
  52.  * with a character special file which is accessed by user mode drivers. 
  53.  * 
  54.  * The list of i2c_dev structures is parallel to the i2c_adapter lists 
  55.  * maintained by the driver model, and is updated using notifications 
  56.  * delivered to the i2cdev_driver. 
  57.  */  
  58. struct i2c_dev {  
  59.     struct list_head list;  
  60.     struct i2c_adapter *adap;  
  61.     struct device *dev;  
  62. };  
  63.   
  64. #define I2C_MINORS  256   
  65. static LIST_HEAD(i2c_dev_list);  
  66. static DEFINE_SPINLOCK(i2c_dev_list_lock);  
  67.   
  68. static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)  
  69. {  
  70.     struct i2c_dev *i2c_dev;  
  71.   
  72.     spin_lock(&i2c_dev_list_lock);  
  73.     list_for_each_entry(i2c_dev, &i2c_dev_list, list) {  
  74.         if (i2c_dev->adap->nr == index)  
  75.             goto found;  
  76.     }  
  77.     i2c_dev = NULL;  
  78. found:  
  79.     spin_unlock(&i2c_dev_list_lock);  
  80.     return i2c_dev;  
  81. }  
  82.   
  83. static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)  
  84. {  
  85.     struct i2c_dev *i2c_dev;  
  86.   
  87.     if (adap->nr >= I2C_MINORS) {  
  88.         printk(KERN_ERR "i2c-dev: Out of device minors (%d)\n",  
  89.                adap->nr);  
  90.         return ERR_PTR(-ENODEV);  
  91.     }  
  92.   
  93.     i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);  
  94.     if (!i2c_dev)  
  95.         return ERR_PTR(-ENOMEM);  
  96.     i2c_dev->adap = adap;  
  97.   
  98.     spin_lock(&i2c_dev_list_lock);  
  99.     list_add_tail(&i2c_dev->list, &i2c_dev_list);  
  100.     spin_unlock(&i2c_dev_list_lock);  
  101.     return i2c_dev;  
  102. }  
  103.   
  104. static void return_i2c_dev(struct i2c_dev *i2c_dev)  
  105. {  
  106.     spin_lock(&i2c_dev_list_lock);  
  107.     list_del(&i2c_dev->list);  
  108.     spin_unlock(&i2c_dev_list_lock);  
  109.     kfree(i2c_dev);  
  110. }  
  111.   
  112. static ssize_t show_adapter_name(struct device *dev,  
  113.                  struct device_attribute *attr, char *buf)  
  114. {  
  115.     struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(dev->devt));  
  116.   
  117.     if (!i2c_dev)  
  118.         return -ENODEV;  
  119.     return sprintf(buf, "%s\n", i2c_dev->adap->name);  
  120. }  
  121. static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);  
  122.   
  123. /* ------------------------------------------------------------------------- */  
  124.   
  125. /* 
  126.  * After opening an instance of this character special file, a file 
  127.  * descriptor starts out associated only with an i2c_adapter (and bus). 
  128.  * 
  129.  * Using the I2C_RDWR ioctl(), you can then *immediately* issue i2c_msg 
  130.  * traffic to any devices on the bus used by that adapter.  That's because 
  131.  * the i2c_msg vectors embed all the addressing information they need, and 
  132.  * are submitted directly to an i2c_adapter.  However, SMBus-only adapters 
  133.  * don't support that interface. 
  134.  * 
  135.  * To use read()/write() system calls on that file descriptor, or to use 
  136.  * SMBus interfaces (and work with SMBus-only hosts!), you must first issue 
  137.  * an I2C_SLAVE (or I2C_SLAVE_FORCE) ioctl.  That configures an anonymous 
  138.  * (never registered) i2c_client so it holds the addressing information 
  139.  * needed by those system calls and by this SMBus interface. 
  140.  */  
  141.   
  142. static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,  
  143.         loff_t *offset)  
  144. {  
  145.     char *tmp;  
  146.     int ret;  
  147.   
  148.     struct i2c_client *client = file->private_data;  
  149.   
  150.     if (count > 8192)  
  151.         count = 8192;  
  152.   
  153.     tmp = kmalloc(count, GFP_KERNEL);  
  154.     if (tmp == NULL)  
  155.         return -ENOMEM;  
  156.   
  157.     pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",  
  158.         iminor(file->f_path.dentry->d_inode), count);  
  159.   
  160.     ret = i2c_master_recv(client, tmp, count);  
  161.   
  162.     if (ret >= 0)  
  163.     {  
  164.     #if 1   
  165.         DBG("发送 1 条读msg,读到的数据如下:\n");  
  166.         struct i2c_msg msg;  
  167.         msg.addr = client->addr;  
  168.         msg.len = count;  
  169.         msg.buf = tmp;  
  170.         DBG("msg.flags=0x%x\n",msg.flags);    
  171.         DBG("msg.addr=0x%x\n",msg.addr);  
  172.         DBG("msg.len=%d\n",msg.len);  
  173.         int i;  
  174.         for(i=0;i<msg.len;i++){  
  175.         DBG("msg.buf[%d]=0x%x\n",i,msg.buf[i]);  
  176.         }  
  177.     #endif   
  178.         ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;  
  179.     }  
  180.           
  181.     kfree(tmp);  
  182.     return ret;  
  183. }  
  184.   
  185. static ssize_t i2cdev_write(struct file *file, const char __user *buf,  
  186.         size_t count, loff_t *offset)  
  187. {  
  188.     int ret;  
  189.     char *tmp;  
  190.     struct i2c_client *client = file->private_data;  
  191.   
  192.     if (count > 8192)  
  193.         count = 8192;  
  194.   
  195.     tmp = memdup_user(buf, count);  
  196.     if (IS_ERR(tmp))  
  197.         return PTR_ERR(tmp);  
  198.   
  199.     pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",  
  200.         iminor(file->f_path.dentry->d_inode), count);  
  201.   
  202. #if 1   
  203.     DBG("发送 1 条写msg,写入的数据如下:\n");  
  204.     struct i2c_msg msg;  
  205.     msg.addr = client->addr;  
  206.     msg.len = count;  
  207.     msg.buf = (char *)buf;  
  208.     DBG("msg.flags=0x%x\n",msg.flags);    
  209.     DBG("msg.addr=0x%x\n",msg.addr);  
  210.     DBG("msg.len=%d\n",msg.len);  
  211.     int i;  
  212.     for(i=0;i<msg.len;i++){  
  213.     DBG("msg.buf[%d]=0x%x\n",i,msg.buf[i]);  
  214.     }  
  215. #endif   
  216.     ret = i2c_master_send(client, tmp, count);  
  217.     kfree(tmp);  
  218.     return ret;  
  219. }  
  220.   
  221. static int i2cdev_check(struct device *dev, void *addrp)  
  222. {  
  223.     struct i2c_client *client = i2c_verify_client(dev);  
  224.   
  225.     if (!client || client->addr != *(unsigned int *)addrp)  
  226.         return 0;  
  227.   
  228.     return dev->driver ? -EBUSY : 0;  
  229. }  
  230.   
  231. /* walk up mux tree */  
  232. static int i2cdev_check_mux_parents(struct i2c_adapter *adapter, int addr)  
  233. {  
  234.     struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);  
  235.     int result;  
  236.   
  237.     result = device_for_each_child(&adapter->dev, &addr, i2cdev_check);  
  238.     if (!result && parent)  
  239.         result = i2cdev_check_mux_parents(parent, addr);  
  240.   
  241.     return result;  
  242. }  
  243.   
  244. /* recurse down mux tree */  
  245. static int i2cdev_check_mux_children(struct device *dev, void *addrp)  
  246. {  
  247.     int result;  
  248.   
  249.     if (dev->type == &i2c_adapter_type)  
  250.         result = device_for_each_child(dev, addrp,  
  251.                         i2cdev_check_mux_children);  
  252.     else  
  253.         result = i2cdev_check(dev, addrp);  
  254.   
  255.     return result;  
  256. }  
  257.   
  258. /* This address checking function differs from the one in i2c-core 
  259.    in that it considers an address with a registered device, but no 
  260.    driver bound to it, as NOT busy. */  
  261. static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)  
  262. {  
  263.     struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);  
  264.     int result = 0;  
  265.   
  266.     if (parent)  
  267.         result = i2cdev_check_mux_parents(parent, addr);  
  268.   
  269.     if (!result)  
  270.         result = device_for_each_child(&adapter->dev, &addr,  
  271.                         i2cdev_check_mux_children);  
  272.   
  273.     return result;  
  274. }  
  275.   
  276. static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,  
  277.         unsigned long arg)  
  278. {  
  279.     struct i2c_rdwr_ioctl_data rdwr_arg;  
  280.     struct i2c_msg *rdwr_pa;  
  281.     u8 __user **data_ptrs;  
  282.     int i, res;  
  283.   
  284.     if (copy_from_user(&rdwr_arg,  
  285.                (struct i2c_rdwr_ioctl_data __user *)arg,  
  286.                sizeof(rdwr_arg)))  
  287.         return -EFAULT;  
  288.   
  289.     /* Put an arbitrary limit on the number of messages that can 
  290.      * be sent at once */  
  291.     if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)  
  292.         return -EINVAL;  
  293.   
  294.     rdwr_pa = kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL);  
  295.     if (!rdwr_pa)  
  296.         return -ENOMEM;  
  297.   
  298.     if (copy_from_user(rdwr_pa, rdwr_arg.msgs,  
  299.                rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {  
  300.         kfree(rdwr_pa);  
  301.         return -EFAULT;  
  302.     }  
  303.   
  304.     data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);  
  305.     if (data_ptrs == NULL) {  
  306.         kfree(rdwr_pa);  
  307.         return -ENOMEM;  
  308.     }  
  309.   
  310.     res = 0;  
  311.     for (i = 0; i < rdwr_arg.nmsgs; i++) {  
  312.         /* Limit the size of the message to a sane amount; 
  313.          * and don't let length change either. */  
  314.         if ((rdwr_pa[i].len > 8192) ||  
  315.             (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {  
  316.             res = -EINVAL;  
  317.             break;  
  318.         }  
  319.         data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;  
  320.         rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len);  
  321.         if (IS_ERR(rdwr_pa[i].buf)) {  
  322.             res = PTR_ERR(rdwr_pa[i].buf);  
  323.             break;  
  324.         }  
  325.     }  
  326.     if (res < 0) {  
  327.         int j;  
  328.         for (j = 0; j < i; ++j)  
  329.             kfree(rdwr_pa[j].buf);  
  330.         kfree(data_ptrs);  
  331.         kfree(rdwr_pa);  
  332.         return res;  
  333.     }  
  334.     res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);  
  335.   
  336.   
  337.     #if 1   
  338.     DBG("\n");  
  339.     DBG("rdwr_arg.nmsgs=%d\n",rdwr_arg.nmsgs);  
  340.     int k,ii;  
  341.     for(ii=0;ii<i;ii++)  
  342.     {  
  343.         DBG("rdwr_pa[%d].addr=0x%x\n",ii,rdwr_pa[ii].addr);  
  344.         DBG("rdwr_pa[%d].len=%d\n",ii,rdwr_pa[ii].len);  
  345.         for(k=0;k<rdwr_pa[ii].len;k++)  
  346.         {  
  347.         DBG("rdwr_pa[%d].buf[%d]=0x%x\n",ii,k,rdwr_pa[ii].buf[k]);  
  348.         }  
  349.     }  
  350.     #endif   
  351.   
  352.     while (i-- > 0) {  
  353.         if (res >= 0 && (rdwr_pa[i].flags & I2C_M_RD)) {  
  354.             if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,  
  355.                      rdwr_pa[i].len))  
  356.                 res = -EFAULT;  
  357.         }  
  358.         kfree(rdwr_pa[i].buf);  
  359.     }  
  360.     kfree(data_ptrs);  
  361.     kfree(rdwr_pa);  
  362.     return res;  
  363. }  
  364.   
  365. static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,  
  366.         unsigned long arg)  
  367. {  
  368.     struct i2c_smbus_ioctl_data data_arg;  
  369.     union i2c_smbus_data temp;  
  370.     int datasize, res;  
  371.   
  372.     if (copy_from_user(&data_arg,  
  373.                (struct i2c_smbus_ioctl_data __user *) arg,  
  374.                sizeof(struct i2c_smbus_ioctl_data)))  
  375.         return -EFAULT;  
  376.     if ((data_arg.size != I2C_SMBUS_BYTE) &&  
  377.         (data_arg.size != I2C_SMBUS_QUICK) &&  
  378.         (data_arg.size != I2C_SMBUS_BYTE_DATA) &&  
  379.         (data_arg.size != I2C_SMBUS_WORD_DATA) &&  
  380.         (data_arg.size != I2C_SMBUS_PROC_CALL) &&  
  381.         (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&  
  382.         (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&  
  383.         (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&  
  384.         (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {  
  385.         dev_dbg(&client->adapter->dev,  
  386.             "size out of range (%x) in ioctl I2C_SMBUS.\n",  
  387.             data_arg.size);  
  388.         return -EINVAL;  
  389.     }  
  390.     /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, 
  391.        so the check is valid if size==I2C_SMBUS_QUICK too. */  
  392.     if ((data_arg.read_write != I2C_SMBUS_READ) &&  
  393.         (data_arg.read_write != I2C_SMBUS_WRITE)) {  
  394.         dev_dbg(&client->adapter->dev,  
  395.             "read_write out of range (%x) in ioctl I2C_SMBUS.\n",  
  396.             data_arg.read_write);  
  397.         return -EINVAL;  
  398.     }  
  399.   
  400.     /* Note that command values are always valid! */  
  401.     if ((data_arg.size == I2C_SMBUS_QUICK) ||  
  402.         ((data_arg.size == I2C_SMBUS_BYTE) &&  
  403.         (data_arg.read_write == I2C_SMBUS_WRITE)))  
  404.         /* These are special: we do not use data */  
  405.         return i2c_smbus_xfer(client->adapter, client->addr,  
  406.                       client->flags, data_arg.read_write,  
  407.                       data_arg.command, data_arg.size, NULL);  
  408.   
  409.     if (data_arg.data == NULL) {  
  410.         dev_dbg(&client->adapter->dev,  
  411.             "data is NULL pointer in ioctl I2C_SMBUS.\n");  
  412.         return -EINVAL;  
  413.     }  
  414.   
  415.     if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||  
  416.         (data_arg.size == I2C_SMBUS_BYTE))  
  417.         datasize = sizeof(data_arg.data->byte);  
  418.     else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||  
  419.          (data_arg.size == I2C_SMBUS_PROC_CALL))  
  420.         datasize = sizeof(data_arg.data->word);  
  421.     else /* size == smbus block, i2c block, or block proc. call */  
  422.         datasize = sizeof(data_arg.data->block);  
  423.   
  424.     if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||  
  425.         (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||  
  426.         (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||  
  427.         (data_arg.read_write == I2C_SMBUS_WRITE)) {  
  428.         if (copy_from_user(&temp, data_arg.data, datasize))  
  429.             return -EFAULT;  
  430.     }  
  431.     if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {  
  432.         /* Convert old I2C block commands to the new 
  433.            convention. This preserves binary compatibility. */  
  434.         data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;  
  435.         if (data_arg.read_write == I2C_SMBUS_READ)  
  436.             temp.block[0] = I2C_SMBUS_BLOCK_MAX;  
  437.     }  
  438. //DBG("\n");   
  439.     res = i2c_smbus_xfer(client->adapter, client->addr, client->flags,  
  440.           data_arg.read_write, data_arg.command, data_arg.size, &temp);  
  441.     if (!res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||  
  442.              (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||  
  443.              (data_arg.read_write == I2C_SMBUS_READ))) {  
  444.         if (copy_to_user(data_arg.data, &temp, datasize))  
  445.             return -EFAULT;  
  446.     }  
  447. //DBG("\n");   
  448.     return res;  
  449. }  
  450.   
  451. static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)  
  452. {  
  453.     struct i2c_client *client = file->private_data;  
  454.     unsigned long funcs;  
  455.   
  456.     dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",  
  457.         cmd, arg);  
  458.   
  459.     switch (cmd) {  
  460.     case I2C_SLAVE:  
  461.     case I2C_SLAVE_FORCE:  
  462.         /* NOTE:  devices set up to work with "new style" drivers 
  463.          * can't use I2C_SLAVE, even when the device node is not 
  464.          * bound to a driver.  Only I2C_SLAVE_FORCE will work. 
  465.          * 
  466.          * Setting the PEC flag here won't affect kernel drivers, 
  467.          * which will be using the i2c_client node registered with 
  468.          * the driver model core.  Likewise, when that client has 
  469.          * the PEC flag already set, the i2c-dev driver won't see 
  470.          * (or use) this setting. 
  471.          */  
  472.         if ((arg > 0x3ff) ||  
  473.             (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))  
  474.             return -EINVAL;  
  475.         if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))  
  476.             return -EBUSY;  
  477.         /* REVISIT: address could become busy later */  
  478.         client->addr = arg;  
  479.         return 0;  
  480.     case I2C_TENBIT:  
  481.         if (arg)  
  482.             client->flags |= I2C_M_TEN;  
  483.         else  
  484.             client->flags &= ~I2C_M_TEN;  
  485.         return 0;  
  486.     case I2C_PEC:  
  487.         if (arg)  
  488.             client->flags |= I2C_CLIENT_PEC;  
  489.         else  
  490.             client->flags &= ~I2C_CLIENT_PEC;  
  491.         return 0;  
  492.     case I2C_FUNCS:  
  493.         funcs = i2c_get_functionality(client->adapter);  
  494.         return put_user(funcs, (unsigned long __user *)arg);  
  495.   
  496.     case I2C_RDWR:  
  497.         return i2cdev_ioctl_rdrw(client, arg);  
  498.   
  499.     case I2C_SMBUS:  
  500.         return i2cdev_ioctl_smbus(client, arg);  
  501.   
  502.     case I2C_RETRIES:  
  503.         client->adapter->retries = arg;  
  504.         break;  
  505.     case I2C_TIMEOUT:  
  506.         /* For historical reasons, user-space sets the timeout 
  507.          * value in units of 10 ms. 
  508.          */  
  509.         client->adapter->timeout = msecs_to_jiffies(arg * 10);  
  510.         break;  
  511.     default:  
  512.         /* NOTE:  returning a fault code here could cause trouble 
  513.          * in buggy userspace code.  Some old kernel bugs returned 
  514.          * zero in this case, and userspace code might accidentally 
  515.          * have depended on that bug. 
  516.          */  
  517.         return -ENOTTY;  
  518.     }  
  519.     return 0;  
  520. }  
  521.   
  522. static int i2cdev_open(struct inode *inode, struct file *file)  
  523. {  
  524.     unsigned int minor = iminor(inode);  
  525.     struct i2c_client *client;  
  526.     struct i2c_adapter *adap;  
  527.     struct i2c_dev *i2c_dev;  
  528.   
  529.     i2c_dev = i2c_dev_get_by_minor(minor);  
  530.     if (!i2c_dev)  
  531.         return -ENODEV;  
  532.   
  533.     adap = i2c_get_adapter(i2c_dev->adap->nr);  
  534.     if (!adap)  
  535.         return -ENODEV;  
  536.   
  537.     /* This creates an anonymous i2c_client, which may later be 
  538.      * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE. 
  539.      * 
  540.      * This client is ** NEVER REGISTERED ** with the driver model 
  541.      * or I2C core code!!  It just holds private copies of addressing 
  542.      * information and maybe a PEC flag. 
  543.      */  
  544.     client = kzalloc(sizeof(*client), GFP_KERNEL);  
  545.     if (!client) {  
  546.         i2c_put_adapter(adap);  
  547.         return -ENOMEM;  
  548.     }  
  549.     snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);  
  550.     client->driver = &i2cdev_driver;  
  551.   
  552.     client->adapter = adap;  
  553.     file->private_data = client;  
  554.   
  555.     return 0;  
  556. }  
  557.   
  558. static int i2cdev_release(struct inode *inode, struct file *file)  
  559. {  
  560.     struct i2c_client *client = file->private_data;  
  561.   
  562.     i2c_put_adapter(client->adapter);  
  563.     kfree(client);  
  564.     file->private_data = NULL;  
  565.   
  566.     return 0;  
  567. }  
  568.   
  569. static const struct file_operations i2cdev_fops = {  
  570.     .owner      = THIS_MODULE,  
  571.     .llseek     = no_llseek,  
  572.     .read       = i2cdev_read,  
  573.     .write      = i2cdev_write,  
  574.     .unlocked_ioctl = i2cdev_ioctl,  
  575.     .open       = i2cdev_open,  
  576.     .release    = i2cdev_release,  
  577. };  
  578.   
  579. /* ------------------------------------------------------------------------- */  
  580.   
  581. /* 
  582.  * The legacy "i2cdev_driver" is used primarily to get notifications when 
  583.  * I2C adapters are added or removed, so that each one gets an i2c_dev 
  584.  * and is thus made available to userspace driver code. 
  585.  */  
  586.   
  587. static struct class *i2c_dev_class;  
  588.   
  589. static int i2cdev_attach_adapter(struct i2c_adapter *adap)  
  590. {  
  591.     struct i2c_dev *i2c_dev;  
  592.     int res;  
  593.   
  594.     i2c_dev = get_free_i2c_dev(adap);  
  595.     if (IS_ERR(i2c_dev))  
  596.         return PTR_ERR(i2c_dev);  
  597.   
  598.     /* register this i2c device with the driver core */  
  599.     i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,  
  600.                      MKDEV(I2C_MAJOR, adap->nr), NULL,  
  601.                      "i2c-%d", adap->nr);  
  602.     if (IS_ERR(i2c_dev->dev)) {  
  603.         res = PTR_ERR(i2c_dev->dev);  
  604.         goto error;  
  605.     }  
  606.     res = device_create_file(i2c_dev->dev, &dev_attr_name);  
  607.     if (res)  
  608.         goto error_destroy;  
  609.   
  610.     pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",  
  611.          adap->name, adap->nr);  
  612.     return 0;  
  613. error_destroy:  
  614.     device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));  
  615. error:  
  616.     return_i2c_dev(i2c_dev);  
  617.     return res;  
  618. }  
  619.   
  620. static int i2cdev_detach_adapter(struct i2c_adapter *adap)  
  621. {  
  622.     struct i2c_dev *i2c_dev;  
  623.   
  624.     i2c_dev = i2c_dev_get_by_minor(adap->nr);  
  625.     if (!i2c_dev) /* attach_adapter must have failed */  
  626.         return 0;  
  627.   
  628.     device_remove_file(i2c_dev->dev, &dev_attr_name);  
  629.     return_i2c_dev(i2c_dev);  
  630.     device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));  
  631.   
  632.     pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);  
  633.     return 0;  
  634. }  
  635.   
  636. static struct i2c_driver i2cdev_driver = {  
  637.     .driver = {  
  638.         .name   = "dev_driver",  
  639.     },  
  640.     .attach_adapter = i2cdev_attach_adapter,  
  641.     .detach_adapter = i2cdev_detach_adapter,  
  642. };  
  643.   
  644. /* ------------------------------------------------------------------------- */  
  645.   
  646. /* 
  647.  * module load/unload record keeping 
  648.  */  
  649.   
  650. static int __init i2c_dev_init(void)  
  651. {  
  652.     int res;  
  653.   
  654.     printk(KERN_INFO "i2c /dev entries driver\n");  
  655.   
  656.     res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);  
  657.     if (res)  
  658.         goto out;  
  659.   
  660.     i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");  
  661.     if (IS_ERR(i2c_dev_class)) {  
  662.         res = PTR_ERR(i2c_dev_class);  
  663.         goto out_unreg_chrdev;  
  664.     }  
  665.   
  666.     res = i2c_add_driver(&i2cdev_driver);  
  667.     if (res)  
  668.         goto out_unreg_class;  
  669.   
  670.     return 0;  
  671.   
  672. out_unreg_class:  
  673.     class_destroy(i2c_dev_class);  
  674. out_unreg_chrdev:  
  675.     unregister_chrdev(I2C_MAJOR, "i2c");  
  676. out:  
  677.     printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);  
  678.     return res;  
  679. }  
  680.   
  681. static void __exit i2c_dev_exit(void)  
  682. {  
  683.     i2c_del_driver(&i2cdev_driver);  
  684.     class_destroy(i2c_dev_class);  
  685.     unregister_chrdev(I2C_MAJOR, "i2c");  
  686. }  
  687.   
  688. MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "  
  689.         "Simon G. Vogl <simon@tk.uni-linz.ac.at>");  
  690. MODULE_DESCRIPTION("I2C /dev entries driver");  
  691. MODULE_LICENSE("GPL");  
  692.   
  693. module_init  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值