一、概览linux i2c驱动子系统
2015-12-26 21:10
696 查看
1、概要
i2c是由PHILIPS推出的串行总线。无论是电气特性和总线协议都比较简单。关于i2c的电气特性和协议请参考i2c的规格说明说。后来intel推出了另一种总线规范SMBus(system management bus)。不过SMBus基本上是基于i2c规范的。关于他们之间的相同和差异,请自行百度。
和spi驱动框架类似,i2c驱动子系统中也有i2c控制器和i2c设备的概念。不过在i2c驱动子系统中,我们称之为i2c adapter和i2c client。只有i2c adapter和i2c client配合起来,连接在i2c总线上的器件才能工作起来。
2、i2c_bus_type
i2c_bus_type 所代表的是i2c总线类型。这数据是在”drivers/i2c/i2c-core.c”中被定义的。它的原型如下:struct bus_type i2c_bus_type = { .name = "i2c", .match = i2c_device_match, .probe = i2c_device_probe, .remove = i2c_device_remove, .shutdown = i2c_device_shutdown, .pm = &i2c_device_pm_ops, }; EXPORT_SYMBOL_GPL(i2c_bus_type);
<1> i2c_device_match
在注册i2c_adapter,
i2c_client和
i2c_driver时,都会被调用来匹配设备和驱动,不过这个函数在开始的时候就判断设备是不是
i2c_client,所以这个函数只能用来匹配
struct i2c_client和
struct i2c_driver。
<2> i2c_device_probe
这个函数是在struct i2c_client和
struct i2c_driver通过
i2c_device_match的匹配规则匹配后被调用。这个函数用来探测i2c设备和驱动。在这个函数中会回调
struct i2c_driver中的
probe()函数来注册相应的设备。
<3> i2c_device_remove
这个函数在删除struct i2c_client会被调用,该函数会回调
struct i2c_driver中的
remove()函数。
<4> i2c_device_shutdown
在关机过程中会被调用来禁止操作设备。这个函数会回调struct i2c_driver中的
shutdown()函数。
<5> i2c_device_pm_ops
电源管理相关操作。基本上都会回调struct i2c_driver.driver.pm中的对应的函数。
3、i2c adapter
一个struct i2c_adapter代表的是一个i2c总线控制器。这个结构体在”include/linux/i2c.h”中被定义。它的原型如下:
struct i2c_adapter { struct module *owner; unsigned int class; /* classes to allow probing for */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_data; /* data fields that are valid for all devices */ struct rt_mutex bus_lock; int timeout; /* in jiffies */ int retries; struct device dev; /* the adapter device */ int nr; char name[48]; struct completion dev_released; struct mutex userspace_clients_lock; struct list_head userspace_clients; struct i2c_bus_recovery_info *bus_recovery_info; };
这里面比较重要的一个字段就是
algo,所有i2c总线相关的数据交换都是调用这个结构中的函数完成的。关于其他的字段,在后面详细讲解。
4、i2c client
一个struct i2c_client代表的是一个连接在i2c总线上的一个设备。它的原型在”include/linux/i2c.h”中被定义的,原型如下:
struct i2c_client { unsigned short flags; /* div., see below */ unsigned short addr; /* chip address - NOTE: 7bit */ /* addresses are stored in the */ /* _LOWER_ 7 bits */ char name[I2C_NAME_SIZE]; struct i2c_adapter *adapter; /* the adapter we sit on */ struct i2c_driver *driver; /* and our access routines */ struct device dev; /* the device structure */ int irq; /* irq issued by device */ struct list_head detected; };
关于各个字段的含义,后面会详细讲解。
5、i2c driver
一个struct i2c_driver代表的就是一类i2c_client的驱动。它的原型如下,在”include/linux/i2c.h”中定义:
struct i2c_driver { unsigned int class; /* Notifies the driver that a new bus has appeared. You should avoid * using this, it will be removed in a near future. */ int (*attach_adapter)(struct i2c_adapter *) __deprecated; /* Standard driver model interfaces */ int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*remove)(struct i2c_client *); /* driver model interfaces that don't relate to enumeration */ void (*shutdown)(struct i2c_client *); int (*suspend)(struct i2c_client *, pm_message_t mesg); int (*resume)(struct i2c_client *); /* Alert callback, for example for the SMBus alert protocol. * The format and meaning of the data value depends on the protocol. * For the SMBus alert protocol, there is a single bit of data passed * as the alert response's low bit ("event flag"). */ void (*alert)(struct i2c_client *, unsigned int data); /* a ioctl like command that can be used to perform specific functions * with the device. */ int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); struct device_driver driver; const struct i2c_device_id *id_table; /* Device detection callback for automatic device creation */ int (*detect)(struct i2c_client *, struct i2c_board_info *); const unsigned short *address_list; struct list_head clients; };
关于各个字段,后面会详细讲解。
6、总结
上述提到的struct i2c_adapter,
struct i2c_client和
struct i2c_driver是i2c子系统工作的核心。注册的
struct i2c_client和
struct i2c_driver匹配,
struct i2c_driver才能驱动
struct i2c_client所代表的硬件设备;cpu和
i2c_client通信又必须调用
struct i2c_adapter中的数据交换的接口。
相关文章推荐
- Linux socket 初步
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- 基于 Linux 集群环境上 GPFS 的问题诊断
- 谁是桌面王者?Win PK Linux三大镇山之宝
- vivi下重新调整分区