Linux2.6.30/driver/i2c/
1.algos: 协议算法相关的东西
2.busses: 各种平台的i2c总线驱动(i2c控制器驱动/i2c适配器驱动)
3.chips: 各种i2c设备驱动(e2prom/某种传感器/触摸屏)
4.i2c-core.c i2c-dev.c: i2c子系统的通用文件(i2c核心层,提供一些通用函数接口)
应用层app: open("设备文件") write read
====================================================================
内核的核心部分 VFS:sys_open sys_write sys_read
向上提供操作驱动的接口: 1.申请主设备号,注册通用接口 register——chrdev
2.构建file_operations结构体.open.write -->利用子系统核心层的函数来找到下层的操作方法.read
(工作层) 3.i2c设备驱动层(e2prom驱动/触摸屏驱动/传感器驱动) :提供策略
2.i2c核心层(i2c-core.c)提供一些通用函数接口,提供了注册/注销的方法
1.i2c总线驱动层(i2c控制器驱动/i2c适配器驱动) :提供操作一个硬件的能力做准备工作--》1.构建一个适配器结构体struct i2c_adapter(用来描述一个i2c设备)
1. 成员:任何一个控制器都应该有套算法const struct i2c_algorithm *algo;2. 任何一套算法都应该有一套函数来实现*master_xfer //实现这个函数--》实现读写操作方法
2.初始化控制器--》会用到平台设备驱动机制3.注册到子系统当中去 i2c_add_adapter
======================================================================
硬件: i2c控制器设备||\/
i2c设备(e2prom)
应用层app: open("设备文件") write read
====================================================================
VFS:sys_open sys_write sys_read
1.i2c设备驱动: 两种写法 (1)万能接口驱动(i2c-dev.c)
(2)e2prom驱动、传感器驱动1.构建file_operations结构体
.open.write.read
2.创建设备文件
kernel:
驱动: 2.i2c核心层
3.i2c总线驱动
===========================================================================
i2c控制器
e2prom 传感器
i2c-dev.c文件分析:
==========================================================
static struct i2c_driver i2cdev_dirver = {
.driver = {.name = "dev_driver",},.attach_adapter = i2cdev_attach_adapter,.detach_adapter = i2cdev_detach_adapter,
};
入口函数:
i2c_dev_init/*注册*/1.register_chrdev();/*创建一个类*/2.class_create();/*加载i2c驱动*/3.i2c_add_driver();1.加载i2c设备驱动结构体,加载到一个链表中2.搜索i2c_adapter链表,每搜索一个都会调用.attach_adapter
i2cdev_attach_adapter 函数分析:
===========================================open("dev/i2c-1");
创建一个设备文件
1.device_create(); //底层有几个i2c适配器就会创建几个设备文件,而且创建的设备文件名为:i2c-0,i2c-1 ...
如何来用i2c通用接口驱动
=================================================
open
sys_openfile_operations--> i2cdev_fops.open = i2cdev_open
/*1.获取次设备号*/unsigned int minor = iminor(inode);
/*2.创建三个结构体*/struct i2c_client *client;struct i2c_adapter *adap;struct i2c_dev *i2c_dev;
/*3.获取i2c_dev*/i2c_dev = i2c_dev_get_by_minor();
/*4.获取i2c配置*/adap = i2c_get_adapter();
/*5.设置i2c-client*/client->adapter = adap;file->private_data = client;
ioctl(fd, I2C_SLAVE, addr)
sys_ioctl
file_operations --> i2cdev_fops.ioctl = i2cdev_ioctl
/*1.从file->private_data里面取出i2c_client*/struct i2c_client *client = (struct i2c_client *)file->private_data;case I2C_SLAVE:
client->addr = arg;
write
sys_write
file_operations--> i2cdev_fops.write = i2cdev_write //i2c设备层/*1.从file->private_data里面取出i2c_client*/struct i2c_client *client = (struct i2c_client *)file->private_data;/*2.发送数据*/ret = i2c_master_send(); //开始进入i2c核心层struct i2c_adapter *adap = client->adapter;struct i2c_msg msg; //构建一个写消息结构体msg.addr = client->addr; //上面ioctl写入msg.flags = client->flags *I2C_M_TEN;msg.len = count;msg.buf = (char *)buf;/*转接到底层的函数*/i2c_transfer();adap->algo->master_xfer(); //开始进入总线驱动层
read
sys_read
file_operations--> i2cdev_fops.read = i2cdev_read //i2c设备层/*1.从file->private_data里面取出i2c_client*/struct i2c_client *client = (struct i2c_client *)file->private_data;tmp = kmalloc(count, GFP_KERNEL);ret = i2c_master_recv();struct i2c_adapter *adap = client->adapter;struct i2c_msg msg; //构建一个写消息结构体msg.addr = client->addr; //上面ioctl写入msg.flags = client->flags *I2C_M_TEN;msg.flags |= I2C_M_RD; //将标记改为读msg.len = count;msg.buf = (char *)buf;copy_to_user(buf, tmp, count);
i2c子系统涉及的函数接口与重要结构体
===================================================================
1.struct i2c_driver //描述一个i2c设备驱动
2.struct i2c_adapter //描述一个i2c控制器/i2c适配器
3.struct i2c_client *client; //描述一个i2c设备(如:e2prom)
.addr = 0xa0.adapter =.driver
4.struct i2c_msg //描述一个i2c消息
.__u16 addr; /*器件地址*/.__u16 flags; /*要读还是写*/0:写 1:读.__u16 len; /*数据长度*/.__u8 *buf; /*要写入的数据,或者读出来的数据放在这里*/
函数接口:
1.i2c_add_driver //加载i2c设备驱动结构体,加载到一个链表里面
2.i2c_add_adapter //加载i2c适配器结构体到适配器链表
3.i2c_master_send //发送数据函数
4.i2c_transfer; //转接到底层的函数