Issue
I'm using an old Linux kernel v3.10 and attempting to get i2c working. Concretely, I am using it to get a Goodix GT911 touch driver IC up and running (I had to backport the Linux driver because it wasn't available back in version 3.10). It seems to work fine for a few messages. However, after a few successful i2c messages an unexpected glitch/short pulse appears on the CLK line and corrupts the whole message. This happens quite often so a simple resend is not an adequate solution. Sometimes I can get 10 messages across, sometimes only 1. On very rare occasions even more then 10.
I am copying below the glitch as captured using a logic analyzer and an oscilloscope. Further below I am also pasting the used device tree file.
If anyone has any advice to offer on what to try, where to check, what to do to fix this, I would greatly appreciate it.
Thank you.
p.s.: upgrading the kernel is of course an option and then hoping that fixes it. However, I would like to leave that as the last resort.
Used device tree source file: (i2c0 is used and gt911 node is the one calling the matching driver)
/*
* acme-acqua_lcd_43.dts
* Device Tree for Acqua A5 SoM with 4.3 inch lcd
* with resistive touch
*
* Copyright (C) 2014 Acme Systems,
* 2014 Sergio Tanzilli <[email protected]>
*
* Licensed under GPLv2 or later.
*/
/dts-v1/;
#include "sama5d3.dtsi"
/ {
model = "Acqua A5 SoM";
compatible = "acme,acqua", "pda,tm43xx", "atmel,sama5d3", "atmel,sama5";
chosen {
bootargs = "console=ttyS0,115200";
};
memory {
reg = <0x20000000 0x10000000>;
};
kd043w {
compatible = "kd043w-gpio";
#address-cells = <0x1>;
ranges;
rst = <&pioD 25 0>;
cs = <&pioD 29 0>;
sdi = <&pioD 27 0>;
scl = <&pioD 23 0>;
};
wiegand {
compatible = "gpio-wiegand";
#address-cells = <0x1>;
ranges;
data-0 = <&pioB 24 0>;
data-1 = <&pioB 19 0>;
};
clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;
main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
mcp251x_clock: mcp2515 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <16000000>;
};
};
ahb {
apb {
watchdog@fffffe40 {
compatible = "atmel,at91sam9260-wdt";
reg = <0xfffffe40 0x10>;
interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
atmel,watchdog-type = "hardware";
atmel,reset-type = "all";
atmel,dbg-halt;
atmel,idle-halt;
status = "okay";
};
lcd_bus@f0030000 {
status = "okay";
lcd@f0030000 {
status = "okay";
};
lcdovl1@f0030140 {
status = "okay";
};
lcdovl2@f0030240 {
status = "okay";
};
lcdheo1@f0030340 {
status = "okay";
};
};
mmc0: mmc@f0000000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>;
status = "okay";
slot@0 {
reg = <0>;
bus-width = <4>;
};
};
mmc1: mmc@f8000000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
status = "disabled";
slot@0 {
reg = <0>;
bus-width = <4>;
};
};
mmc2: mmc@f8004000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>;
status = "disabled";
slot@0 {
reg = <0>;
bus-width = <4>;
};
};
spi0: spi@f0004000 {
cs-gpios = <&pioD 14 0>, <&pioD 13 0>, <0>, <0>;
status = "okay";
device@0 {
compatible = "spidev";
spi-max-frequency = <50000000>; // 50 MHz
reg = <0>;
};
can2: can@1 {
compatible = "microchip,mcp2515";
spi-max-frequency = <50000000>;
reg = <1>;
clocks = <&mcp251x_clock>;
interrupt-parent = <&pioB>;
interrupts = <2 0x2>;
};
};
spi1: spi@f8008000 {
cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>;
status = "disabled";
device@0 {
compatible = "spidev";
spi-max-frequency = <50000000>; // 50 MHz
reg = <0>;
};
};
i2c0: i2c@f0014000 {
status = "okay";
clock-frequency = <200000>;
gt911@14 {
compatible = "goodix,gt911";
reg = <0x14>;
interrupt-parent = <&pioA>;
interrupts = <21 IRQ_TYPE_EDGE_RISING>;
reset-gpios = <&pioA 20 0>;
irq-gpios = <&pioA 21 0>;
mydbg-gpios = <&pioD 31 0>;
};
/*
rtc@68 {
compatible = "fm,i2c_rtc_driver";
reg = <0x68>;
};
*/
};
i2c1: i2c@f0018000 {
status = "disabled";
};
i2c2: i2c@f801c000 {
dmas = <0>, <0>; /* Do not use DMA for i2c2 */
status = "disabled";
};
/* Bit banging I2C wired on the Atmel MAC chip */
i2c3@ {
compatible = "i2c-gpio";
gpios = <&pioE 1 0 /* SDA */
&pioE 2 0 /* SCK */
>;
/*i2c-gpio,sda-open-drain;*/
/*i2c-gpio,scl-open-drain;*/
i2c-gpio,delay-us = <4>; /* ~178 kHz */
#address-cells = <1>;
#size-cells = <0>;
/*rv3029c2@56 {
compatible = "rv3029c2";
reg = <0x56>;
};*/
};
/* Giga Ethernet */
macb0: ethernet@f0028000 {
phy-mode = "rgmii";
status = "disabled";
};
/* 10/100 Ethernet */
macb1: ethernet@f802c000 {
phy-mode = "rmii";
status = "okay";
local-mac-address = [MACHERE];
};
pwm0: pwm@f002c000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm0_pwml0 &pinctrl_pwm0_pwmh1>;
status = "okay";
};
usart0: serial@f001c000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts_cts>;
linux,rs485-enabled-at-boot-time;
rs485-rts-delay = <0 0>;
status = "okay";
};
usart1: serial@f0020000 {
status = "okay";
};
usart2: serial@f8020000 {
status = "okay";
};
usart3: serial@f8024000 {
status = "okay";
};
uart0: serial@f0024000 {
status = "okay";
};
can0: can@f000c000 {
status = "disabled";
};
can1: can@f8010000 {
status = "disabled";
};
adc0: adc@f8018000 {
atmel,adc-clock-rate = <1000000>;
atmel,adc-ts-wires = <4>;
atmel,adc-ts-pressure-threshold = <10000>;
status = "disabled";
};
/*
adc0: adc@f8018000 {
pinctrl-names = "default";
pinctrl-0 = <
&pinctrl_adc0_adtrg
&pinctrl_adc0_ad0
&pinctrl_adc0_ad1
&pinctrl_adc0_ad2
&pinctrl_adc0_ad3
&pinctrl_adc0_ad4
&pinctrl_adc0_ad5
&pinctrl_adc0_ad6
&pinctrl_adc0_ad7
&pinctrl_adc0_ad8
&pinctrl_adc0_ad9
>;
status = "disabled";
};
*/
pinctrl@fffff200 {
board {
pinctrl_mmc0_cd: mmc0_cd {
atmel,pins =
<AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
};
pinctrl_mmc1_cd: mmc1_cd {
atmel,pins =
<AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
};
pinctrl_pwm0_pwml0: pwm0_pwml0 {
atmel,pins =
<AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
};
pinctrl_pwm0_pwmh1: pwm0_pwmh1 {
atmel,pins =
<AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE>;
};
pinctrl_usba_vbus: usba_vbus {
atmel,pins =
<AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */
};
};
};
dbgu: serial@ffffee00 {
status = "okay";
};
};
nand0: nand@60000000 {
nand-bus-width = <8>;
nand-ecc-mode = "hw";
atmel,has-pmecc;
atmel,pmecc-cap = <4>;
atmel,pmecc-sector-size = <512>;
nand-on-flash-bbt;
status = "okay";
at91bootstrap@0 {
label = "at91bootstrap";
reg = <0x0 0x40000>;
};
bootloader@40000 {
label = "bootloader";
reg = <0x40000 0x80000>;
};
bootloaderenv@c0000 {
label = "bootloader env";
reg = <0xc0000 0xc0000>;
};
dtb@180000 {
label = "device tree";
reg = <0x180000 0x80000>;
};
kernel@200000 {
label = "kernel";
reg = <0x200000 0x600000>;
};
rootfs@800000 {
label = "rootfs";
reg = <0x800000 0x0f800000>;
};
};
usb0: gadget@00500000 {
atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usba_vbus>;
status = "disabled";
};
usb1: ohci@00600000 {
num-ports = <3>;
status = "okay";
};
usb2: ehci@00700000 {
status = "okay";
};
};
gpio_keys {
compatible = "gpio-keys";
/* bp3 {
label = "PB_USER";
gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
linux,code = <0x104>;
gpio-key,wakeup;
}; */
};
leds {
compatible = "gpio-leds";
led-blue {
label = "led-blue";
gpios = <&pioE 3 GPIO_ACTIVE_LOW>;
linux,default-trigger = "heartbeat";
};
led-green {
label = "led-green";
gpios = <&pioE 4 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
led-white {
label = "led-white";
gpios = <&pioE 5 GPIO_ACTIVE_LOW>;
linux,default-trigger = "heartbeat";
};
led-red {
label = "led-red";
gpios = <&pioE 6 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
};
sound {
status = "disabled";
};
};
Above referenced sama5d3.dtsi can be found in the Linux kernel repo: https://github.com/torvalds/linux/blob/v3.10/arch/arm/boot/dts/sama5d3.dtsi
Solution
It turns out the issue was in the value of pull-up resistors on I2C data and clk lines. So far, my circuit used 10 kOhm pull-ups. Two other I2C devicecs on the line (one of them also a CTP driver, just like the GT911) worked without issues with these values. However, the GT911 is not happy with these values. despite the low communication speeds. Using 4.7 kOhm or 2.2 kOhm fixed the problem and there is now no more glitches.
Answered By - EEALNT Answer Checked By - Marilyn (WPSolving Volunteer)