--- linux/arch/arm/mach-at91/Kconfig 2011-10-24 18:07:29.000000000 -0400 +++ linux/arch/arm/mach-at91/Kconfig310spi_i2c 2011-11-09 21:44:03.923156549 -0500 @@ -497,6 +497,16 @@ config SAM9G20_SPI1 Select this to have silicon based SPI master on PB0, PB1, PB2 and chip select on PB3 or PC5. +if I2C_AT91 + +config SAM9G20_EXTRA_I2C + bool "extra I2C master on PA25,PA26" + help + Configures a gpio based I2C master on PA25(SDA) and PA26. + Assumes there is a silicon based I2C master on PA23,PA24. + +endif + endif choice --- linux/arch/arm/mach-at91/at91sam9260_devices.c 2011-07-22 14:16:44.000000000 -0400 +++ linux/arch/arm/mach-at91/at91sam9260_devices.c310i2c 2011-11-10 11:45:04.340930371 -0500 @@ -447,35 +447,7 @@ void __init at91_add_device_nand(struct * repeated STARTs in one scenario (the driver doesn't yet handle them). */ -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) - -static struct i2c_gpio_platform_data pdata = { - .sda_pin = AT91_PIN_PA23, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PA24, - .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ -}; - -static struct platform_device at91sam9260_twi_device = { - .name = "i2c-gpio", - .id = -1, - .dev.platform_data = &pdata, -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PA23, 1); - - at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PA24, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91sam9260_twi_device); -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) +#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) static struct resource twi_resources[] = { [0] = { @@ -509,6 +481,39 @@ void __init at91_add_device_i2c(struct i i2c_register_board_info(0, devices, nr_devices); platform_device_register(&at91sam9260_twi_device); } + +#elif defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) + +static struct i2c_gpio_platform_data pdata = { + .sda_pin = AT91_PIN_PA23, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA24, + .scl_is_open_drain = 1, + /* Some I2C devices are limited to 100 kHz and i2c-gpio.h + * says "frequency is (500 / udelay) kHz" so 5 is best (and is + * used in i2c-gpio.c) + */ + .udelay = 5, /* ~100 kHz */ +}; + +static struct platform_device at91sam9260_twi_device = { + .name = "i2c-gpio", + .id = -1, + .dev.platform_data = &pdata, +}; + +void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) +{ + at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PA23, 1); + + at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PA24, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&at91sam9260_twi_device); +} + #else void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} #endif --- linux/arch/arm/mach-at91/board-foxg20.c 2011-10-24 18:07:29.000000000 -0400 +++ linux/arch/arm/mach-at91/board-foxg20.c310spi_i2c 2011-11-10 11:43:26.264928133 -0500 @@ -148,6 +148,48 @@ static struct spi_board_info foxg20_spi_ #endif }; +#if defined(CONFIG_SAM9G20_EXTRA_I2C) || defined(CONFIG_SAM9G20_EXTRA_I2C_MODULE) + +#include + +static struct i2c_gpio_platform_data i2c_pdata = { + .sda_pin = AT91_PIN_PA25, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA26, + .scl_is_open_drain = 1, + /* Some I2C devices are limited to 100 kHz and i2c-gpio.h + * says "frequency is (500 / udelay) kHz" so 5 is best (and is + * used in i2c-gpio.c) + */ + .udelay = 5, /* ~100 kHz */ +}; + +static struct platform_device sam9g20_extra_twi_device = { + .name = "i2c-gpio", + .id = 1, /* hooks to /dev/i2c-1 */ + .dev.platform_data = &i2c_pdata, +}; + +static void __init add_device_i2c_extra(struct i2c_board_info *devices, + int nr_devices) +{ + at91_set_GPIO_periph(AT91_PIN_PA25, 1); /* TWD (SDA) */ + at91_set_multi_drive(AT91_PIN_PA25, 1); + + at91_set_GPIO_periph(AT91_PIN_PA26, 1); /* TWCK (SCL) */ + at91_set_multi_drive(AT91_PIN_PA26, 1); + + i2c_register_board_info(0, devices, nr_devices); + platform_device_register(&sam9g20_extra_twi_device); +} + +static struct i2c_board_info __initdata foxg20_i2c_extra_devices[] = { + { + I2C_BOARD_INFO("xyzxyz", 0x1), + }, +}; +#endif + /* * MACB Ethernet device @@ -266,6 +308,10 @@ static void __init foxg20_board_init(voi at91_add_device_mmc(0, &foxg20_mmc_data); /* I2C */ at91_add_device_i2c(foxg20_i2c_devices, ARRAY_SIZE(foxg20_i2c_devices)); +#if defined(CONFIG_SAM9G20_EXTRA_I2C) || defined(CONFIG_SAM9G20_EXTRA_I2C_MODULE) + add_device_i2c_extra(foxg20_i2c_extra_devices, + ARRAY_SIZE(foxg20_i2c_extra_devices)); +#endif /* LEDs */ at91_gpio_leds(foxg20_leds, ARRAY_SIZE(foxg20_leds)); /* Push Buttons */