]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - arch/arm/mach-at91/at91sam9g45_devices.c
Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
[mirror_ubuntu-artful-kernel.git] / arch / arm / mach-at91 / at91sam9g45_devices.c
index 1f89b206c26ff8fa7b35747cdf44f01fdd908f8b..698479f1e197cf5725139bf135eb0c89f0d5d715 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
+#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 #include <linux/atmel-mci.h>
 #include <mach/board.h>
 #include <mach/at91sam9g45.h>
 #include <mach/at91sam9g45_matrix.h>
+#include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at_hdmac.h>
 #include <mach/atmel-mci.h>
 
+#include <media/atmel-isi.h>
+
 #include "generic.h"
+#include "clock.h"
 
 
 /* --------------------------------------------------------------------
 #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
 static u64 hdmac_dmamask = DMA_BIT_MASK(32);
 
-static struct at_dma_platform_data atdma_pdata = {
-       .nr_channels    = 8,
-};
-
 static struct resource hdmac_resources[] = {
        [0] = {
                .start  = AT91SAM9G45_BASE_DMA,
@@ -56,12 +57,11 @@ static struct resource hdmac_resources[] = {
 };
 
 static struct platform_device at_hdmac_device = {
-       .name           = "at_hdmac",
+       .name           = "at91sam9g45_dma",
        .id             = -1,
        .dev            = {
                                .dma_mask               = &hdmac_dmamask,
                                .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &atdma_pdata,
        },
        .resource       = hdmac_resources,
        .num_resources  = ARRAY_SIZE(hdmac_resources),
@@ -69,9 +69,15 @@ static struct platform_device at_hdmac_device = {
 
 void __init at91_add_device_hdmac(void)
 {
-       dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
-       dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask);
-       platform_device_register(&at_hdmac_device);
+#if defined(CONFIG_OF)
+       struct device_node *of_node =
+               of_find_node_by_name(NULL, "dma-controller");
+
+       if (of_node)
+               of_node_put(of_node);
+       else
+#endif
+               platform_device_register(&at_hdmac_device);
 }
 #else
 void __init at91_add_device_hdmac(void) {}
@@ -551,8 +557,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
        if (!data)
                return;
 
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
+       csa = at91_matrix_read(AT91_MATRIX_EBICSA);
+       at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
 
        /* enable pin */
        if (gpio_is_valid(data->enable_pin))
@@ -868,6 +874,96 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
 void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  Image Sensor Interface
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
+static u64 isi_dmamask = DMA_BIT_MASK(32);
+static struct isi_platform_data isi_data;
+
+struct resource isi_resources[] = {
+       [0] = {
+               .start  = AT91SAM9G45_BASE_ISI,
+               .end    = AT91SAM9G45_BASE_ISI + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9G45_ID_ISI,
+               .end    = AT91SAM9G45_ID_ISI,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91sam9g45_isi_device = {
+       .name           = "atmel_isi",
+       .id             = 0,
+       .dev            = {
+                       .dma_mask               = &isi_dmamask,
+                       .coherent_dma_mask      = DMA_BIT_MASK(32),
+                       .platform_data          = &isi_data,
+       },
+       .resource       = isi_resources,
+       .num_resources  = ARRAY_SIZE(isi_resources),
+};
+
+static struct clk_lookup isi_mck_lookups[] = {
+       CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL),
+};
+
+void __init at91_add_device_isi(struct isi_platform_data *data,
+               bool use_pck_as_mck)
+{
+       struct clk *pck;
+       struct clk *parent;
+
+       if (!data)
+               return;
+       isi_data = *data;
+
+       at91_set_A_periph(AT91_PIN_PB20, 0);    /* ISI_D0 */
+       at91_set_A_periph(AT91_PIN_PB21, 0);    /* ISI_D1 */
+       at91_set_A_periph(AT91_PIN_PB22, 0);    /* ISI_D2 */
+       at91_set_A_periph(AT91_PIN_PB23, 0);    /* ISI_D3 */
+       at91_set_A_periph(AT91_PIN_PB24, 0);    /* ISI_D4 */
+       at91_set_A_periph(AT91_PIN_PB25, 0);    /* ISI_D5 */
+       at91_set_A_periph(AT91_PIN_PB26, 0);    /* ISI_D6 */
+       at91_set_A_periph(AT91_PIN_PB27, 0);    /* ISI_D7 */
+       at91_set_A_periph(AT91_PIN_PB28, 0);    /* ISI_PCK */
+       at91_set_A_periph(AT91_PIN_PB30, 0);    /* ISI_HSYNC */
+       at91_set_A_periph(AT91_PIN_PB29, 0);    /* ISI_VSYNC */
+       at91_set_B_periph(AT91_PIN_PB8, 0);     /* ISI_PD8 */
+       at91_set_B_periph(AT91_PIN_PB9, 0);     /* ISI_PD9 */
+       at91_set_B_periph(AT91_PIN_PB10, 0);    /* ISI_PD10 */
+       at91_set_B_periph(AT91_PIN_PB11, 0);    /* ISI_PD11 */
+
+       platform_device_register(&at91sam9g45_isi_device);
+
+       if (use_pck_as_mck) {
+               at91_set_B_periph(AT91_PIN_PB31, 0);    /* ISI_MCK (PCK1) */
+
+               pck = clk_get(NULL, "pck1");
+               parent = clk_get(NULL, "plla");
+
+               BUG_ON(IS_ERR(pck) || IS_ERR(parent));
+
+               if (clk_set_parent(pck, parent)) {
+                       pr_err("Failed to set PCK's parent\n");
+               } else {
+                       /* Register PCK as ISI_MCK */
+                       isi_mck_lookups[0].clk = pck;
+                       clkdev_add_table(isi_mck_lookups,
+                                       ARRAY_SIZE(isi_mck_lookups));
+               }
+
+               clk_put(pck);
+               clk_put(parent);
+       }
+}
+#else
+void __init at91_add_device_isi(struct isi_platform_data *data,
+               bool use_pck_as_mck) {}
+#endif
+
 
 /* --------------------------------------------------------------------
  *  LCD Controller
@@ -955,7 +1051,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
 static struct resource tcb0_resources[] = {
        [0] = {
                .start  = AT91SAM9G45_BASE_TCB0,
-               .end    = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1,
+               .end    = AT91SAM9G45_BASE_TCB0 + SZ_256 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -976,7 +1072,7 @@ static struct platform_device at91sam9g45_tcb0_device = {
 static struct resource tcb1_resources[] = {
        [0] = {
                .start  = AT91SAM9G45_BASE_TCB1,
-               .end    = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1,
+               .end    = AT91SAM9G45_BASE_TCB1 + SZ_256 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -993,8 +1089,25 @@ static struct platform_device at91sam9g45_tcb1_device = {
        .num_resources  = ARRAY_SIZE(tcb1_resources),
 };
 
+#if defined(CONFIG_OF)
+static struct of_device_id tcb_ids[] = {
+       { .compatible = "atmel,at91rm9200-tcb" },
+       { /*sentinel*/ }
+};
+#endif
+
 static void __init at91_add_device_tc(void)
 {
+#if defined(CONFIG_OF)
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, tcb_ids);
+       if (np) {
+               of_node_put(np);
+               return;
+       }
+#endif
+
        platform_device_register(&at91sam9g45_tcb0_device);
        platform_device_register(&at91sam9g45_tcb1_device);
 }
@@ -1097,6 +1210,8 @@ static struct resource rtt_resources[] = {
                .start  = AT91SAM9G45_BASE_RTT,
                .end    = AT91SAM9G45_BASE_RTT + SZ_16 - 1,
                .flags  = IORESOURCE_MEM,
+       }, {
+               .flags  = IORESOURCE_MEM,
        }
 };
 
@@ -1104,11 +1219,32 @@ static struct platform_device at91sam9g45_rtt_device = {
        .name           = "at91_rtt",
        .id             = 0,
        .resource       = rtt_resources,
-       .num_resources  = ARRAY_SIZE(rtt_resources),
 };
 
+#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9)
+static void __init at91_add_device_rtt_rtc(void)
+{
+       at91sam9g45_rtt_device.name = "rtc-at91sam9";
+       /*
+        * The second resource is needed:
+        * GPBR will serve as the storage for RTC time offset
+        */
+       at91sam9g45_rtt_device.num_resources = 2;
+       rtt_resources[1].start = AT91SAM9G45_BASE_GPBR +
+                                4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;
+       rtt_resources[1].end = rtt_resources[1].start + 3;
+}
+#else
+static void __init at91_add_device_rtt_rtc(void)
+{
+       /* Only one resource is needed: RTT not used as RTC */
+       at91sam9g45_rtt_device.num_resources = 1;
+}
+#endif
+
 static void __init at91_add_device_rtt(void)
 {
+       at91_add_device_rtt_rtc();
        platform_device_register(&at91sam9g45_rtt_device);
 }
 
@@ -1563,7 +1699,6 @@ static inline void configure_usart3_pins(unsigned pins)
 }
 
 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_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {