1. IIC设备
i2c设备包含了名字、独有的资源等等一些驱动程序的硬件或自定义信息。通过platform_add_devices(platform_device_register)函数将定义的平台设备注册到内核中,用于匹配设备驱动。
内核在drivers\i2c\i2c-s3c2410.c目录中实现了s3c2416 i2c驱动,在mach-home2416.c中实现i2c设备。
static struct resources3c_i2c0_resource[] = {[0]= DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K),[1]= DEFINE_RES_IRQ(IRQ_IIC),};struct platform_device s3c_device_i2c0 ={.name = "s3c2410-i2c",.id = 0,.num_resources = ARRAY_SIZE(s3c_i2c0_resource),.resource = s3c_i2c0_resource,};struct s3c2410_platform_i2cdefault_i2c_data __initdata = {.flags = 0,.slave_addr = 0x10,.frequency = 100*1000,.sda_delay = 100,};void __init s3c_i2c0_set_platdata(structs3c2410_platform_i2c *pd){structs3c2410_platform_i2c *npd;if(!pd) {pd= &default_i2c_data;pd->bus_num= 0;}npd= s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),&s3c_device_i2c0);if(!npd->cfg_gpio)npd->cfg_gpio= s3c_i2c0_cfg_gpio;}
在板级初始化函数home2416_machine_init ()中加入i2c平台数据,s3c_i2c0_set_platdata(NULL),在static struct platform_device *home2416_devices[]板级平台设备列表中加入&s3c_device_i2c0,使i2c设备能够注册到内核中。
2. 内核配置
Linux内核配置支持i2c设备驱动,选中Device Drivers->I2C support->I2CHardware Bus support->S3C2410 I2C Driver。

3. 应用编程
cat/proc/devices可以知道i2c的主设备号为89,次设备号为0,在/dev目录中创建i2c设备文件。
mknod /dev/i2c-0 c 89 0
应用程序可以通过设备文件访问i2c,i2c应用测试代码i2c_test.c实现对eeprom at24cxx的读写。
#include "fcntl.h"#include <stdio.h>#include <stdlib.h>#include <linux/i2c.h>#include <linux/i2c-dev.h>#include <sys/ioctl.h>int main(void){unsignedchar addr;intret;intfd;inti;unsignedchar buf[9];fd= open("/dev/i2c-0", O_RDWR);if(fd == -1) {printf("Openi2c-0 failed\n");exit(1);}ret= ioctl(fd, I2C_TENBIT, 0); // 7 bit addressif(ret == -1) {printf("IO1failed\n");close(fd);exit(1);}ioctl(fd,I2C_SLAVE_FORCE, 0x50); // at24c08 slave address 0x50(7 bit)ioctl(fd,I2C_TIMEOUT, 1);ioctl(fd,I2C_RETRIES, 2);buf[0]= 0x20; // write addressbuf[1]= 0x12; // write 8 bytesbuf[2]= 0x34;buf[3]= 0x56;buf[4]= 0x78;buf[5]= 0x98;buf[6]= 0x76;buf[7]= 0x54;buf[8]= 0x32;ret= write(fd, buf, 9);if(ret == -1) {printf("Writefailed\n");close(fd);exit(1);}printf("write:");for(i=1; i<9; i++) {printf("%02x", buf[i]);}sleep(1);// wait done//read testret= write(fd, buf, 1); // read addressif(ret == -1) {printf("Writefailed\n");close(fd);exit(1);}ret= read(fd, buf, 8); // read 8 bytesif(ret == -1) {printf("Readfailed\n");close(fd);exit(1);}close(fd);printf("read:");for(i=0; i<8; i++) {printf("%02x", buf[i]);}return 0;}
用arm-linux-gcc静态编译,使之生成arm cpu可执行的指令,并且可脱离任何库独立运行,arm-linux-gcc -static -o i2c_test i2c_test.c,生成i2c_test可执行文件。复制可执行文件到根文件系统,目标板启动后在目录输入./i2c_test即可执行。

