I2C Data Structure
我們要搞懂一個(gè) Linux 子系統(tǒng),必須研究它的數(shù)據(jù)結(jié)構(gòu),搞懂每個(gè)結(jié)構(gòu)體存儲(chǔ)了什么東西,才能梳理清楚該子系統(tǒng)的架構(gòu)。
I2C 子系統(tǒng)有幾個(gè)主要的結(jié)構(gòu)體:
I2C 控制器:i2c_adapter、i2c_algorithm、mtk_i2c
I2C 設(shè)備驅(qū)動(dòng):i2c_client、i2c_driver
I2C 傳輸:i2c_msg
i2c_adapter:i2c-core 層描述一個(gè) I2C 控制器,假如一個(gè)芯片有 8 路 I2C bus,則有 8 個(gè) i2c_adapter。請(qǐng)?jiān)敿?xì)看博主對(duì) code 的注釋說明。
struct i2c_adapter {
struct module *owner;
unsigned int class; /* 該 I2C bus 支持哪些類型的從設(shè)備 */
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;/* 超過該時(shí)間無法重發(fā) */
int retries;/* I2C發(fā)送失敗重試次數(shù) */
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 傳輸函數(shù)合集,其中 master_xfer 是真正的傳輸函數(shù) ,芯片原廠寫 I2C 控制器驅(qū)動(dòng)時(shí)必須實(shí)現(xiàn)。functionality 函數(shù)會(huì)返回該 I2C 控制器支持什么通信協(xié)議,也需要實(shí)現(xiàn),其他的函數(shù)即便 Linux 規(guī)定了,芯片原廠也可以不實(shí)現(xiàn),因?yàn)椴怀S谩?/p>
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 只實(shí)現(xiàn)了其中兩個(gè)
i2c_client:描述設(shè)備信息
struct i2c_client {
unsigned short flags;/* I2C 傳輸標(biāo)志位如下*/
#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:普通驅(qū)動(dòng)工程師寫驅(qū)動(dòng)時(shí),必須實(shí)現(xiàn)其中的 probe 函數(shù)和 remove 函數(shù),其余的函數(shù)一般用不到。
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 平臺(tái)用該結(jié)構(gòu)體表示 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 讀寫時(shí),必須填充 i2c_msg。
標(biāo)志位:寫為 0 ,讀為 I2C_M_RD,其他的 flag 大家可以參考。
I2C 單筆傳輸最大 64KB,len 的長(zhǎng)度博主在注釋中有說明。
-
I2C
+關(guān)注
關(guān)注
28文章
1487瀏覽量
123787 -
結(jié)構(gòu)體
+關(guān)注
關(guān)注
1文章
130瀏覽量
10844 -
系統(tǒng)
+關(guān)注
關(guān)注
1文章
1017瀏覽量
21347
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論