vserver 1.9.5.x5
[linux-2.6.git] / arch / arm / mach-pxa / mainstone.c
index 663c1ee..2e5f1a9 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
+#include <linux/fb.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <asm/arch/pxa-regs.h>
 #include <asm/arch/mainstone.h>
+#include <asm/arch/audio.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/mmc.h>
 
 #include "generic.h"
 
@@ -116,9 +121,169 @@ static struct platform_device smc91x_device = {
        .resource       = smc91x_resources,
 };
 
+static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv)
+{
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
+       return 0;
+}
+
+static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv)
+{
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
+}
+
+static long mst_audio_suspend_mask;
+
+static void mst_audio_suspend(void *priv)
+{
+       mst_audio_suspend_mask = MST_MSCWR2;
+       MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
+}
+
+static void mst_audio_resume(void *priv)
+{
+       MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
+}
+
+static pxa2xx_audio_ops_t mst_audio_ops = {
+       .startup        = mst_audio_startup,
+       .shutdown       = mst_audio_shutdown,
+       .suspend        = mst_audio_suspend,
+       .resume         = mst_audio_resume,
+};
+
+static struct platform_device mst_audio_device = {
+       .name           = "pxa2xx-ac97",
+       .id             = -1,
+       .dev            = { .platform_data = &mst_audio_ops },
+};
+
+static void mainstone_backlight_power(int on)
+{
+       if (on) {
+               pxa_gpio_mode(GPIO16_PWM0_MD);
+               pxa_set_cken(CKEN0_PWM0, 1);
+               PWM_CTRL0 = 0;
+               PWM_PWDUTY0 = 0x3ff;
+               PWM_PERVAL0 = 0x3ff;
+       } else {
+               PWM_CTRL0 = 0;
+               PWM_PWDUTY0 = 0x0;
+               PWM_PERVAL0 = 0x3FF;
+               pxa_set_cken(CKEN0_PWM0, 0);
+       }
+}
+
+static struct pxafb_mach_info toshiba_ltm04c380k __initdata = {
+       .pixclock               = 50000,
+       .xres                   = 640,
+       .yres                   = 480,
+       .bpp                    = 16,
+       .hsync_len              = 1,
+       .left_margin            = 0x9f,
+       .right_margin           = 1,
+       .vsync_len              = 44,
+       .upper_margin           = 0,
+       .lower_margin           = 0,
+       .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+       .lccr0                  = LCCR0_Act,
+       .lccr3                  = LCCR3_PCP,
+       .pxafb_backlight_power  = mainstone_backlight_power,
+};
+
+static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
+       .pixclock               = 110000,
+       .xres                   = 240,
+       .yres                   = 320,
+       .bpp                    = 16,
+       .hsync_len              = 4,
+       .left_margin            = 8,
+       .right_margin           = 20,
+       .vsync_len              = 3,
+       .upper_margin           = 1,
+       .lower_margin           = 10,
+       .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+       .lccr0                  = LCCR0_Act,
+       .lccr3                  = LCCR3_PCP,
+       .pxafb_backlight_power  = mainstone_backlight_power,
+};
+
+static int mainstone_mci_init(struct device *dev, irqreturn_t (*mstone_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+       int err;
+
+       /*
+        * setup GPIO for PXA27x MMC controller
+        */
+       pxa_gpio_mode(GPIO32_MMCCLK_MD);
+       pxa_gpio_mode(GPIO112_MMCCMD_MD);
+       pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+       pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+       pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+       pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+       /* make sure SD/Memory Stick multiplexer's signals
+        * are routed to MMC controller
+        */
+       MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
+
+       err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, SA_INTERRUPT,
+                            "MMC card detect", data);
+       if (err) {
+               printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
+{
+       struct pxamci_platform_data* p_d = dev->platform_data;
+
+       if (( 1 << vdd) & p_d->ocr_mask) {
+               printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
+               MST_MSCWR1 |= MST_MSCWR1_MMC_ON;
+               MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
+       } else {
+               printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
+               MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
+       }
+}
+
+static void mainstone_mci_exit(struct device *dev, void *data)
+{
+       free_irq(MAINSTONE_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data mainstone_mci_platform_data = {
+       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
+       .init           = mainstone_mci_init,
+       .setpower       = mainstone_mci_setpower,
+       .exit           = mainstone_mci_exit,
+};
+
 static void __init mainstone_init(void)
 {
-       platform_add_device(&smc91x_device);
+       /*
+        * On Mainstone, we route AC97_SYSCLK via GPIO45 to
+        * the audio daughter card
+        */
+       pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
+
+       platform_device_register(&smc91x_device);
+       platform_device_register(&mst_audio_device);
+
+       /* reading Mainstone's "Virtual Configuration Register"
+          might be handy to select LCD type here */
+       if (0)
+               set_pxa_fb_info(&toshiba_ltm04c380k);
+       else
+               set_pxa_fb_info(&toshiba_ltm035a776c);
+
+       pxa_set_mci_info(&mainstone_mci_platform_data);
 }
 
 
@@ -137,5 +302,6 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
        BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
        MAPIO(mainstone_map_io)
        INITIRQ(mainstone_init_irq)
+       .timer          = &pxa_timer,
        INIT_MACHINE(mainstone_init)
 MACHINE_END