I2C has no response and SDA line is always low. Here are the problematic board information
Hi Stalin,
Regarding the issue mentioned by SooChait previously, could you please share with us what is the rootcause of the issue and what is the trigger point for it? We would like to understand how we can prevent the issue happen and the impact of this issue to the field radios instead of passively recover the IC when issue happen.
Thank you.
Best Regards,
Loh Lim Ling (Joyce)
---------- Forwarded message ----------
In the earlier mail, they suggest to fix the issue rather than continue to rootcause.
In this reply, they propose to go with the gpio bitbang method, rather than making use of the i2c module driver.
" I hope this would solve problem as it helped most of the customers. "
Again, the above sentence highlight that we're not the first one to face the issue when using that IC.
---------- Forwarded message ----------
From: Stalin, Titusrathinaraj <
Thanks for your answers.
The following is the suggested solution. Hope it should get resolved in this attempt.
Please enable the GPIO based bitbang I2C driver and see whether it could solve the problem.
I hope this would solve problem as it helped most of the customers.
You can enable the GPIO based bitbang I2C via "make menuconfig"
> cd linux-source
> make menuconfig -> Device Drivers -> I2C Support -> I2C Hardware Bus support -> GPIO based bitbanging I2C
Below are the changes required in the board file for registering the GPIO based bitbanging I2C driver.
In "arch/arm/mach-davinci/board-da850-evm.c"
#include <linux/i2c-gpio.h>
static struct i2c_gpio_platform_data da850_gpio_i2c_pdata = {
.sda_pin = GPIO_TO_PIN(1, 4),
.scl_pin = GPIO_TO_PIN(1, 5),
.udelay = 2, /* 250 KHz */
};
const short da850_i2c0_gpiobitbang[] __initdata = {
DA850_GPIO1_4, DA850_GPIO1_5,
-1
};
static struct platform_device da850_gpio_i2c = {
.name = "i2c-gpio",
.id = 1,
.dev = {
.platform_data = &da850_gpio_i2c_pdata,
},
};
/* ret = da8xx_pinmux_setup(da850_i2c0_pins); */
ret = da8xx_pinmux_setup(da850_i2c0_gpiobitbang); /* Titus : You should use this "da850_i2c0_gpiobitbang" */
if (ret)
pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
ret);
platform_device_register(&da850_gpio_i2c);
Note:
1. The above board file changes can be seen in the below davinci link
http://arago-project.org/git/projects/linux-davinci.git?p=projects/linux-davinci.git;a=blob;f=arch/arm/mach-davinci/board-da850-evm.c;h=b400edcd626d4c8fea49c8ee782853c9c7b69002;hb=DAVINCIPSP_03.21.00.01
2. To confirm the PINMUX settings of GPIO are appropriate, please use devmem2 to display the values of PINMUX5 register like below.
> devmem2 0x01C14130
Regards,
Titus S.
Hi Stalin,
We're accessing the I2C interface via direct I2C lines.
So far we manage to see the issue on a few devices,
a) SSD1309 OLED Display Driver
b) Accelerometer Chip (Especially when we're running on 400kHz)
To isolate the i2c slave devices, we did not remove the other i2c slave devices on the hardware board. Instead, we make sure not to register the i2c slave device and not to initiate any communication with it. In other word, there is no ioctl with the command I2C_SLAVE or I2C_SLAVE_FORCE, at the same time there is no i2c transfer directed at their slave address.
I shall try to perform the test on a board with a single slave device at a later time when I'm free.
We modify the i2c speed via .bus_freq.
The I2C initialization part done in board-da850-evm.c is as followed.
static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = {
.bus_freq = 400, /* kHz */
.bus_delay = 0, /* usec */
};
static void __init da850_evm_init_i2c(void)
{
da8xx_register_i2c(0, &da850_evm_i2c_0_pdata);
}
ret = da8xx_pinmux_setup(da850_i2c0_pins);
if (ret)
pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
ret);
da850_evm_init_i2c();
const short da850_i2c0_pins[] __initdata = {
DA850_I2C0_SDA, DA850_I2C0_SCL,
-1
};
int __init da8xx_register_i2c(int instance,
struct davinci_i2c_platform_data *pdata)
{
struct platform_device *pdev;
if (instance == 0)
pdev = &da8xx_i2c_device0;
else if (instance == 1)
pdev = &da8xx_i2c_device1;
else
return -EINVAL;
pdev->dev.platform_data = pdata;
return platform_device_register(pdev);
}