GT5688无法正常通信

移植汇顶的TP GT9271时,发现i2c通信不上,检查了TP的供电和复位脚及硬件连接,都没发现问题,然后发现内核有如下的报错信息。

[49533.829164] gpio-272 (goodix_ts_int): _gpiod_direction_output_raw: tried to set a GPIO tied to an IRQ as output
[49533.849418] goodix-ts 3-005d: I2c read failed,dev:5d,reg:8047,size:1
[49533.849433] goodix-ts 3-005d: GTP i2c test failed time 1
[49533.871495] goodix-ts 3-005d: I2c read failed,dev:5d,reg:8047,size:1
[49533.871510] goodix-ts 3-005d: GTP i2c test failed time 2
[49533.895621] goodix-ts 3-005d: I2c read failed,dev:5d,reg:8047,size:1
[49533.895634] goodix-ts 3-005d: GTP i2c test failed time
但为什么设置io口为输出也报错呢 ,查看相应的代码

drivers/gpio/gpiolib.c

static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value)
{
struct gpio_chip *gc = desc->gdev->chip;
int val = !!value;
int ret;

/* GPIOs used for IRQs shall not be set as output */
if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) {
	gpiod_err(desc,
		  "%s: tried to set a GPIO tied to an IRQ as output\n",
		  __func__);
	return -EIO;
}

if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) {
	/* First see if we can enable open drain in hardware */
	ret = gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
					  PIN_CONFIG_DRIVE_OPEN_DRAIN);
	if (!ret)
		goto set_output_value;
	/* Emulate open drain by not actively driving the line high */
	if (val)
		return gpiod_direction_input(desc);
}
else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
	ret = gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
					  PIN_CONFIG_DRIVE_OPEN_SOURCE);
	if (!ret)
		goto set_output_value;
	/* Emulate open source by not actively driving the line low */
	if (!val)
		return gpiod_direction_input(desc);
} else {
	gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
				    PIN_CONFIG_DRIVE_PUSH_PULL);
}

set_output_value:
if (!gc->set || !gc->direction_output) {
gpiod_warn(desc,
“%s: missing set() or direction_output() operations\n”,
func);
return -EIO;
}

ret = gc->direction_output(gc, gpio_chip_hwgpio(desc), val);
if (!ret)
	set_bit(FLAG_IS_OUT, &desc->flags);
trace_gpio_value(desc_to_gpio(desc), 0, val);
trace_gpio_direction(desc_to_gpio(desc), 0, ret);
return ret;

}
原来,内核默认禁止中断设置成输出,这也合理,一般设置成中断模式的引脚,只需设置成输入模式,然后读取引脚的状态即可。

但为什么代码里将中断脚设置成输出呢。

查看规格书https://github.com/hadess/gt9xx
GT5688无法正常通信_第1张图片

居然用中断脚来进行通信了 ,跟普通的中断脚不一样了。

但为什么高通/MTK他们用这份驱动没有问题了,原来他们用pinctrl的方式控制引脚状态,但展讯平台还没支持pinctrl这种方式,用的是普通的gpio模式,所以有这样的问题。那要怎么修改呢。

一种方式是先释放中断,拉低或拉高gpio后,重新设置成中断模式。

第二种方式是屏蔽_gpiod_direction_output_raw的返回,让代码跑下去。

你可能感兴趣的:(GT5688无法正常通信)