内核中对swI2c 有两个参考,一个是在driver/i2c/bus/i2c-gpio.c 中,要使用这的话,可以像正常使用i2c一样,客户不清楚下面是真的i2c还是用gpio 模拟的,这个直接链接到i2c的框架中国。但是这个需要bios来适配,另外一个实现在drivers/staging/sm750fb/ddk750_swi2c.c 中,这个文件中直接写死gpio,不需要bios 来配置。和i2c的适配层没有关系,i2c的读和写都是自己实现
这里以scl的波形如何控制
static void sw_i2c_scl(unsigned char value)
{
unsigned long gpio_data;
unsigned long gpio_dir;
gpio_dir = peek32(sw_i2c_clk_gpio_data_dir_reg);
if (value) { /* High */
/*
* Set direction as input. This will automatically
* pull the signal up.
*/
gpio_dir &= ~(1 << sw_i2c_clk_gpio);
poke32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir);
} else { /* Low */
/* Set the signal down */
gpio_data = peek32(sw_i2c_clk_gpio_data_reg);
gpio_data &= ~(1 << sw_i2c_clk_gpio);
poke32(sw_i2c_clk_gpio_data_reg, gpio_data);
/* Set direction as output */
gpio_dir |= (1 << sw_i2c_clk_gpio);
poke32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir);
}
}
可以看到这里直接通过peek32 和 poke32 来直接写gpio相关的寄存器的。
/* software control endianness */
static inline u32 peek32(u32 addr)
{
return readl(addr + mmio750);
}
static inline void poke32(u32 addr, u32 data)
{
writel(data, addr + mmio750);
}