I2C
时间:2010-07-21 来源:nearfuture_qinyaomin
1:
i2c总线(串行总线),用于CPU与外设直接进行通信。只有两条线:数据线SDA总线),用于CPU与外设直接进行通信。只有两条线:数据线SDA, 控制线SCL。 具有简单性,有效性,"最主要优点"是:多主控,即可以连接多个设备,但同一时刻只有一个设备成为主设备与CPU通信。为主设备时,可以自己控制当前总线的时钟频率及数据传输。
2:
2.1 总线的构成及信号类型 I2C 总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率 100kbps。各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程 中,I2C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。CPU发出的控制信号分为地址码和控制 量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。这样,各控制电路虽然挂 在同一条总线上,却彼此独立,互不相关。
I2C总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。 开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。 结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。 应 答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元 发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。 目前有很多半导体集成电路上都集成了I2C接口。
2.2 i2c总线是两条线连接多个设备,inter ic. 寻址是通过在scl线上发出寻址信号: 起始,7/10位 地址 + 1位(读/写),(多个后续的数据),终止位。 而地址是由设备的脚决定,一般会有几个固定脚与几个可编程脚。通过编程可以确定设备的地址。当设备收到寻址信号后,判断是不是其地址。
7位寻址,被I2C协会保留,所以一般用10位寻址:s,1111 0xx (R/W) ACK xxxxxxxx 若(R/W) = 0, 则为从MASTER > slave,写 所以10个x为地址 若(R/W) = 1,则为 从 SLAVE > MASTER, 读, 此时先前被寻址了的SLAVE就会发送数据给MASTER。
2.3 i2c是基于8位的 SCL时钟线,由主机提供时钟。 起始位: sda下降,scl保持高 结束位: sda上升,scl保持高。 地址位,一般是10位,被拆分为 xx (r/w) ack xxxxxxxx 数据: 每个字节必须是8位,先传MSB。每个字节后必须跟一个响应位(从机发) 每次从机接收时,可以使SCL为低,从而让主机进入等待状态。
3:"linuxi2c体系结构" 三个层次: 1,i2c核心,内核完成 i2c-core.c 2, i2c总线驱动, 实现 i2c_adapter(总线适配器),i2c_algorithm(通信方法) 3, i2c设备驱动,实现 i2c_driver, i2c_client 通信方法: 通过i2c_msg来表示每次的通信。每次可以收发多个i2c_msg.
//adapter注册,当成是一个platform_bus总线下的设备。 int i2c_add_adapter(struct i2c_adapter *adapter) res = idr_get_new_above(&i2c_adapter_idr, adapter,__i2c_first_dynamic_bus_num, &id); i2c_register_adapter(adapter); static int i2c_register_adapter(struct i2c_adapter *adap) { if (adap->dev.parent == NULL) adap->dev.parent = &platform_bus; adap->dev.release = &i2c_adapter_dev_release; adap->dev.class = &i2c_adapter_class; res = device_register(&adap->dev); } //i2c_add_adapter()而言,它使用的是动态总线号,即由系统给其分析一个总线号,而i2c_add_numbered_adapter()则是自己指定总线号,
//i2c_driver注册, 即driver先匹配所有adapter,找到正确的,然后检测硬件,生成对应的i2c_client, 然后把i2c_client注册到adapter上。 当 i2c_driver向内核注册时,会被调用attach_adatper,先匹配当前系统中所有adapter,再去检测硬件,当确定硬件存在,则会生 成匹配i2c_client?, 把i2c_client的driver指针指向自己(driver),adapter指针指向其adapter.然后会让这个adapter调用 其client_register.
注册: static inline int i2c_add_driver(struct i2c_driver *driver) { return i2c_register_driver(THIS_MODULE, driver); } int i2c_register_driver(struct module *owner, struct i2c_driver *driver) { driver->driver.owner = owner; driver->driver.bus = &i2c_bus_type; res = driver_register(&driver->driver); //注册代表本 i2c_driver的 内部 driver class_for_each_device(&i2c_adapter_class, NULL, driver, __attach_adapter); //从目前系统中所的adapter中去匹配 对应的 adapter. } static int __attach_adapter(struct device *dev, void *da ta) { struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = da ta;
i2c_detect(adapter, driver); //检测硬件
/* Legacy drivers scan i2c busses directly */ if (driver->attach_adapter) driver->attach_adapter(adapter); //生成client 并加入到adapter 中。 return 0; } 而一般 i2c_driver的实现时是: static int yy_attach_adapter(struct i2c_adapter *adapter) { return i2c_probe(adapter, &addr_da ta, yy_detect); }
static int yy_detect (struct i2c_adapter * adapter, int address, int kind) { struct yy_da ta da ta = kzalloc(sizeof(struct yy_da ta), GFP_KERNEL); i2c_client new_client = da ta->client; err = i2c_attach_client(new_client); }
/* * The following structs are for those who like to implement new bus drivers: * i2c_algorithm is the interface to a class of hardware solutions which can * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584 * to name two of the most common. */ struct i2c_algorithm { /* If an adapter algorithm can't do I2C-level access, set master_xfer to NULL. If an adapter algorithm can do SMBus access, set smbus_xfer. If set to NULL, the SMBus protocol is simulated using common I2C messages */ /* master_xfer should return the number of messages successfully processed, or a negative value on error */ int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, "i2c传输函数" int num); int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, "smbus传输函数" unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_da ta *da ta);
/* To determine what the adapter supports */ u32 (*functionality) (struct i2c_adapter *); "返回适配器支持的功能" }; /* * i2c_adapter is the structure used to identify a physical i2c bus along * with the access algorithms necessary to access it. */ struct i2c_adapter { "代表 一个物理的I2C总线" struct module *owner; unsigned int id; unsigned int class; /* classes to allow probing for */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_da ta;
/* --- administration stuff. */ int (*client_register)(struct i2c_client *); int (*client_unregister)(struct i2c_client *);
/* da ta fields that are valid for all devices */ u8 level; /* nesting level for lockdep */ struct mutex bus_lock; struct mutex clist_lock;
int timeout; /* in jiffies */ int retries; struct device dev; /* the adapter device */
int nr; struct list_head clients; /* DEPRECATED */ char name[48]; struct completion dev_released; };
/** * struct i2c_driver - represent an I2C device driver * @id: Unique driver ID (optional) * @class: What kind of i2c device we instantiate (for detect) * @attach_adapter: Callback for bus addition (for legacy drivers) * @detach_adapter: Callback for bus removal (for legacy drivers) * @detach_client: Callback for device removal (for legacy drivers) * @probe: Callback for device binding (new-style drivers) * @remove: Callback for device unbinding (new-style drivers) * @shutdown: Callback for device shutdown * @suspend: Callback for device suspend * @resume: Callback for device resume * @command: Callback for bus-wide signaling (optional) * @driver: Device driver model driver * @id_table: List of I2C devices supported by this driver * @detect: Callback for device detection * @address_da ta: The I2C addresses to probe, ignore or force (for detect) * @clients: List of detected clients we created (for i2c-core use on ly) * * The driver.owner field should be set to the module owner of this driver. * The driver.name field should be set to the name of this driver. * * For automatic device detection, both @detect and @address_da ta must * be defined. @class should also be set, otherwise on ly devices forced * with module parameters will be created. The detect function must * fill at least the name field of the i2c_board_info structure it is * handed upon successful detection, and possibly also the flags field. * * If @detect is missing, the driver will still work fine for enumerated * devices. Detected devices simply won't be supported. This is expected * for the many I2C/SMBus devices which can't be detected reliably, and * the on es which can always be enumerated in practice. * * The i2c_client structure which is handed to the @detect callback is * not a real i2c_client. It is initialized just enough so that you can * call i2c_smbus_read_byte_da ta and friends on it. Don't do anything * else with it. In particular, calling dev_dbg and friends on it is * not allowed. */ struct i2c_driver { int id; unsigned int class;
/* Notifies the driver that a new bus has appeared. This routine * can be used by the driver to test if the bus meets its conditions * & seek for the presence of the chip(s) it supports. If found, it * registers the client(s) that are on the bus to the i2c admin. via * i2c_attach_client. (LEGACY I2C DRIVERS ON LY) */ int (*attach_adapter)(struct i2c_adapter *); int (*detach_adapter)(struct i2c_adapter *);
/* tells the driver that a client is about to be deleted & gives it * the chance to remove its private da ta. Also, if the client struct * has been dynamically allocated by the driver in the function above, * it must be freed here. (LEGACY I2C DRIVERS ON LY) */ int (*detach_client)(struct i2c_client *) __deprecated;
/* Standard driver model interfaces, for "new style" i2c drivers. * With the driver model, device enumeration is NEVER done by drivers; * it's done by infrastructure. (NEW STYLE DRIVERS ON LY) */ 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 *);
/* 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); "类似ioctl"
struct device_driver driver; const struct i2c_device_id *id_table; "与本驱动 匹配的 设备id"
/* Device detection callback for automatic device creation */ int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *); "设备检测" const struct i2c_client_address_da ta *address_da ta; struct list_head clients; };
/** * struct i2c_client - represent an I2C slave device * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address; * I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking * @addr: Address used on the I2C bus connected to the parent adapter. * @name: Indicates the type of the device, usually a chip name that's * generic enough to hide second-sourcing and compatible revisions. * @adapter: manages the bus segment hosting this I2C device * @driver: device's driver, hence pointer to access routines * @dev: Driver model device node for the slave. * @irq: indicates the IRQ generated by this device (if any) * @list: list of active/busy clients (DEPRECATED) * @detected: member of an i2c_driver.clients list * @released: used to synchronize client releases & detaches and references * * An i2c_client identifies a single device (i.e. chip) connected to an * i2c bus. The behaviour exposed to Linux is defined by the driver * managing the device. */ 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 list; /* DEPRECATED */ struct list_head detected; struct completion released; };
/** * struct i2c_board_info - template for device creation * @type: chip type, to initialize i2c_client.name * @flags: to initialize i2c_client.flags * @addr: stored in i2c_client.addr * @platform_da ta: stored in i2c_client.dev.platform_da ta * @archdata: copied into i2c_client.dev.archdata * @irq: stored in i2c_client.irq * * I2C doesn't actually support hardware probing, although controllers and * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's * a device at a given address. Drivers commonly need more information than * that, such as chip type, configuration, associated IRQ, and so on. * * i2c_board_info is used to build tables of information listing I2C devices * that are present. This information is used to grow the driver model tree * for "new style" I2C drivers. For mainboards this is done statically using * i2c_register_board_info(); bus numbers identify adapters that aren't * yet available. For add-on boards, i2c_new_device() does this dynamically * with the adapter already known. */ struct i2c_board_info { char type[I2C_NAME_SIZE]; unsigned short flags; unsigned short addr; void *platform_da ta; struct dev_archdata *archdata; int irq; }; struct i2c_devinfo { struct list_head list; int busnum; struct i2c_board_info board_info; };
//***************************************************************// struct i2c_msg { __u16 addr; /* slave address */ __u16 flags; #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ #define I2C_M_RD 0x0001 /* read da ta, from slave to master */ #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ __u16 len; /* msg length */ __u8 *buf; /* pointer to msg da ta */ };
2:
2.1 总线的构成及信号类型 I2C 总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率 100kbps。各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程 中,I2C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。CPU发出的控制信号分为地址码和控制 量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。这样,各控制电路虽然挂 在同一条总线上,却彼此独立,互不相关。
I2C总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。 开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。 结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。 应 答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元 发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。 目前有很多半导体集成电路上都集成了I2C接口。
2.2 i2c总线是两条线连接多个设备,inter ic. 寻址是通过在scl线上发出寻址信号: 起始,7/10位 地址 + 1位(读/写),(多个后续的数据),终止位。 而地址是由设备的脚决定,一般会有几个固定脚与几个可编程脚。通过编程可以确定设备的地址。当设备收到寻址信号后,判断是不是其地址。
7位寻址,被I2C协会保留,所以一般用10位寻址:s,1111 0xx (R/W) ACK xxxxxxxx 若(R/W) = 0, 则为从MASTER > slave,写 所以10个x为地址 若(R/W) = 1,则为 从 SLAVE > MASTER, 读, 此时先前被寻址了的SLAVE就会发送数据给MASTER。
2.3 i2c是基于8位的 SCL时钟线,由主机提供时钟。 起始位: sda下降,scl保持高 结束位: sda上升,scl保持高。 地址位,一般是10位,被拆分为 xx (r/w) ack xxxxxxxx 数据: 每个字节必须是8位,先传MSB。每个字节后必须跟一个响应位(从机发) 每次从机接收时,可以使SCL为低,从而让主机进入等待状态。
3:"linuxi2c体系结构" 三个层次: 1,i2c核心,内核完成 i2c-core.c 2, i2c总线驱动, 实现 i2c_adapter(总线适配器),i2c_algorithm(通信方法) 3, i2c设备驱动,实现 i2c_driver, i2c_client 通信方法: 通过i2c_msg来表示每次的通信。每次可以收发多个i2c_msg.
//adapter注册,当成是一个platform_bus总线下的设备。 int i2c_add_adapter(struct i2c_adapter *adapter) res = idr_get_new_above(&i2c_adapter_idr, adapter,__i2c_first_dynamic_bus_num, &id); i2c_register_adapter(adapter); static int i2c_register_adapter(struct i2c_adapter *adap) { if (adap->dev.parent == NULL) adap->dev.parent = &platform_bus; adap->dev.release = &i2c_adapter_dev_release; adap->dev.class = &i2c_adapter_class; res = device_register(&adap->dev); } //i2c_add_adapter()而言,它使用的是动态总线号,即由系统给其分析一个总线号,而i2c_add_numbered_adapter()则是自己指定总线号,
//i2c_driver注册, 即driver先匹配所有adapter,找到正确的,然后检测硬件,生成对应的i2c_client, 然后把i2c_client注册到adapter上。 当 i2c_driver向内核注册时,会被调用attach_adatper,先匹配当前系统中所有adapter,再去检测硬件,当确定硬件存在,则会生 成匹配i2c_client?, 把i2c_client的driver指针指向自己(driver),adapter指针指向其adapter.然后会让这个adapter调用 其client_register.
注册: static inline int i2c_add_driver(struct i2c_driver *driver) { return i2c_register_driver(THIS_MODULE, driver); } int i2c_register_driver(struct module *owner, struct i2c_driver *driver) { driver->driver.owner = owner; driver->driver.bus = &i2c_bus_type; res = driver_register(&driver->driver); //注册代表本 i2c_driver的 内部 driver class_for_each_device(&i2c_adapter_class, NULL, driver, __attach_adapter); //从目前系统中所的adapter中去匹配 对应的 adapter. } static int __attach_adapter(struct device *dev, void *da ta) { struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = da ta;
i2c_detect(adapter, driver); //检测硬件
/* Legacy drivers scan i2c busses directly */ if (driver->attach_adapter) driver->attach_adapter(adapter); //生成client 并加入到adapter 中。 return 0; } 而一般 i2c_driver的实现时是: static int yy_attach_adapter(struct i2c_adapter *adapter) { return i2c_probe(adapter, &addr_da ta, yy_detect); }
static int yy_detect (struct i2c_adapter * adapter, int address, int kind) { struct yy_da ta da ta = kzalloc(sizeof(struct yy_da ta), GFP_KERNEL); i2c_client new_client = da ta->client; err = i2c_attach_client(new_client); }
/* * The following structs are for those who like to implement new bus drivers: * i2c_algorithm is the interface to a class of hardware solutions which can * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584 * to name two of the most common. */ struct i2c_algorithm { /* If an adapter algorithm can't do I2C-level access, set master_xfer to NULL. If an adapter algorithm can do SMBus access, set smbus_xfer. If set to NULL, the SMBus protocol is simulated using common I2C messages */ /* master_xfer should return the number of messages successfully processed, or a negative value on error */ int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, "i2c传输函数" int num); int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, "smbus传输函数" unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_da ta *da ta);
/* To determine what the adapter supports */ u32 (*functionality) (struct i2c_adapter *); "返回适配器支持的功能" }; /* * i2c_adapter is the structure used to identify a physical i2c bus along * with the access algorithms necessary to access it. */ struct i2c_adapter { "代表 一个物理的I2C总线" struct module *owner; unsigned int id; unsigned int class; /* classes to allow probing for */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_da ta;
/* --- administration stuff. */ int (*client_register)(struct i2c_client *); int (*client_unregister)(struct i2c_client *);
/* da ta fields that are valid for all devices */ u8 level; /* nesting level for lockdep */ struct mutex bus_lock; struct mutex clist_lock;
int timeout; /* in jiffies */ int retries; struct device dev; /* the adapter device */
int nr; struct list_head clients; /* DEPRECATED */ char name[48]; struct completion dev_released; };
/** * struct i2c_driver - represent an I2C device driver * @id: Unique driver ID (optional) * @class: What kind of i2c device we instantiate (for detect) * @attach_adapter: Callback for bus addition (for legacy drivers) * @detach_adapter: Callback for bus removal (for legacy drivers) * @detach_client: Callback for device removal (for legacy drivers) * @probe: Callback for device binding (new-style drivers) * @remove: Callback for device unbinding (new-style drivers) * @shutdown: Callback for device shutdown * @suspend: Callback for device suspend * @resume: Callback for device resume * @command: Callback for bus-wide signaling (optional) * @driver: Device driver model driver * @id_table: List of I2C devices supported by this driver * @detect: Callback for device detection * @address_da ta: The I2C addresses to probe, ignore or force (for detect) * @clients: List of detected clients we created (for i2c-core use on ly) * * The driver.owner field should be set to the module owner of this driver. * The driver.name field should be set to the name of this driver. * * For automatic device detection, both @detect and @address_da ta must * be defined. @class should also be set, otherwise on ly devices forced * with module parameters will be created. The detect function must * fill at least the name field of the i2c_board_info structure it is * handed upon successful detection, and possibly also the flags field. * * If @detect is missing, the driver will still work fine for enumerated * devices. Detected devices simply won't be supported. This is expected * for the many I2C/SMBus devices which can't be detected reliably, and * the on es which can always be enumerated in practice. * * The i2c_client structure which is handed to the @detect callback is * not a real i2c_client. It is initialized just enough so that you can * call i2c_smbus_read_byte_da ta and friends on it. Don't do anything * else with it. In particular, calling dev_dbg and friends on it is * not allowed. */ struct i2c_driver { int id; unsigned int class;
/* Notifies the driver that a new bus has appeared. This routine * can be used by the driver to test if the bus meets its conditions * & seek for the presence of the chip(s) it supports. If found, it * registers the client(s) that are on the bus to the i2c admin. via * i2c_attach_client. (LEGACY I2C DRIVERS ON LY) */ int (*attach_adapter)(struct i2c_adapter *); int (*detach_adapter)(struct i2c_adapter *);
/* tells the driver that a client is about to be deleted & gives it * the chance to remove its private da ta. Also, if the client struct * has been dynamically allocated by the driver in the function above, * it must be freed here. (LEGACY I2C DRIVERS ON LY) */ int (*detach_client)(struct i2c_client *) __deprecated;
/* Standard driver model interfaces, for "new style" i2c drivers. * With the driver model, device enumeration is NEVER done by drivers; * it's done by infrastructure. (NEW STYLE DRIVERS ON LY) */ 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 *);
/* 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); "类似ioctl"
struct device_driver driver; const struct i2c_device_id *id_table; "与本驱动 匹配的 设备id"
/* Device detection callback for automatic device creation */ int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *); "设备检测" const struct i2c_client_address_da ta *address_da ta; struct list_head clients; };
/** * struct i2c_client - represent an I2C slave device * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address; * I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking * @addr: Address used on the I2C bus connected to the parent adapter. * @name: Indicates the type of the device, usually a chip name that's * generic enough to hide second-sourcing and compatible revisions. * @adapter: manages the bus segment hosting this I2C device * @driver: device's driver, hence pointer to access routines * @dev: Driver model device node for the slave. * @irq: indicates the IRQ generated by this device (if any) * @list: list of active/busy clients (DEPRECATED) * @detected: member of an i2c_driver.clients list * @released: used to synchronize client releases & detaches and references * * An i2c_client identifies a single device (i.e. chip) connected to an * i2c bus. The behaviour exposed to Linux is defined by the driver * managing the device. */ 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 list; /* DEPRECATED */ struct list_head detected; struct completion released; };
/** * struct i2c_board_info - template for device creation * @type: chip type, to initialize i2c_client.name * @flags: to initialize i2c_client.flags * @addr: stored in i2c_client.addr * @platform_da ta: stored in i2c_client.dev.platform_da ta * @archdata: copied into i2c_client.dev.archdata * @irq: stored in i2c_client.irq * * I2C doesn't actually support hardware probing, although controllers and * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's * a device at a given address. Drivers commonly need more information than * that, such as chip type, configuration, associated IRQ, and so on. * * i2c_board_info is used to build tables of information listing I2C devices * that are present. This information is used to grow the driver model tree * for "new style" I2C drivers. For mainboards this is done statically using * i2c_register_board_info(); bus numbers identify adapters that aren't * yet available. For add-on boards, i2c_new_device() does this dynamically * with the adapter already known. */ struct i2c_board_info { char type[I2C_NAME_SIZE]; unsigned short flags; unsigned short addr; void *platform_da ta; struct dev_archdata *archdata; int irq; }; struct i2c_devinfo { struct list_head list; int busnum; struct i2c_board_info board_info; };
//***************************************************************// struct i2c_msg { __u16 addr; /* slave address */ __u16 flags; #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ #define I2C_M_RD 0x0001 /* read da ta, from slave to master */ #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ __u16 len; /* msg length */ __u8 *buf; /* pointer to msg da ta */ };
相关阅读 更多 +