I2C子系统几个主要的结构体

i2c data structure我们要搞懂一个 linux 子系统,必须研究它的数据结构,搞懂每个结构体存储了什么东西,才能梳理清楚该子系统的架构。
i2c 子系统有几个主要的结构体:
i2c 控制器:i2c_adapter、i2c_algorithm、mtk_i2ci2c 设备驱动:i2c_client、i2c_driveri2c 传输:i2c_msgi2c_adapter:i2c-core 层描述一个 i2c 控制器,假如一个芯片有 8 路 i2c bus,则有 8 个 i2c_adapter。请详细看博主对 code 的注释说明。
struct i2c_adapter { struct module *owner; unsigned int class; /* 该 i2c bus 支持哪些类型的从设备 */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_data; /* data fields that are valid for all devices */ const struct i2c_lock_operations *lock_ops; struct rt_mutex bus_lock; struct rt_mutex mux_lock; int timeout;/* 超过该时间无法重发 */ int retries;/* i2c发送失败重试次数 */ struct device dev; /* the adapter device */ unsigned long locked_flags; /* owned by the i2c core */#define i2c_alf_is_suspended 0#define i2c_alf_suspend_reported 1 int nr;/*i2c bus id*/ 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; const struct i2c_adapter_quirks *quirks; struct irq_domain *host_notify_domain; struct regulator *bus_regulator;};i2c_algorithm:i2c 传输函数合集,其中 master_xfer 是真正的传输函数 ,芯片原厂写 i2c 控制器驱动时必须实现。functionality 函数会返回该 i2c 控制器支持什么通信协议,也需要实现,其他的函数即便 linux 规定了,芯片原厂也可以不实现,因为不常用。
struct i2c_algorithm { int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,int num); int (*master_xfer_atomic)(struct i2c_adapter *adap,struct i2c_msg *msgs, int num); int (*smbus_xfer)(struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union i2c_smbus_data *data); int (*smbus_xfer_atomic)(struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union i2c_smbus_data *data); /* to determine what the adapter supports */ u32 (*functionality)(struct i2c_adapter *adap);#if is_enabled(config_i2c_slave) int (*reg_slave)(struct i2c_client *client); int (*unreg_slave)(struct i2c_client *client);#endif};mtk 只实现了其中两个
i2c_client:描述设备信息
struct i2c_client { unsigned short flags;/* i2c 传输标志位如下*/#define i2c_client_pec 0x04 /* use packet error checking */#define i2c_client_ten 0x10 /* we have a ten bit chip address *//* must equal i2c_m_ten below */#define i2c_client_slave 0x20 /* we are the slave */#define i2c_client_host_notify 0x40 /* we want to use i2c host notify */#define i2c_client_wake 0x80 /* for board_info; true iff can wake */#define i2c_client_sccb 0x9000 /* use omnivision sccb protocol */ /* must match i2c_m_stop|ignore_nak */ unsigned short addr; /* chip address - note: 7bit */ /* addresses are stored in the */ /* _lower_ 7 bits */ char name[i2c_name_size]; struct i2c_adapter *adapter;/* 所处的那一路 i2c bus */ struct device dev; /* the device structure */ int init_irq; /* irq set at initialization */ int irq; /* irq issued by device */ struct list_head detected;#if is_enabled(config_i2c_slave) i2c_slave_cb_t slave_cb; /* callback for slave mode */#endif void *devres_group_id; /* id of probe devres group */};i2c_driver:普通驱动工程师写驱动时,必须实现其中的 probe 函数和 remove 函数,其余的函数一般用不到。
struct i2c_driver { unsigned int class; /* standard driver model interfaces */ int (*probe)(struct i2c_client *client, const struct i2c_device_id *id); int (*remove)(struct i2c_client *client); int (*probe_new)(struct i2c_client *client); void (*shutdown)(struct i2c_client *client); void (*alert)(struct i2c_client *client, enum i2c_alert_protocol protocol,unsigned int data); int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); struct device_driver driver; const struct i2c_device_id *id_table; int (*detect)(struct i2c_client *client, struct i2c_board_info *info); const unsigned short *address_list; struct list_head clients;};mtk_i2c:mtk 平台用该结构体表示 i2c 控制器,定义在/kernel-5.10/drivers/i2c/busses/i2c-mt65xx.c
struct mtk_i2c { struct i2c_adapter adap; /* i2c host adapter */ struct device *dev; struct completion msg_complete; /* set in i2c probe */ void __iomem *base; /* i2c base addr */ void __iomem *pdmabase; /* dma base address*/ struct clk *clk_main; /* main clock for i2c bus */ struct clk *clk_dma; /* dma clock for i2c via dma */ struct clk *clk_pmic; /* pmic clock for i2c from pmic */ bool have_pmic; /* can use i2c pins from pmic */ bool use_push_pull; /* io config push-pull mode */ u16 irq_stat; /* interrupt status */ unsigned int clk_src_div; unsigned int speed_hz; /* the speed in transfer */ enum mtk_trans_op op; u16 timing_reg; u16 high_speed_reg; unsigned char auto_restart; bool ignore_restart_irq; const struct mtk_i2c_compatible *dev_comp;};i2c_msg:i2c 读写时,必须填充 i2c_msg。
标志位:写为 0 ,读为 i2c_m_rd,其他的 flag 大家可以参考。
i2c 单笔传输最大 64kb,len 的长度博主在注释中有说明。

为什么说小米8发布后,整个手机圈基本上就“圆满”了
探讨目前主流3D激光SLAM算法方案
PLC拓展模块的具体用处有哪些
OPPO Reno3 Pro 5G的重量公布,下放到170-179g之间
微星宙斯盾钛5主机正式发布:可配RTX 3090等显卡
I2C子系统几个主要的结构体
台积电5纳米即将在明年第一季正式量产 并预计新增预算中将有25亿美元用在5纳米制程
STM32基础知识:串口通信-DMA方式
可提高效率的升压稳压器的介绍
苹果VS华为 究竟谁才是中国未来的智能手机之王?
比特币25天跌近37% 盘中跌破13000美元
物联网转售产业迎来实质性突破
小米移动有望成为中国民营电信运营商的代表品牌
人工智能驱动数字化转型升级
wms仓库管理对企业的重要性
SPI总线的工作方式是怎样的
浅析天线与波长的关系
混合电动车MH-Ni电源系统的应用
FORESEE MCP系列重构智能移动终端存储组合
三星S8+屏幕增至6.2寸 屏占比轻松秒iPhone 7P