]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/arm/mach-ep93xx/core.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[mv-sheeva.git] / arch / arm / mach-ep93xx / core.c
index 9092677f63eb739a529d137b5b1be891b11f53da..4cb55d3902ff675e4fb5e3ed59d6244eb20f181d 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/termios.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
+#include <linux/mtd/physmap.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <linux/spi/spi.h>
@@ -215,8 +216,8 @@ void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
        spin_lock_irqsave(&syscon_swlock, flags);
 
        val = __raw_readl(EP93XX_SYSCON_DEVCFG);
-       val |= set_bits;
        val &= ~clear_bits;
+       val |= set_bits;
        __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
        __raw_writel(val, EP93XX_SYSCON_DEVCFG);
 
@@ -347,6 +348,43 @@ static struct platform_device ep93xx_ohci_device = {
 };
 
 
+/*************************************************************************
+ * EP93xx physmap'ed flash
+ *************************************************************************/
+static struct physmap_flash_data ep93xx_flash_data;
+
+static struct resource ep93xx_flash_resource = {
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device ep93xx_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &ep93xx_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &ep93xx_flash_resource,
+};
+
+/**
+ * ep93xx_register_flash() - Register the external flash device.
+ * @width:     bank width in octets
+ * @start:     resource start address
+ * @size:      resource size
+ */
+void __init ep93xx_register_flash(unsigned int width,
+                                 resource_size_t start, resource_size_t size)
+{
+       ep93xx_flash_data.width         = width;
+
+       ep93xx_flash_resource.start     = start;
+       ep93xx_flash_resource.end       = start + size - 1;
+
+       platform_device_register(&ep93xx_flash);
+}
+
+
 /*************************************************************************
  * EP93xx ethernet peripheral handling
  *************************************************************************/
@@ -620,6 +658,11 @@ static struct platform_device ep93xx_fb_device = {
        .resource               = ep93xx_fb_resource,
 };
 
+static struct platform_device ep93xx_bl_device = {
+       .name           = "ep93xx-bl",
+       .id             = -1,
+};
+
 /**
  * ep93xx_register_fb - Register the framebuffer platform device.
  * @data:      platform specific framebuffer configuration (__initdata)
@@ -628,6 +671,7 @@ void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
 {
        ep93xxfb_data = *data;
        platform_device_register(&ep93xx_fb_device);
+       platform_device_register(&ep93xx_bl_device);
 }
 
 
@@ -714,6 +758,73 @@ void ep93xx_keypad_release_gpio(struct platform_device *pdev)
 }
 EXPORT_SYMBOL(ep93xx_keypad_release_gpio);
 
+/*************************************************************************
+ * EP93xx I2S audio peripheral handling
+ *************************************************************************/
+static struct resource ep93xx_i2s_resource[] = {
+       {
+               .start  = EP93XX_I2S_PHYS_BASE,
+               .end    = EP93XX_I2S_PHYS_BASE + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device ep93xx_i2s_device = {
+       .name           = "ep93xx-i2s",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(ep93xx_i2s_resource),
+       .resource       = ep93xx_i2s_resource,
+};
+
+void __init ep93xx_register_i2s(void)
+{
+       platform_device_register(&ep93xx_i2s_device);
+}
+
+#define EP93XX_SYSCON_DEVCFG_I2S_MASK  (EP93XX_SYSCON_DEVCFG_I2SONSSP | \
+                                        EP93XX_SYSCON_DEVCFG_I2SONAC97)
+
+#define EP93XX_I2SCLKDIV_MASK          (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \
+                                        EP93XX_SYSCON_I2SCLKDIV_SPOL)
+
+int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config)
+{
+       unsigned val;
+
+       /* Sanity check */
+       if (i2s_pins & ~EP93XX_SYSCON_DEVCFG_I2S_MASK)
+               return -EINVAL;
+       if (i2s_config & ~EP93XX_I2SCLKDIV_MASK)
+               return -EINVAL;
+
+       /* Must have only one of I2SONSSP/I2SONAC97 set */
+       if ((i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONSSP) ==
+           (i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONAC97))
+               return -EINVAL;
+
+       ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
+       ep93xx_devcfg_set_bits(i2s_pins);
+
+       /*
+        * This is potentially racy with the clock api for i2s_mclk, sclk and 
+        * lrclk. Since the i2s driver is the only user of those clocks we
+        * rely on it to prevent parallel use of this function and the 
+        * clock api for the i2s clocks.
+        */
+       val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
+       val &= ~EP93XX_I2SCLKDIV_MASK;
+       val |= i2s_config;
+       ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV);
+
+       return 0;
+}
+EXPORT_SYMBOL(ep93xx_i2s_acquire);
+
+void ep93xx_i2s_release(void)
+{
+       ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
+}
+EXPORT_SYMBOL(ep93xx_i2s_release);
 
 extern void ep93xx_gpio_init(void);