Add I2C with PCA9665
Hi,
I am using the PCA9665 controller in my custom board because the internal I2C controller of my processor (AT91RM9200) is not robust. The following are my configs:
Hardware:
D0 - D7 --> D0 - D7
Write strobe --> NWR0/NWE/CFWE
Read strobe --> NRD/NOE/CFOE
Chip Enable --> NCS2
A0 --> A0/NBS0
A1 --> A1
Interrupt request --> PB29/IRQ0
Reset --> PB27
Software:
static struct resource i2c_resources[] = {
[0] = {
.start = AT91_CHIPSELECT_2, /* 0x30000000 */
.end = AT91_CHIPSELECT_2 + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91RM9200_ID_IRQ0,
.end = AT91RM9200_ID_IRQ0,
.flags = IORESOURCE_IRQ,
},
};static struct i2c_pca9564_pf_platform_data pca9665_platform_data = {
.gpio = AT91_PIN_PB27,
.i2c_clock_speed= 0,
.timeout = HZ, /* timeout in jiffies */
};static struct platform_device pca9665_twi_device = {
.name = "i2c-pca-platform",
.id = -1,
.dev = {
.platform_data = &pca9665_platform_data,
},
.num_resources = ARRAY_SIZE(i2c_resources),
.resource = i2c_resources,
};void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
at91_set_A_periph(AT91_PIN_PB29, 1); /* IRQ0 interrupt pin */
i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&pca9665_twi_device);
}But the board detects the wrong external I2C controller (PCA9564):
# dmesg | grep PCA PCA9564/PCA9665 at 0x30000000: PCA9564 detected. PCA9564/PCA9665 at 0x30000000: Choosing the clock frequency based on index is deprecated. Use the nominal frequency. PCA9564/PCA9665 at 0x30000000: Clock frequency is 330kHz PCA9564/PCA9665 at 0x30000000 registered.
And, the i2c controller is not functional at all. The i2cdetect command of i2c-tools package from lm-sensors, does not detect any devices on my i2c bus, while there must be two i2c devices (a RTC and a temperature sensor) on my board. There is no i2c clock or data signal either on the bus using the oscilloscope probe.
How can I fix this so the board detects the functional and correct controller (PCA9665)?
Best regards,
Elyas Razzaghi
Quoted 5 lines
static struct resource i2c_resources[] = {
[0] = {
.start = AT91_CHIPSELECT_2, /* 0x30000000 */
.end = AT91_CHIPSELECT_2 + SZ_16K - 1,
.flags = IORESOURCE_MEM,Unless reading 0x30000000 does not return something like 0xf8, you have a problem with mapping in the register range. Make sure the, 8 bit bus width works.
Regards,
Wolfram
Hi,
Thanks a lot Wolfram for the hint. I have added the mapping configs:
#if defined (CONFIG_I2C_PCA_PLATFORM) || defined(CONFIG_I2C_ALGOPCA)
static struct resource i2c_resources[] = {
[0] = {
.start = AT91_CHIPSELECT_2, /* 0x30000000 */
.end = AT91_CHIPSELECT_2 + SZ_16K - 1,
.flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
},
[1] = {
.start = AT91RM9200_ID_IRQ0,
.end = AT91RM9200_ID_IRQ0,
.flags = IORESOURCE_IRQ,
},
};static struct i2c_pca9564_pf_platform_data pca9665_platform_data = {
.gpio = AT91_PIN_PB27,
.i2c_clock_speed= 400000,
.timeout = HZ, /* timeout in jiffies */
};static struct platform_device pca9665_twi_device = {
.name = "i2c-pca-platform",
.id = -1,
.dev = {
.platform_data = &pca9665_platform_data,
},
.num_resources = ARRAY_SIZE(i2c_resources),
.resource = i2c_resources,
};static struct i2c_board_info __initdata ek_i2c_devices[] = {
{
I2C_BOARD_INFO("lm75", 0x48),
},
{
I2C_BOARD_INFO("pcf8523", 0x68),
},
};void __init at91_add_device_i2c_pca(struct i2c_board_info *devices, int nr_devices)
{
at91_set_A_periph(AT91_PIN_PB29, 1); /* IRQ0 interrupt pin */
/* Initialization of the Static Memory Controller for Chip Select 2 */
at91_ramc_write(0, AT91_SMC_CSR(2), AT91_SMC_ACSS_STD
| AT91_SMC_DBW_8 /* 8 bit */
| AT91_SMC_WSEN /* Wait State Enable */
);
i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&pca9665_twi_device);
}#endif
And now the correct controller is detected:
# dmesg | grep PCA PCA9564/PCA9665 at 0x30000000: PCA9665 detected. PCA9564/PCA9665 at 0x30000000: Clock frequency is 400000Hz PCA9564/PCA9665 at 0x30000000 registered.
The i2c devices are also detected:
# i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --Best regards,
Elyas
Quoted 14 lines · Wolfram Sang
Quoted 5 lines
static struct resource i2c_resources[] = { [0] = { .start = AT91_CHIPSELECT_2, /* 0x30000000 */ .end = AT91_CHIPSELECT_2 + SZ_16K - 1, .flags = IORESOURCE_MEM,Unless reading
0x30000000does not return something like0xf8, you have a problem with mapping in the register range. Make sure the, 8 bit bus width works.Regards,
Wolfram