Linux下的模擬i2c

內核默認支持模擬i2c,那應該怎麼用呢,參考https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/i2c/i2c-gpio.txt?h=v4.14-rc6   是不是跟平常用的硬件i2c dts配置很類似呢

i2c@0 {
	compatible = "i2c-gpio";
	gpios = <&pioA 23 0 /* sda */
		 &pioA 24 0 /* scl */
		>;
	i2c-gpio,sda-open-drain;
	i2c-gpio,scl-open-drain;
	i2c-gpio,delay-us = <2>;	/* ~100 kHz */
	#address-cells = <1>;
	#size-cells = <0>;

	rv3029c2@56 {
		compatible = "rv3029c2";
		reg = <0x56>;
	};
};

同時加上CONFIG_I2C_GPIO CONFIG_I2C_ALGOBIT

drivers/i2c/busses/i2c-gpio.c 註冊i2c總線

drivers/i2c/algos/i2c-algo-bit.c  實現模擬i2c協議

const struct i2c_algorithm i2c_bit_algo = {
	.master_xfer	= bit_xfer,
	.functionality	= bit_func,
};

static int __i2c_bit_add_bus(struct i2c_adapter *adap,int (*add_adapter)(struct i2c_adapter *))
{
	adap->algo = &i2c_bit_algo;
	ret = add_adapter(adap);
}

int i2c_bit_add_numbered_bus(struct i2c_adapter *adap)
{
	return __i2c_bit_add_bus(adap, i2c_add_numbered_adapter);
}
EXPORT_SYMBOL(i2c_bit_add_numbered_bus);

 我使用平臺的有點差異,要獲取sda的電平,先要設置成輸入狀態,按如下修改

 static int i2c_gpio_getsda(void *data)
 {
        struct i2c_gpio_platform_data *pdata = data;
-
-       return gpio_get_value(pdata->sda_pin);
+       int state;
+       gpio_direction_input(pdata->sda_pin);
+       state=gpio_get_value(pdata->sda_pin);
+       gpio_direction_output(pdata->sda_pin,1);
+       return state;
 }

是不是瞬間就搞定了呢,i2c驅動用硬件的i2c驅動就行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章