avr32: improve NGW100 I2C/PMBus setup
authorDavid Brownell <dbrownell@users.sourceforge.net>
Thu, 12 Jun 2008 19:18:05 +0000 (12:18 -0700)
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>
Fri, 27 Jun 2008 13:32:29 +0000 (15:32 +0200)
Basic I2C initialization for the NGW100 board:

  - Provide empty i2c device table. Daughtercards may add devices,
    and the ATtiny24 could do stuff too.

  - Set up EXTINT(3) so the ATtiny24 can interrupt the AP7000.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
arch/avr32/boards/atngw100/setup.c

index 00ce961..a51bb9f 100644 (file)
@@ -9,6 +9,8 @@
  */
 #include <linux/clk.h>
 #include <linux/etherdevice.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <linux/init.h>
 #include <linux/linkage.h>
@@ -147,6 +149,10 @@ static struct platform_device i2c_gpio_device = {
        },
 };
 
+static struct i2c_board_info __initdata i2c_info[] = {
+       /* NOTE:  original ATtiny24 firmware is at address 0x0b */
+};
+
 static int __init atngw100_init(void)
 {
        unsigned        i;
@@ -172,12 +178,28 @@ static int __init atngw100_init(void)
        }
        platform_device_register(&ngw_gpio_leds);
 
+       /* all these i2c/smbus pins should have external pullups for
+        * open-drain sharing among all I2C devices.  SDA and SCL do;
+        * PB28/EXTINT3 doesn't; it should be SMBALERT# (for PMBus),
+        * but it's not available off-board.
+        */
+       at32_select_periph(GPIO_PIN_PB(28), 0, AT32_GPIOF_PULLUP);
        at32_select_gpio(i2c_gpio_data.sda_pin,
                AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
        at32_select_gpio(i2c_gpio_data.scl_pin,
                AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
        platform_device_register(&i2c_gpio_device);
+       i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
 
        return 0;
 }
 postcore_initcall(atngw100_init);
+
+static int __init atngw100_arch_init(void)
+{
+       /* set_irq_type() after the arch_initcall for EIC has run, and
+        * before the I2C subsystem could try using this IRQ.
+        */
+       return set_irq_type(AT32_EXTINT(3), IRQ_TYPE_EDGE_FALLING);
+}
+arch_initcall(atngw100_arch_init);