學習資料:https://blog.csdn.net/yangguoyu8023/article/details/122362946
原始碼:
drivers\i2c\busses\i2c-designware-platdrv.c drivers\i2c\busses\i2c-designware-master.c drivers\i2c\busses\i2c-designware-slave.c
DTS:
i2c2: i2c@f0d80000 { compatible = "snps,designware-i2c"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; reg = <0x0 0xf0d80000 0x0 0x1000>; clock-frequency = <400000>; #address-cells = <1>; #size-cells = <0>; };
I2C control例項化分析:
static const struct of_device_id dw_i2c_of_match[] = { { .compatible = "snps,designware-i2c", }, {}, };
最終dw_i2c_plat_probe(drivers\i2c\busses\i2c-designware-platdrv.c)函式會呼叫
static int dw_i2c_plat_probe(struct platform_device *pdev) { ... ... i2c_dw_configure(dev); // 區分master和slave ... ... ret = i2c_dw_probe(dev); ... ... } static inline void i2c_dw_configure(struct dw_i2c_dev *dev) { if (i2c_detect_slave_mode(dev->dev)) i2c_dw_configure_slave(dev); else i2c_dw_configure_master(dev); } static inline int i2c_dw_probe(struct dw_i2c_dev *dev) { switch (dev->mode) { case DW_IC_SLAVE: return i2c_dw_probe_slave(dev); case DW_IC_MASTER: return i2c_dw_probe_master(dev); default: dev_err(dev->dev, "Wrong operation mode: %d\n", dev->mode); return -EINVAL; } }
根據該i2c控制器是主機還是從機,進行控制器配置並且呼叫響應的probe函式,這裡分析主機模式,呼叫i2c_dw_probe_master函式
static const struct i2c_algorithm i2c_dw_algo = { .master_xfer = i2c_dw_xfer, .functionality = i2c_dw_func, }; int i2c_dw_probe_master(struct dw_i2c_dev *dev) { struct i2c_adapter *adap = &dev->adapter; unsigned long irq_flags; int ret; ....... ret = dev->init(dev); if (ret) return ret; snprintf(adap->name, sizeof(adap->name), "Synopsys DesignWare I2C adapter"); adap->retries = 3; adap->algo = &i2c_dw_algo; adap->dev.parent = dev->dev; i2c_set_adapdata(adap, dev); if (dev->pm_disabled) { dev_pm_syscore_device(dev->dev, true); irq_flags = IRQF_NO_SUSPEND; } else { irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; } ..... i2c_dw_disable_int(dev); ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags, dev_name(dev->dev), dev); ...... ret = i2c_add_numbered_adapter(adap); }
解析dts,設定struct i2c_adapter結構體,主要是adap->algo = &i2c_dw_algo,註冊中斷,最終呼叫i2c_add_numbered_adapter註冊adapter