最近刚开了这个博客,人家说要做好开源就一定要经常记笔记,写博客,将资料拿出来大家分享,最近正好在学习linux驱动,把这个拿出来写写,望大家指点。
关于i2c_davinci.c文件:位于drivers/i2c/busses/目录下
开头一大堆的define,看这部分:
#define DAVINCI_I2C_OAR_REG 0x00
#define DAVINCI_I2C_IMR_REG 0x04
#define DAVINCI_I2C_STR_REG 0x08
#define DAVINCI_I2C_CLKL_REG 0x0c
#define DAVINCI_I2C_CLKH_REG 0x10
#define DAVINCI_I2C_CNT_REG 0x14
#define DAVINCI_I2C_DRR_REG 0x18
#define DAVINCI_I2C_SAR_REG 0x1c
#define DAVINCI_I2C_DXR_REG 0x20
#define DAVINCI_I2C_MDR_REG 0x24
#define DAVINCI_I2C_IVR_REG 0x28
#define DAVINCI_I2C_EMDR_REG 0x2c
#define DAVINCI_I2C_PSC_REG 0x30
这里包含REG后缀,是定义了关于DM365中I2C相关寄存器的偏移地址,参考DM365的datasheet能够找到匹配。
#define DAVINCI_I2C_IVR_AAS 0x07
#define DAVINCI_I2C_IVR_SCD 0x06
#define DAVINCI_I2C_IVR_XRDY 0x05
#define DAVINCI_I2C_IVR_RDR 0x04
#define DAVINCI_I2C_IVR_ARDY 0x03
#define DAVINCI_I2C_IVR_NACK 0x02
#define DAVINCI_I2C_IVR_AL 0x01
#define DAVINCI_I2C_STR_BB BIT(12)
#define DAVINCI_I2C_STR_RSFULL BIT(11)
#define DAVINCI_I2C_STR_SCD BIT(5)
#define DAVINCI_I2C_STR_ARDY BIT(2)
#define DAVINCI_I2C_STR_NACK BIT(1)
#define DAVINCI_I2C_STR_AL BIT(0)
#define DAVINCI_I2C_MDR_NACK BIT(15)
#define DAVINCI_I2C_MDR_STT BIT(13)
#define DAVINCI_I2C_MDR_STP BIT(11)
#define DAVINCI_I2C_MDR_MST BIT(10)
#define DAVINCI_I2C_MDR_TRX BIT(9)
#define DAVINCI_I2C_MDR_XA BIT(8)
#define DAVINCI_I2C_MDR_RM BIT(7)
#define DAVINCI_I2C_MDR_IRS BIT(5)
#define DAVINCI_I2C_IMR_AAS BIT(6)
#define DAVINCI_I2C_IMR_SCD BIT(5)
#define DAVINCI_I2C_IMR_XRDY BIT(4)
#define DAVINCI_I2C_IMR_RRDY BIT(3)
#define DAVINCI_I2C_IMR_ARDY BIT(2)
#define DAVINCI_I2C_IMR_NACK BIT(1)
#define DAVINCI_I2C_IMR_AL BIT(0)
这段是几个寄存器的位掩码,分别是IVR、STR、MDR、IMR寄存器。
static inline void davinci_i2c_write_reg(struct davinci_i2c_dev *i2c_dev,
int reg, u16 val)
{
__raw_writew(val, i2c_dev->base + reg);
}
这个函数:是写寄存器,将val值写到reg中。获取基址加offset,即得到寄存器的地址。类似的davinci_i2c_read_reg是读取寄存器的值。
static void generic_i2c_clock_pulse(unsigned int scl_pin)函数是设置I2C引脚SCL,使其产生脉冲。但是函数中for循环是10次,也就是只产生10次脉冲。
static void i2c_recover_bus(struct davinci_i2c_dev *dev)
这个函数是“bus clear”,函数中完成三部分,第一步是发送NACK信号,第二是写模式寄存器,然后发送停止位信号。这个注释中写是bus recovery是特定于I2C协议的。
davinci_i2c_reset_ctrl函数是完成对I2C总线的复位控制。
i2c_davinci_calc_clk_dividers函数是计算时钟,预分频神马的,具体为什么这么计算,有点搞不清楚。
i2c_davinci_init函数是初始化I2C,开中断,获取分频数,时钟数等等。
i2c_davinci_wait_bus_not_busy函数:读取状态寄存器STR的内容和其位BB(Bus Busy)的内容,等待超过最大重试次数(这里是2),就返回错误,否则就调用i2c_recover_bus和i2c_davinci_init函数来初始化I2C总线。
i2c_davinci_xfer_msg函数:传递msg。
terminate_read终止读。terminate_write终止写
//目前读来,所有这些函数大部分都是调用了davinci_i2c_read_reg和davinci_i2c_write_reg这两个函数来操作DM365的I2C的寄存器。之前不明白在何处操作寄存器的问题终于有点明白了!但是还是有点不太明白的是我们怎么操作这些寄存器呢?真是看的太痛苦了!
i2c_davinci_isr中断服务,I2C中断时会调用这个函数。
i2c_davinci_cpufreq_transition这个函数不是很明白。