ARM: 5631/1: Platform data for CF/IDE support in AT91SAM9260
authorSergey Matyukevich <geomatsi@gmail.com>
Thu, 30 Jul 2009 21:23:24 +0000 (22:23 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 1 Aug 2009 15:24:59 +0000 (16:24 +0100)
This patch adds platform data for CF/IDE support
and SMC init code for AT91SAM9260 SoC.

Tested-by: Sergey Matyukevich <geomatsi@gmail.com>
Signed-off-by: Sergey Matyukevich <geomatsi@gmail.com>
Acked-by: Andrew Victor <linux@maxim.org.za>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-at91/at91sam9260_devices.c

index d74c9ac007e75c1d91642d711c7ef19c93b320e1..ee4ea0e720cf14239dedbece059d24c9c20c0f54 100644 (file)
@@ -1113,6 +1113,122 @@ void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  CF/IDE
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \
+       defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \
+       defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_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,
+       }
+};
+
+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,
+       }
+};
+
+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)
+{
+       struct platform_device *pdev;
+       unsigned long csa;
+
+       if (!data)
+               return;
+
+       csa = at91_sys_read(AT91_MATRIX_EBICSA);
+
+       switch (data->chipselect) {
+       case 4:
+               at91_set_multi_drive(AT91_PIN_PC8, 0);
+               at91_set_A_periph(AT91_PIN_PC8, 0);
+               csa |= AT91_MATRIX_CS4A_SMC_CF1;
+               cf0_data = *data;
+               pdev = &cf0_device;
+               break;
+       case 5:
+               at91_set_multi_drive(AT91_PIN_PC9, 0);
+               at91_set_A_periph(AT91_PIN_PC9, 0);
+               csa |= AT91_MATRIX_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_EBICSA, csa);
+
+       if (data->rst_pin) {
+               at91_set_multi_drive(data->rst_pin, 0);
+               at91_set_gpio_output(data->rst_pin, 1);
+       }
+
+       if (data->irq_pin) {
+               at91_set_gpio_input(data->irq_pin, 0);
+               at91_set_deglitch(data->irq_pin, 1);
+       }
+
+       if (data->det_pin) {
+               at91_set_gpio_input(data->det_pin, 0);
+               at91_set_deglitch(data->det_pin, 1);
+       }
+
+       at91_set_B_periph(AT91_PIN_PC6, 0);     /* CFCE1 */
+       at91_set_B_periph(AT91_PIN_PC7, 0);     /* CFCE2 */
+       at91_set_A_periph(AT91_PIN_PC10, 0);    /* CFRNW */
+       at91_set_A_periph(AT91_PIN_PC15, 1);    /* NWAIT */
+
+       if (data->flags & AT91_CF_TRUE_IDE)
+#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE)
+               pdev->name = "pata_at91";
+#elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
+               pdev->name = "at91_ide";
+#else
+#warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91"
+#endif
+       else
+               pdev->name = "at91_cf";
+
+       platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_cf(struct at91_cf_data * data) {}
+#endif
 
 /* -------------------------------------------------------------------- */
 /*