aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap1/devices.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap1/devices.c')
-rw-r--r--arch/arm/mach-omap1/devices.c547
1 files changed, 337 insertions, 210 deletions
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 3c5d901efea..325e6030095 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -9,213 +9,125 @@
* (at your option) any later version.
*/
-#include <linux/config.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/mach-types.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/tc.h>
-#include <asm/arch/board.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/gpio.h>
-
-
-static void omap_nop_release(struct device *dev)
-{
- /* Nothing */
-}
+#include <linux/platform_data/omap-wd-timer.h>
-/*-------------------------------------------------------------------------*/
+#include <asm/mach/map.h>
-#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+#include <mach/tc.h>
+#include <mach/mux.h>
-#define OMAP_I2C_BASE 0xfffb3800
+#include <mach/omap7xx.h>
+#include <mach/camera.h>
+#include <mach/hardware.h>
-static struct resource i2c_resources[] = {
- {
- .start = OMAP_I2C_BASE,
- .end = OMAP_I2C_BASE + 0x3f,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = INT_I2C,
- .flags = IORESOURCE_IRQ,
- },
-};
+#include "common.h"
+#include "clock.h"
+#include "mmc.h"
+#include "sram.h"
-/* DMA not used; works around erratum writing to non-empty i2c fifo */
+#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
-static struct platform_device omap_i2c_device = {
- .name = "i2c_omap",
- .id = -1,
- .dev = {
- .release = omap_nop_release,
- },
- .num_resources = ARRAY_SIZE(i2c_resources),
- .resource = i2c_resources,
+static struct platform_device omap_pcm = {
+ .name = "omap-pcm-audio",
+ .id = -1,
};
-static void omap_init_i2c(void)
+static void omap_init_audio(void)
{
- /* FIXME define and use a boot tag, in case of boards that
- * either don't wire up I2C, or chips that mux it differently...
- * it can include clocking and address info, maybe more.
- */
- omap_cfg_reg(I2C_SCL);
- omap_cfg_reg(I2C_SDA);
-
- (void) platform_device_register(&omap_i2c_device);
+ platform_device_register(&omap_pcm);
}
-#else
-static inline void omap_init_i2c(void) {}
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE)
-static u64 irda_dmamask = 0xffffffff;
-
-static struct platform_device omap1610ir_device = {
- .name = "omap1610-ir",
- .id = -1,
- .dev = {
- .release = omap_nop_release,
- .dma_mask = &irda_dmamask,
- },
-};
-
-static void omap_init_irda(void)
-{
- /* FIXME define and use a boot tag, members something like:
- * u8 uart; // uart1, or uart3
- * ... but driver only handles uart3 for now
- * s16 fir_sel; // gpio for SIR vs FIR
- * ... may prefer a callback for SIR/MIR/FIR mode select;
- * while h2 uses a GPIO, H3 uses a gpio expander
- */
- if (machine_is_omap_h2()
- || machine_is_omap_h3())
- (void) platform_device_register(&omap1610ir_device);
-}
#else
-static inline void omap_init_irda(void) {}
+static inline void omap_init_audio(void) {}
#endif
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-
-#define OMAP_MMC1_BASE 0xfffb7800
-#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
-
-static struct omap_mmc_conf mmc1_conf;
+#if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
-static u64 mmc1_dmamask = 0xffffffff;
+#define OMAP_RTC_BASE 0xfffb4800
-static struct resource mmc1_resources[] = {
+static struct resource rtc_resources[] = {
{
- .start = IO_ADDRESS(OMAP_MMC1_BASE),
- .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
+ .start = OMAP_RTC_BASE,
+ .end = OMAP_RTC_BASE + 0x5f,
.flags = IORESOURCE_MEM,
},
{
- .start = INT_MMC,
+ .start = INT_RTC_TIMER,
.flags = IORESOURCE_IRQ,
},
-};
-
-static struct platform_device mmc_omap_device1 = {
- .name = "mmci-omap",
- .id = 1,
- .dev = {
- .release = omap_nop_release,
- .dma_mask = &mmc1_dmamask,
- .platform_data = &mmc1_conf,
- },
- .num_resources = ARRAY_SIZE(mmc1_resources),
- .resource = mmc1_resources,
-};
-
-#ifdef CONFIG_ARCH_OMAP16XX
-
-static struct omap_mmc_conf mmc2_conf;
-
-static u64 mmc2_dmamask = 0xffffffff;
-
-static struct resource mmc2_resources[] = {
- {
- .start = IO_ADDRESS(OMAP_MMC2_BASE),
- .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
- .flags = IORESOURCE_MEM,
- },
{
- .start = INT_1610_MMC2,
+ .start = INT_RTC_ALARM,
.flags = IORESOURCE_IRQ,
},
};
-static struct platform_device mmc_omap_device2 = {
- .name = "mmci-omap",
- .id = 2,
- .dev = {
- .release = omap_nop_release,
- .dma_mask = &mmc2_dmamask,
- .platform_data = &mmc2_conf,
- },
- .num_resources = ARRAY_SIZE(mmc2_resources),
- .resource = mmc2_resources,
+static struct platform_device omap_rtc_device = {
+ .name = "omap_rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
};
-#endif
-static void __init omap_init_mmc(void)
+static void omap_init_rtc(void)
{
- const struct omap_mmc_config *mmc_conf;
- const struct omap_mmc_conf *mmc;
+ (void) platform_device_register(&omap_rtc_device);
+}
+#else
+static inline void omap_init_rtc(void) {}
+#endif
- /* NOTE: assumes MMC was never (wrongly) enabled */
- mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
- if (!mmc_conf)
- return;
+static inline void omap_init_mbox(void) { }
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
+ int controller_nr)
+{
+ if (controller_nr == 0) {
+ if (cpu_is_omap7xx()) {
+ omap_cfg_reg(MMC_7XX_CMD);
+ omap_cfg_reg(MMC_7XX_CLK);
+ omap_cfg_reg(MMC_7XX_DAT0);
+ } else {
+ omap_cfg_reg(MMC_CMD);
+ omap_cfg_reg(MMC_CLK);
+ omap_cfg_reg(MMC_DAT0);
+ }
- /* block 1 is always available and has just one pinout option */
- mmc = &mmc_conf->mmc[0];
- if (mmc->enabled) {
- omap_cfg_reg(MMC_CMD);
- omap_cfg_reg(MMC_CLK);
- omap_cfg_reg(MMC_DAT0);
if (cpu_is_omap1710()) {
- omap_cfg_reg(M15_1710_MMC_CLKI);
- omap_cfg_reg(P19_1710_MMC_CMDDIR);
- omap_cfg_reg(P20_1710_MMC_DATDIR0);
- }
- if (mmc->wire4) {
+ omap_cfg_reg(M15_1710_MMC_CLKI);
+ omap_cfg_reg(P19_1710_MMC_CMDDIR);
+ omap_cfg_reg(P20_1710_MMC_DATDIR0);
+ }
+ if (mmc_controller->slots[0].wires == 4 && !cpu_is_omap7xx()) {
omap_cfg_reg(MMC_DAT1);
- /* NOTE: DAT2 can be on W10 (here) or M15 */
- if (!mmc->nomux)
+ /* NOTE: DAT2 can be on W10 (here) or M15 */
+ if (!mmc_controller->slots[0].nomux)
omap_cfg_reg(MMC_DAT2);
omap_cfg_reg(MMC_DAT3);
}
- mmc1_conf = *mmc;
- (void) platform_device_register(&mmc_omap_device1);
}
-#ifdef CONFIG_ARCH_OMAP16XX
- /* block 2 is on newer chips, and has many pinout options */
- mmc = &mmc_conf->mmc[1];
- if (mmc->enabled) {
- if (!mmc->nomux) {
+ /* Block 2 is on newer chips, and has many pinout options */
+ if (cpu_is_omap16xx() && controller_nr == 1) {
+ if (!mmc_controller->slots[1].nomux) {
omap_cfg_reg(Y8_1610_MMC2_CMD);
omap_cfg_reg(Y10_1610_MMC2_CLK);
omap_cfg_reg(R18_1610_MMC2_CLKIN);
omap_cfg_reg(W8_1610_MMC2_DAT0);
- if (mmc->wire4) {
+ if (mmc_controller->slots[1].wires == 4) {
omap_cfg_reg(V8_1610_MMC2_DAT1);
omap_cfg_reg(W15_1610_MMC2_DAT2);
omap_cfg_reg(R10_1610_MMC2_DAT3);
@@ -230,88 +142,255 @@ static void __init omap_init_mmc(void)
/* Feedback clock must be set on OMAP-1710 MMC2 */
if (cpu_is_omap1710())
omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
- MOD_CONF_CTRL_1);
- mmc2_conf = *mmc;
- (void) platform_device_register(&mmc_omap_device2);
+ MOD_CONF_CTRL_1);
}
+}
+
+#define OMAP_MMC_NR_RES 4
+
+/*
+ * Register MMC devices.
+ */
+static int __init omap_mmc_add(const char *name, int id, unsigned long base,
+ unsigned long size, unsigned int irq,
+ unsigned rx_req, unsigned tx_req,
+ struct omap_mmc_platform_data *data)
+{
+ struct platform_device *pdev;
+ struct resource res[OMAP_MMC_NR_RES];
+ int ret;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ return -ENOMEM;
+
+ memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
+ res[0].start = base;
+ res[0].end = base + size - 1;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = res[1].end = irq;
+ res[1].flags = IORESOURCE_IRQ;
+ res[2].start = rx_req;
+ res[2].name = "rx";
+ res[2].flags = IORESOURCE_DMA;
+ res[3].start = tx_req;
+ res[3].name = "tx";
+ res[3].flags = IORESOURCE_DMA;
+
+ if (cpu_is_omap7xx())
+ data->slots[0].features = MMC_OMAP7XX;
+ if (cpu_is_omap15xx())
+ data->slots[0].features = MMC_OMAP15XX;
+ if (cpu_is_omap16xx())
+ data->slots[0].features = MMC_OMAP16XX;
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret == 0)
+ ret = platform_device_add_data(pdev, data, sizeof(*data));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto fail;
+
+ /* return device handle to board setup code */
+ data->dev = &pdev->dev;
+ return 0;
+
+fail:
+ platform_device_put(pdev);
+ return ret;
+}
+
+void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+ int i;
+
+ for (i = 0; i < nr_controllers; i++) {
+ unsigned long base, size;
+ unsigned rx_req, tx_req;
+ unsigned int irq = 0;
+
+ if (!mmc_data[i])
+ continue;
+
+ omap1_mmc_mux(mmc_data[i], i);
+
+ switch (i) {
+ case 0:
+ base = OMAP1_MMC1_BASE;
+ irq = INT_MMC;
+ rx_req = 22;
+ tx_req = 21;
+ break;
+ case 1:
+ if (!cpu_is_omap16xx())
+ return;
+ base = OMAP1_MMC2_BASE;
+ irq = INT_1610_MMC2;
+ rx_req = 55;
+ tx_req = 54;
+ break;
+ default:
+ continue;
+ }
+ size = OMAP1_MMC_SIZE;
+
+ omap_mmc_add("mmci-omap", i, base, size, irq,
+ rx_req, tx_req, mmc_data[i]);
+ }
+}
+
#endif
- return;
+
+/*-------------------------------------------------------------------------*/
+
+/* OMAP7xx SPI support */
+#if defined(CONFIG_SPI_OMAP_100K) || defined(CONFIG_SPI_OMAP_100K_MODULE)
+
+struct platform_device omap_spi1 = {
+ .name = "omap1_spi100k",
+ .id = 1,
+};
+
+struct platform_device omap_spi2 = {
+ .name = "omap1_spi100k",
+ .id = 2,
+};
+
+static void omap_init_spi100k(void)
+{
+ omap_spi1.dev.platform_data = ioremap(OMAP7XX_SPI1_BASE, 0x7ff);
+ if (omap_spi1.dev.platform_data)
+ platform_device_register(&omap_spi1);
+
+ omap_spi2.dev.platform_data = ioremap(OMAP7XX_SPI2_BASE, 0x7ff);
+ if (omap_spi2.dev.platform_data)
+ platform_device_register(&omap_spi2);
}
+
#else
-static inline void omap_init_mmc(void) {}
+static inline void omap_init_spi100k(void)
+{
+}
#endif
-#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
-#define OMAP_RTC_BASE 0xfffb4800
+#define OMAP1_CAMERA_BASE 0xfffb6800
+#define OMAP1_CAMERA_IOSIZE 0x1c
-static struct resource rtc_resources[] = {
- {
- .start = OMAP_RTC_BASE,
- .end = OMAP_RTC_BASE + 0x5f,
- .flags = IORESOURCE_MEM,
+static struct resource omap1_camera_resources[] = {
+ [0] = {
+ .start = OMAP1_CAMERA_BASE,
+ .end = OMAP1_CAMERA_BASE + OMAP1_CAMERA_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
},
- {
- .start = INT_RTC_TIMER,
- .flags = IORESOURCE_IRQ,
- },
- {
- .start = INT_RTC_ALARM,
- .flags = IORESOURCE_IRQ,
+ [1] = {
+ .start = INT_CAMERA,
+ .flags = IORESOURCE_IRQ,
},
};
-static struct platform_device omap_rtc_device = {
- .name = "omap_rtc",
- .id = -1,
- .dev = {
- .release = omap_nop_release,
+static u64 omap1_camera_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device omap1_camera_device = {
+ .name = "omap1-camera",
+ .id = 0, /* This is used to put cameras on this interface */
+ .dev = {
+ .dma_mask = &omap1_camera_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
- .num_resources = ARRAY_SIZE(rtc_resources),
- .resource = rtc_resources,
+ .num_resources = ARRAY_SIZE(omap1_camera_resources),
+ .resource = omap1_camera_resources,
};
-static void omap_init_rtc(void)
+void __init omap1_camera_init(void *info)
{
- (void) platform_device_register(&omap_rtc_device);
+ struct platform_device *dev = &omap1_camera_device;
+ int ret;
+
+ dev->dev.platform_data = info;
+
+ ret = platform_device_register(dev);
+ if (ret)
+ dev_err(&dev->dev, "unable to register device: %d\n", ret);
}
-#else
-static inline void omap_init_rtc(void) {}
-#endif
+
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
+static inline void omap_init_sti(void) {}
-#define OMAP_WDT_BASE 0xfffeb000
+/* Numbering for the SPI-capable controllers when used for SPI:
+ * spi = 1
+ * uwire = 2
+ * mmc1..2 = 3..4
+ * mcbsp1..3 = 5..7
+ */
-static struct resource wdt_resources[] = {
+#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
+
+#define OMAP_UWIRE_BASE 0xfffb3000
+
+static struct resource uwire_resources[] = {
{
- .start = OMAP_WDT_BASE,
- .end = OMAP_WDT_BASE + 0x4f,
+ .start = OMAP_UWIRE_BASE,
+ .end = OMAP_UWIRE_BASE + 0x20,
.flags = IORESOURCE_MEM,
},
};
-static struct platform_device omap_wdt_device = {
- .name = "omap1610_wdt",
+static struct platform_device omap_uwire_device = {
+ .name = "omap_uwire",
.id = -1,
- .dev = {
- .release = omap_nop_release,
- },
- .num_resources = ARRAY_SIZE(wdt_resources),
- .resource = wdt_resources,
+ .num_resources = ARRAY_SIZE(uwire_resources),
+ .resource = uwire_resources,
};
-static void omap_init_wdt(void)
+static void omap_init_uwire(void)
{
- (void) platform_device_register(&omap_wdt_device);
+ /* FIXME define and use a boot tag; not all boards will be hooking
+ * up devices to the microwire controller, and multi-board configs
+ * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
+ */
+
+ /* board-specific code must configure chipselects (only a few
+ * are normally used) and SCLK/SDI/SDO (each has two choices).
+ */
+ (void) platform_device_register(&omap_uwire_device);
}
#else
-static inline void omap_init_wdt(void) {}
+static inline void omap_init_uwire(void) {}
#endif
+#define OMAP1_RNG_BASE 0xfffe5000
+
+static struct resource omap1_rng_resources[] = {
+ {
+ .start = OMAP1_RNG_BASE,
+ .end = OMAP1_RNG_BASE + 0x4f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap1_rng_device = {
+ .name = "omap_rng",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap1_rng_resources),
+ .resource = omap1_rng_resources,
+};
+
+static void omap1_init_rng(void)
+{
+ if (!cpu_is_omap16xx())
+ return;
+
+ (void) platform_device_register(&omap1_rng_device);
+}
+
/*-------------------------------------------------------------------------*/
/*
@@ -329,23 +408,71 @@ static inline void omap_init_wdt(void) {}
* Claiming GPIOs, and setting their direction and initial values, is the
* responsibility of the device drivers. So is responding to probe().
*
- * Board-specific knowlege like creating devices or pin setup is to be
+ * Board-specific knowledge like creating devices or pin setup is to be
* kept out of drivers as much as possible. In particular, pin setup
* may be handled by the boot loader, and drivers should expect it will
* normally have been done by the time they're probed.
*/
-static int __init omap_init_devices(void)
+static int __init omap1_init_devices(void)
{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ omap_sram_init();
+ omap1_clk_late_init();
+
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
- omap_init_i2c();
- omap_init_irda();
- omap_init_mmc();
+
+ omap_init_audio();
+ omap_init_mbox();
omap_init_rtc();
- omap_init_wdt();
+ omap_init_spi100k();
+ omap_init_sti();
+ omap_init_uwire();
+ omap1_init_rng();
return 0;
}
-arch_initcall(omap_init_devices);
+arch_initcall(omap1_init_devices);
+
+#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
+static struct resource wdt_resources[] = {
+ {
+ .start = 0xfffeb000,
+ .end = 0xfffeb07F,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_wdt_device = {
+ .name = "omap_wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static int __init omap_init_wdt(void)
+{
+ struct omap_wd_timer_platform_data pdata;
+ int ret;
+
+ if (!cpu_is_omap16xx())
+ return -ENODEV;
+
+ pdata.read_reset_sources = omap1_get_reset_sources;
+
+ ret = platform_device_register(&omap_wdt_device);
+ if (!ret) {
+ ret = platform_device_add_data(&omap_wdt_device, &pdata,
+ sizeof(pdata));
+ if (ret)
+ platform_device_del(&omap_wdt_device);
+ }
+
+ return ret;
+}
+subsys_initcall(omap_init_wdt);
+#endif