内核对swi2c的实现

内核中对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);
}

 

你可能感兴趣的:(Linux,源码分析)