aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68knommu/platform/528x/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68knommu/platform/528x/config.c')
-rw-r--r--arch/m68knommu/platform/528x/config.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c
index 6e608d1836f..76b743343bf 100644
--- a/arch/m68knommu/platform/528x/config.c
+++ b/arch/m68knommu/platform/528x/config.c
@@ -17,10 +17,13 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
+#include <asm/mcfqspi.h>
/***************************************************************************/
@@ -76,10 +79,141 @@ static struct platform_device m528x_fec = {
.resource = m528x_fec_resources,
};
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+static struct resource m528x_qspi_resources[] = {
+ {
+ .start = MCFQSPI_IOBASE,
+ .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCFINT_VECBASE + MCFINT_QSPI,
+ .end = MCFINT_VECBASE + MCFINT_QSPI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+#define MCFQSPI_CS0 147
+#define MCFQSPI_CS1 148
+#define MCFQSPI_CS2 149
+#define MCFQSPI_CS3 150
+
+static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)
+{
+ int status;
+
+ status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
+ if (status) {
+ pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
+ goto fail0;
+ }
+ status = gpio_direction_output(MCFQSPI_CS0, 1);
+ if (status) {
+ pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
+ goto fail1;
+ }
+
+ status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
+ if (status) {
+ pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
+ goto fail1;
+ }
+ status = gpio_direction_output(MCFQSPI_CS1, 1);
+ if (status) {
+ pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
+ goto fail2;
+ }
+
+ status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
+ if (status) {
+ pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
+ goto fail2;
+ }
+ status = gpio_direction_output(MCFQSPI_CS2, 1);
+ if (status) {
+ pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
+ goto fail3;
+ }
+
+ status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
+ if (status) {
+ pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
+ goto fail3;
+ }
+ status = gpio_direction_output(MCFQSPI_CS3, 1);
+ if (status) {
+ pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
+ goto fail4;
+ }
+
+ return 0;
+
+fail4:
+ gpio_free(MCFQSPI_CS3);
+fail3:
+ gpio_free(MCFQSPI_CS2);
+fail2:
+ gpio_free(MCFQSPI_CS1);
+fail1:
+ gpio_free(MCFQSPI_CS0);
+fail0:
+ return status;
+}
+
+static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)
+{
+ gpio_free(MCFQSPI_CS3);
+ gpio_free(MCFQSPI_CS2);
+ gpio_free(MCFQSPI_CS1);
+ gpio_free(MCFQSPI_CS0);
+}
+
+static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,
+ u8 chip_select, bool cs_high)
+{
+ gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
+}
+
+static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,
+ u8 chip_select, bool cs_high)
+{
+ gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
+}
+
+static struct mcfqspi_cs_control m528x_cs_control = {
+ .setup = m528x_cs_setup,
+ .teardown = m528x_cs_teardown,
+ .select = m528x_cs_select,
+ .deselect = m528x_cs_deselect,
+};
+
+static struct mcfqspi_platform_data m528x_qspi_data = {
+ .bus_num = 0,
+ .num_chipselect = 4,
+ .cs_control = &m528x_cs_control,
+};
+
+static struct platform_device m528x_qspi = {
+ .name = "mcfqspi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m528x_qspi_resources),
+ .resource = m528x_qspi_resources,
+ .dev.platform_data = &m528x_qspi_data,
+};
+
+static void __init m528x_qspi_init(void)
+{
+ /* setup Port QS for QSPI with gpio CS control */
+ __raw_writeb(0x07, MCFGPIO_PQSPAR);
+}
+#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
static struct platform_device *m528x_devices[] __initdata = {
&m528x_uart,
&m528x_fec,
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+ &m528x_qspi,
+#endif
};
/***************************************************************************/
@@ -174,6 +308,9 @@ static int __init init_BSP(void)
mach_reset = m528x_cpu_reset;
m528x_uarts_init();
m528x_fec_init();
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+ m528x_qspi_init();
+#endif
platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
return 0;
}