Linux下的模拟i2c

       内核默认支持模拟i2c,那应该怎么用呢,参考i2c-gpio.txt « i2c « bindings « devicetree « Documentation - kernel/git/torvalds/linux.git - Linux kernel source tree   是不是跟平常用的硬件i2c dts配置很类似呢

aliases {
	i2c8 = &i2c8;
}

i2c8:i2c8 {
	compatible = "i2c-gpio";
	gpios = <&pio 23 0 /* sda */
		     &pio 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>;
	};
};

       如果平台也有i2c8,需要将平台对应的i2c屏蔽掉,同时引脚配置成普通gpio模式,主要引脚还是要上拉哦。

       i2c8的应该根据实际的主板情况配置而来,因为系统可能默认有了i2c0,i2c1等,如果这里不指定第几条总线,系统原本的硬件i2c注册会有问题。 

同时加上

CONFIG_I2C_GPIO=y
CONFIG_I2C_ALGOBIT=y

i2c8 = &i2c8这个有什么作用呢,看pdeev->id默认是-1,然后获取i2c属性或者具体的总线。

#define PLATFORM_DEVID_NONE     (-1)
int of_device_add(struct platform_device *ofdev)
{
...
	ofdev->id = PLATFORM_DEVID_NONE;
...
}
static int i2c_gpio_probe(struct platform_device *pdev)
{
...
	adap->nr = pdev->id;
	ret = i2c_bit_add_numbered_bus(adap);
...
}

int i2c_add_numbered_adapter(struct i2c_adapter *adap)
{
...
	if (adap->nr == -1) /* -1 means dynamically assign bus id */
		return i2c_add_adapter(adap);
...
}

int i2c_add_adapter(struct i2c_adapter *adapter)
{
	struct device *dev = &adapter->dev;
	int id;

	if (dev->of_node) {
		id = of_alias_get_id(dev->of_node, "i2c");
		if (id >= 0) {
			adapter->nr = id;
			return __i2c_add_numbered_adapter(adapter);
		}
	}
...
}

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);

使用平台的有点差异(sprd/mtk),要获取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驱动就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值