ARM: 5766/1: Fix watchdog enabling for AT91SAM9G45
[safe/jmp/linux-2.6] / arch / arm / mach-at91 / at91sam9263_devices.c
index f83ef62..fb5c23a 100644 (file)
 #include <linux/fb.h>
 #include <video/atmel_lcdc.h>
 
-#include <asm/arch/board.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/at91sam9263.h>
-#include <asm/arch/at91sam926x_mc.h>
-#include <asm/arch/at91sam9263_matrix.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9263.h>
+#include <mach/at91sam9263_matrix.h>
+#include <mach/at91sam9_smc.h>
 
 #include "generic.h"
 
@@ -308,7 +308,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
                }
 
                mmc0_data = *data;
-               at91_clock_associate("mci0_clk", &at91sam9263_mmc1_device.dev, "mci_clk");
+               at91_clock_associate("mci0_clk", &at91sam9263_mmc0_device.dev, "mci_clk");
                platform_device_register(&at91sam9263_mmc0_device);
        } else {                        /* MCI1 */
                /* CLK */
@@ -347,26 +347,136 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
 void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  Compact Flash (PCMCIA or IDE)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \
+    defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
+
+static struct at91_cf_data cf0_data;
+
+static struct resource cf0_resources[] = {
+       [0] = {
+               .start  = AT91_CHIPSELECT_4,
+               .end    = AT91_CHIPSELECT_4 + SZ_256M - 1,
+               .flags  = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+       }
+};
+
+static struct platform_device cf0_device = {
+       .id             = 0,
+       .dev            = {
+                               .platform_data  = &cf0_data,
+       },
+       .resource       = cf0_resources,
+       .num_resources  = ARRAY_SIZE(cf0_resources),
+};
+
+static struct at91_cf_data cf1_data;
+
+static struct resource cf1_resources[] = {
+       [0] = {
+               .start  = AT91_CHIPSELECT_5,
+               .end    = AT91_CHIPSELECT_5 + SZ_256M - 1,
+               .flags  = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+       }
+};
+
+static struct platform_device cf1_device = {
+       .id             = 1,
+       .dev            = {
+                               .platform_data  = &cf1_data,
+       },
+       .resource       = cf1_resources,
+       .num_resources  = ARRAY_SIZE(cf1_resources),
+};
+
+void __init at91_add_device_cf(struct at91_cf_data *data)
+{
+       unsigned long ebi0_csa;
+       struct platform_device *pdev;
+
+       if (!data)
+               return;
+
+       /*
+        * assign CS4 or CS5 to SMC with Compact Flash logic support,
+        * we assume SMC timings are configured by board code,
+        * except True IDE where timings are controlled by driver
+        */
+       ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
+       switch (data->chipselect) {
+       case 4:
+               at91_set_A_periph(AT91_PIN_PD6, 0);  /* EBI0_NCS4/CFCS0 */
+               ebi0_csa |= AT91_MATRIX_EBI0_CS4A_SMC_CF1;
+               cf0_data = *data;
+               pdev = &cf0_device;
+               break;
+       case 5:
+               at91_set_A_periph(AT91_PIN_PD7, 0);  /* EBI0_NCS5/CFCS1 */
+               ebi0_csa |= AT91_MATRIX_EBI0_CS5A_SMC_CF2;
+               cf1_data = *data;
+               pdev = &cf1_device;
+               break;
+       default:
+               printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
+                      data->chipselect);
+               return;
+       }
+       at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa);
+
+       if (data->det_pin) {
+               at91_set_gpio_input(data->det_pin, 1);
+               at91_set_deglitch(data->det_pin, 1);
+       }
+
+       if (data->irq_pin) {
+               at91_set_gpio_input(data->irq_pin, 1);
+               at91_set_deglitch(data->irq_pin, 1);
+       }
+
+       if (data->vcc_pin)
+               /* initially off */
+               at91_set_gpio_output(data->vcc_pin, 0);
+
+       /* enable EBI controlled pins */
+       at91_set_A_periph(AT91_PIN_PD5, 1);  /* NWAIT */
+       at91_set_A_periph(AT91_PIN_PD8, 0);  /* CFCE1 */
+       at91_set_A_periph(AT91_PIN_PD9, 0);  /* CFCE2 */
+       at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */
+
+       pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf";
+       platform_device_register(pdev);
+}
+#else
+void __init at91_add_device_cf(struct at91_cf_data *data) {}
+#endif
 
 /* --------------------------------------------------------------------
  *  NAND / SmartMedia
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
-static struct at91_nand_data nand_data;
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
 
 #define NAND_BASE      AT91_CHIPSELECT_3
 
 static struct resource nand_resources[] = {
-       {
+       [0] = {
                .start  = NAND_BASE,
                .end    = NAND_BASE + SZ_256M - 1,
                .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91_BASE_SYS + AT91_ECC0,
+               .end    = AT91_BASE_SYS + AT91_ECC0 + SZ_512 - 1,
+               .flags  = IORESOURCE_MEM,
        }
 };
 
 static struct platform_device at91sam9263_nand_device = {
-       .name           = "at91_nand",
+       .name           = "atmel_nand",
        .id             = -1,
        .dev            = {
                                .platform_data  = &nand_data,
@@ -375,30 +485,15 @@ static struct platform_device at91sam9263_nand_device = {
        .num_resources  = ARRAY_SIZE(nand_resources),
 };
 
-void __init at91_add_device_nand(struct at91_nand_data *data)
+void __init at91_add_device_nand(struct atmel_nand_data *data)
 {
-       unsigned long csa, mode;
+       unsigned long csa;
 
        if (!data)
                return;
 
        csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
-       at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC);
-
-       /* set the bus interface characteristics */
-       at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
-                       | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
-
-       at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
-                       | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
-
-       at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
-
-       if (data->bus_width_16)
-               mode = AT91_SMC_DBW_16;
-       else
-               mode = AT91_SMC_DBW_8;
-       at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
+       at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
 
        /* enable pin */
        if (data->enable_pin)
@@ -416,7 +511,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
        platform_device_register(&at91sam9263_nand_device);
 }
 #else
-void __init at91_add_device_nand(struct at91_nand_data *data) {}
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
 #endif
 
 
@@ -612,9 +707,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
  *  AC97
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
+#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
 static u64 ac97_dmamask = DMA_BIT_MASK(32);
-static struct atmel_ac97_data ac97_data;
+static struct ac97c_platform_data ac97_data;
 
 static struct resource ac97_resources[] = {
        [0] = {
@@ -630,8 +725,8 @@ static struct resource ac97_resources[] = {
 };
 
 static struct platform_device at91sam9263_ac97_device = {
-       .name           = "ac97c",
-       .id             = 1,
+       .name           = "atmel_ac97c",
+       .id             = 0,
        .dev            = {
                                .dma_mask               = &ac97_dmamask,
                                .coherent_dma_mask      = DMA_BIT_MASK(32),
@@ -641,7 +736,7 @@ static struct platform_device at91sam9263_ac97_device = {
        .num_resources  = ARRAY_SIZE(ac97_resources),
 };
 
-void __init at91_add_device_ac97(struct atmel_ac97_data *data)
+void __init at91_add_device_ac97(struct ac97c_platform_data *data)
 {
        if (!data)
                return;
@@ -655,13 +750,49 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data)
        if (data->reset_pin)
                at91_set_gpio_output(data->reset_pin, 0);
 
-       ac97_data = *ek_data;
+       ac97_data = *data;
        platform_device_register(&at91sam9263_ac97_device);
 }
 #else
-void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
+void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  CAN Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE)
+static struct resource can_resources[] = {
+       [0] = {
+               .start  = AT91SAM9263_BASE_CAN,
+               .end    = AT91SAM9263_BASE_CAN + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9263_ID_CAN,
+               .end    = AT91SAM9263_ID_CAN,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91sam9263_can_device = {
+       .name           = "at91_can",
+       .id             = -1,
+       .resource       = can_resources,
+       .num_resources  = ARRAY_SIZE(can_resources),
+};
+
+void __init at91_add_device_can(struct at91_can_data *data)
+{
+       at91_set_A_periph(AT91_PIN_PA13, 0);    /* CANTX */
+       at91_set_A_periph(AT91_PIN_PA14, 0);    /* CANRX */
+       at91sam9263_can_device.dev.platform_data = data;
+
+       platform_device_register(&at91sam9263_can_device);
+}
+#else
+void __init at91_add_device_can(struct at91_can_data *data) {}
+#endif
 
 /* --------------------------------------------------------------------
  *  LCD Controller
@@ -783,6 +914,43 @@ void __init at91_add_device_isi(void) {}
 
 
 /* --------------------------------------------------------------------
+ *  Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+       [0] = {
+               .start  = AT91SAM9263_BASE_TCB0,
+               .end    = AT91SAM9263_BASE_TCB0 + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9263_ID_TCB,
+               .end    = AT91SAM9263_ID_TCB,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91sam9263_tcb_device = {
+       .name           = "atmel_tcb",
+       .id             = 0,
+       .resource       = tcb_resources,
+       .num_resources  = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+       /* this chip has one clock and irq for all three TC channels */
+       at91_clock_associate("tcb_clk", &at91sam9263_tcb_device.dev, "t0_clk");
+       platform_device_register(&at91sam9263_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
  *  RTT
  * -------------------------------------------------------------------- */
 
@@ -827,7 +995,7 @@ static void __init at91_add_device_rtt(void)
  *  Watchdog
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
 static struct platform_device at91sam9263_wdt_device = {
        .name           = "at91_wdt",
        .id             = -1,
@@ -844,24 +1012,55 @@ static void __init at91_add_device_watchdog(void) {}
 
 
 /* --------------------------------------------------------------------
- *  LEDs
- * -------------------------------------------------------------------- */
+ *  PWM
+ * --------------------------------------------------------------------*/
 
-#if defined(CONFIG_LEDS)
-u8 at91_leds_cpu;
-u8 at91_leds_timer;
+#if defined(CONFIG_ATMEL_PWM)
+static u32 pwm_mask;
 
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+static struct resource pwm_resources[] = {
+       [0] = {
+               .start  = AT91SAM9263_BASE_PWMC,
+               .end    = AT91SAM9263_BASE_PWMC + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9263_ID_PWMC,
+               .end    = AT91SAM9263_ID_PWMC,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91sam9263_pwm0_device = {
+       .name   = "atmel_pwm",
+       .id     = -1,
+       .dev    = {
+               .platform_data          = &pwm_mask,
+       },
+       .resource       = pwm_resources,
+       .num_resources  = ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
 {
-       /* Enable GPIO to access the LEDs */
-       at91_set_gpio_output(cpu_led, 1);
-       at91_set_gpio_output(timer_led, 1);
+       if (mask & (1 << AT91_PWM0))
+               at91_set_B_periph(AT91_PIN_PB7, 1);     /* enable PWM0 */
+
+       if (mask & (1 << AT91_PWM1))
+               at91_set_B_periph(AT91_PIN_PB8, 1);     /* enable PWM1 */
+
+       if (mask & (1 << AT91_PWM2))
+               at91_set_B_periph(AT91_PIN_PC29, 1);    /* enable PWM2 */
+
+       if (mask & (1 << AT91_PWM3))
+               at91_set_B_periph(AT91_PIN_PB29, 1);    /* enable PWM3 */
 
-       at91_leds_cpu   = cpu_led;
-       at91_leds_timer = timer_led;
+       pwm_mask = mask;
+
+       platform_device_register(&at91sam9263_pwm0_device);
 }
 #else
-void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+void __init at91_add_device_pwm(u32 mask) {}
 #endif
 
 
@@ -955,9 +1154,6 @@ static inline void configure_ssc1_pins(unsigned pins)
 }
 
 /*
- * Return the device node so that board init code can use it as the
- * parent for the device node reflecting how it's used on this board.
- *
  * SSC controllers are accessed through library code, instead of any
  * kind of all-singing/all-dancing driver.  For example one could be
  * used by a particular I2S audio codec's driver, while another one
@@ -1071,12 +1267,15 @@ static struct platform_device at91sam9263_uart0_device = {
        .num_resources  = ARRAY_SIZE(uart0_resources),
 };
 
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(unsigned pins)
 {
        at91_set_A_periph(AT91_PIN_PA26, 1);            /* TXD0 */
        at91_set_A_periph(AT91_PIN_PA27, 0);            /* RXD0 */
-       at91_set_A_periph(AT91_PIN_PA28, 0);            /* RTS0 */
-       at91_set_A_periph(AT91_PIN_PA29, 0);            /* CTS0 */
+
+       if (pins & ATMEL_UART_RTS)
+               at91_set_A_periph(AT91_PIN_PA28, 0);    /* RTS0 */
+       if (pins & ATMEL_UART_CTS)
+               at91_set_A_periph(AT91_PIN_PA29, 0);    /* CTS0 */
 }
 
 static struct resource uart1_resources[] = {
@@ -1111,12 +1310,15 @@ static struct platform_device at91sam9263_uart1_device = {
        .num_resources  = ARRAY_SIZE(uart1_resources),
 };
 
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(unsigned pins)
 {
        at91_set_A_periph(AT91_PIN_PD0, 1);             /* TXD1 */
        at91_set_A_periph(AT91_PIN_PD1, 0);             /* RXD1 */
-       at91_set_B_periph(AT91_PIN_PD7, 0);             /* RTS1 */
-       at91_set_B_periph(AT91_PIN_PD8, 0);             /* CTS1 */
+
+       if (pins & ATMEL_UART_RTS)
+               at91_set_B_periph(AT91_PIN_PD7, 0);     /* RTS1 */
+       if (pins & ATMEL_UART_CTS)
+               at91_set_B_periph(AT91_PIN_PD8, 0);     /* CTS1 */
 }
 
 static struct resource uart2_resources[] = {
@@ -1151,55 +1353,58 @@ static struct platform_device at91sam9263_uart2_device = {
        .num_resources  = ARRAY_SIZE(uart2_resources),
 };
 
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(unsigned pins)
 {
        at91_set_A_periph(AT91_PIN_PD2, 1);             /* TXD2 */
        at91_set_A_periph(AT91_PIN_PD3, 0);             /* RXD2 */
-       at91_set_B_periph(AT91_PIN_PD5, 0);             /* RTS2 */
-       at91_set_B_periph(AT91_PIN_PD6, 0);             /* CTS2 */
+
+       if (pins & ATMEL_UART_RTS)
+               at91_set_B_periph(AT91_PIN_PD5, 0);     /* RTS2 */
+       if (pins & ATMEL_UART_CTS)
+               at91_set_B_periph(AT91_PIN_PD6, 0);     /* CTS2 */
 }
 
-static struct platform_device *at91_uarts[ATMEL_MAX_UART];     /* the UARTs to use */
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
 struct platform_device *atmel_default_console_device;  /* the serial console device */
 
-void __init at91_init_serial(struct at91_uart_config *config)
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
-       int i;
+       struct platform_device *pdev;
 
-       /* Fill in list of supported UARTs */
-       for (i = 0; i < config->nr_tty; i++) {
-               switch (config->tty_map[i]) {
-                       case 0:
-                               configure_usart0_pins();
-                               at91_uarts[i] = &at91sam9263_uart0_device;
-                               at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart");
-                               break;
-                       case 1:
-                               configure_usart1_pins();
-                               at91_uarts[i] = &at91sam9263_uart1_device;
-                               at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart");
-                               break;
-                       case 2:
-                               configure_usart2_pins();
-                               at91_uarts[i] = &at91sam9263_uart2_device;
-                               at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart");
-                               break;
-                       case 3:
-                               configure_dbgu_pins();
-                               at91_uarts[i] = &at91sam9263_dbgu_device;
-                               at91_clock_associate("mck", &at91sam9263_dbgu_device.dev, "usart");
-                               break;
-                       default:
-                               continue;
-               }
-               at91_uarts[i]->id = i;          /* update ID number to mapped ID */
+       switch (id) {
+               case 0:         /* DBGU */
+                       pdev = &at91sam9263_dbgu_device;
+                       configure_dbgu_pins();
+                       at91_clock_associate("mck", &pdev->dev, "usart");
+                       break;
+               case AT91SAM9263_ID_US0:
+                       pdev = &at91sam9263_uart0_device;
+                       configure_usart0_pins(pins);
+                       at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+                       break;
+               case AT91SAM9263_ID_US1:
+                       pdev = &at91sam9263_uart1_device;
+                       configure_usart1_pins(pins);
+                       at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+                       break;
+               case AT91SAM9263_ID_US2:
+                       pdev = &at91sam9263_uart2_device;
+                       configure_usart2_pins(pins);
+                       at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+                       break;
+               default:
+                       return;
        }
+       pdev->id = portnr;              /* update to mapped ID */
 
-       /* Set serial console device */
-       if (config->console_tty < ATMEL_MAX_UART)
-               atmel_default_console_device = at91_uarts[config->console_tty];
-       if (!atmel_default_console_device)
-               printk(KERN_INFO "AT91: No default serial console defined.\n");
+       if (portnr < ATMEL_MAX_UART)
+               at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+       if (portnr < ATMEL_MAX_UART)
+               atmel_default_console_device = at91_uarts[portnr];
 }
 
 void __init at91_add_device_serial(void)
@@ -1210,9 +1415,13 @@ void __init at91_add_device_serial(void)
                if (at91_uarts[i])
                        platform_device_register(at91_uarts[i]);
        }
+
+       if (!atmel_default_console_device)
+               printk(KERN_INFO "AT91: No default serial console defined.\n");
 }
 #else
-void __init at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
 #endif
 
@@ -1226,6 +1435,7 @@ static int __init at91_add_standard_devices(void)
 {
        at91_add_device_rtt();
        at91_add_device_watchdog();
+       at91_add_device_tc();
        return 0;
 }