]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - arch/sh/boards/mach-se/7724/setup.c
sh: ms7724: Add tiny-document for sound
[linux-2.6.git] / arch / sh / boards / mach-se / 7724 / setup.c
index 8fed45a2fb8550dd4cf09f3f8844269194d613cd..ccaa290e9aba1cb29222cde90819cecb2f246cc6 100644 (file)
 #include <linux/smc91x.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/usb/r8a66597.h>
 #include <video/sh_mobile_lcdc.h>
 #include <media/sh_mobile_ceu.h>
+#include <sound/sh_fsi.h>
 #include <asm/io.h>
 #include <asm/heartbeat.h>
 #include <asm/sh_eth.h>
 #include <asm/clock.h>
-#include <asm/sh_keysc.h>
+#include <asm/suspend.h>
 #include <cpu/sh7724.h>
 #include <mach-se/mach/se7724.h>
 
  * SW41 : abxx xxxx  -> a = 0 : Analog  monitor
  *                          1 : Digital monitor
  *                      b = 0 : VGA
- *                          1 : SVGA
+ *                          1 : 720p
  */
 
-/* Heartbeat */
-static struct heartbeat_data heartbeat_data = {
-       .regsize = 16,
-};
+/*
+ * about 720p
+ *
+ * When you use 1280 x 720 lcdc output,
+ * you should change OSC6 lcdc clock from 25.175MHz to 74.25MHz,
+ * and change SW41 to use 720p
+ */
 
-static struct resource heartbeat_resources[] = {
-       [0] = {
-               .start  = PA_LED,
-               .end    = PA_LED,
-               .flags  = IORESOURCE_MEM,
-       },
+/*
+ * about sound
+ *
+ * This setup.c supports FSI slave mode.
+ * Please change J20, J21, J22 pin to 1-2 connection.
+ */
+
+/* Heartbeat */
+static struct resource heartbeat_resource = {
+       .start  = PA_LED,
+       .end    = PA_LED,
+       .flags  = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
 };
 
 static struct platform_device heartbeat_device = {
        .name           = "heartbeat",
        .id             = -1,
-       .dev = {
-               .platform_data = &heartbeat_data,
-       },
-       .num_resources  = ARRAY_SIZE(heartbeat_resources),
-       .resource       = heartbeat_resources,
+       .num_resources  = 1,
+       .resource       = &heartbeat_resource,
 };
 
 /* LAN91C111 */
@@ -158,7 +166,7 @@ static struct resource lcdc_resources[] = {
        [0] = {
                .name   = "LCDC",
                .start  = 0xfe940000,
-               .end    = 0xfe941fff,
+               .end    = 0xfe942fff,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -174,6 +182,9 @@ static struct platform_device lcdc_device = {
        .dev            = {
                .platform_data  = &lcdc_info,
        },
+       .archdata = {
+               .hwblk_id = HWBLK_LCDC,
+       },
 };
 
 /* CEU0 */
@@ -205,6 +216,9 @@ static struct platform_device ceu0_device = {
        .dev    = {
                .platform_data  = &sh_mobile_ceu0_info,
        },
+       .archdata = {
+               .hwblk_id = HWBLK_CEU0,
+       },
 };
 
 /* CEU1 */
@@ -236,12 +250,78 @@ static struct platform_device ceu1_device = {
        .dev    = {
                .platform_data  = &sh_mobile_ceu1_info,
        },
+       .archdata = {
+               .hwblk_id = HWBLK_CEU1,
+       },
+};
+
+/* FSI */
+/*
+ * FSI-A use external clock which came from ak464x.
+ * So, we should change parent of fsi
+ */
+#define FCLKACR                0xa4150008
+static void fsimck_init(struct clk *clk)
+{
+       u32 status = __raw_readl(clk->enable_reg);
+
+       /* use external clock */
+       status &= ~0x000000ff;
+       status |= 0x00000080;
+       __raw_writel(status, clk->enable_reg);
+}
+
+static struct clk_ops fsimck_clk_ops = {
+       .init = fsimck_init,
+};
+
+static struct clk fsimcka_clk = {
+       .name           = "fsimcka_clk",
+       .id             = -1,
+       .ops            = &fsimck_clk_ops,
+       .enable_reg     = (void __iomem *)FCLKACR,
+       .rate           = 0, /* unknown */
+};
+
+/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
+struct sh_fsi_platform_info fsi_info = {
+       .porta_flags = SH_FSI_BRS_INV |
+                      SH_FSI_OUT_SLAVE_MODE |
+                      SH_FSI_IN_SLAVE_MODE |
+                      SH_FSI_OFMT(PCM) |
+                      SH_FSI_IFMT(PCM),
+};
+
+static struct resource fsi_resources[] = {
+       [0] = {
+               .name   = "FSI",
+               .start  = 0xFE3C0000,
+               .end    = 0xFE3C021d,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 108,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device fsi_device = {
+       .name           = "sh_fsi",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(fsi_resources),
+       .resource       = fsi_resources,
+       .dev    = {
+               .platform_data  = &fsi_info,
+       },
+       .archdata = {
+               .hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */
+       },
 };
 
-/* KEYSC */
+/* KEYSC in SoC (Needs SW33-2 set to ON) */
 static struct sh_keysc_info keysc_info = {
        .mode = SH_KEYSC_MODE_1,
-       .scan_timing = 10,
+       .scan_timing = 3,
        .delay = 50,
        .keycodes = {
                KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
@@ -255,12 +335,13 @@ static struct sh_keysc_info keysc_info = {
 
 static struct resource keysc_resources[] = {
        [0] = {
-               .start  = 0x1a204000,
-               .end    = 0x1a20400f,
+               .name   = "KEYSC",
+               .start  = 0x044b0000,
+               .end    = 0x044b000f,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = IRQ0_KEY,
+               .start  = 79,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -273,6 +354,9 @@ static struct platform_device keysc_device = {
        .dev    = {
                .platform_data  = &keysc_info,
        },
+       .archdata = {
+               .hwblk_id = HWBLK_KEYSC,
+       },
 };
 
 /* SH Eth */
@@ -301,15 +385,19 @@ static struct platform_device sh_eth_device = {
        },
        .num_resources = ARRAY_SIZE(sh_eth_resources),
        .resource = sh_eth_resources,
+       .archdata = {
+               .hwblk_id = HWBLK_ETHER,
+       },
 };
 
 static struct r8a66597_platdata sh7724_usb0_host_data = {
+       .on_chip = 1,
 };
 
 static struct resource sh7724_usb0_host_resources[] = {
        [0] = {
                .start  = 0xa4d80000,
-               .end    = 0xa4d800ff,
+               .end    = 0xa4d80124 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -329,6 +417,104 @@ static struct platform_device sh7724_usb0_host_device = {
        },
        .num_resources  = ARRAY_SIZE(sh7724_usb0_host_resources),
        .resource       = sh7724_usb0_host_resources,
+       .archdata = {
+               .hwblk_id = HWBLK_USB0,
+       },
+};
+
+static struct r8a66597_platdata sh7724_usb1_gadget_data = {
+       .on_chip = 1,
+};
+
+static struct resource sh7724_usb1_gadget_resources[] = {
+       [0] = {
+               .start  = 0xa4d90000,
+               .end    = 0xa4d90123,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 66,
+               .end    = 66,
+               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+       },
+};
+
+static struct platform_device sh7724_usb1_gadget_device = {
+       .name           = "r8a66597_udc",
+       .id             = 1, /* USB1 */
+       .dev = {
+               .dma_mask               = NULL,         /*  not use dma */
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &sh7724_usb1_gadget_data,
+       },
+       .num_resources  = ARRAY_SIZE(sh7724_usb1_gadget_resources),
+       .resource       = sh7724_usb1_gadget_resources,
+};
+
+static struct resource sdhi0_cn7_resources[] = {
+       [0] = {
+               .name   = "SDHI0",
+               .start  = 0x04ce0000,
+               .end    = 0x04ce01ff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 100,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device sdhi0_cn7_device = {
+       .name           = "sh_mobile_sdhi",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(sdhi0_cn7_resources),
+       .resource       = sdhi0_cn7_resources,
+       .archdata = {
+               .hwblk_id = HWBLK_SDHI0,
+       },
+};
+
+static struct resource sdhi1_cn8_resources[] = {
+       [0] = {
+               .name   = "SDHI1",
+               .start  = 0x04cf0000,
+               .end    = 0x04cf01ff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 23,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device sdhi1_cn8_device = {
+       .name           = "sh_mobile_sdhi",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(sdhi1_cn8_resources),
+       .resource       = sdhi1_cn8_resources,
+       .archdata = {
+               .hwblk_id = HWBLK_SDHI1,
+       },
+};
+
+/* IrDA */
+static struct resource irda_resources[] = {
+       [0] = {
+               .name   = "IrDA",
+               .start  = 0xA45D0000,
+               .end    = 0xA45D0049,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 20,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device irda_device = {
+       .name           = "sh_sir",
+       .num_resources  = ARRAY_SIZE(irda_resources),
+       .resource       = irda_resources,
 };
 
 static struct platform_device *ms7724se_devices[] __initdata = {
@@ -341,6 +527,18 @@ static struct platform_device *ms7724se_devices[] __initdata = {
        &keysc_device,
        &sh_eth_device,
        &sh7724_usb0_host_device,
+       &sh7724_usb1_gadget_device,
+       &fsi_device,
+       &sdhi0_cn7_device,
+       &sdhi1_cn8_device,
+       &irda_device,
+};
+
+/* I2C device */
+static struct i2c_board_info i2c0_devices[] = {
+       {
+               I2C_BOARD_INFO("ak4642", 0x12),
+       },
 };
 
 #define EEPROM_OP   0xBA206000
@@ -353,9 +551,9 @@ static int __init sh_eth_is_eeprom_ready(void)
        int t = 10000;
 
        while (t--) {
-               if (!ctrl_inw(EEPROM_STAT))
+               if (!__raw_readw(EEPROM_STAT))
                        return 1;
-               cpu_relax();
+               udelay(1);
        }
 
        printk(KERN_ERR "ms7724se can not access to eeprom\n");
@@ -365,7 +563,7 @@ static int __init sh_eth_is_eeprom_ready(void)
 static void __init sh_eth_init(void)
 {
        int i;
-       u16 mac[3];
+       u16 mac;
 
        /* check EEPROM status */
        if (!sh_eth_is_eeprom_ready())
@@ -373,22 +571,16 @@ static void __init sh_eth_init(void)
 
        /* read MAC addr from EEPROM */
        for (i = 0 ; i < 3 ; i++) {
-               ctrl_outw(0x0, EEPROM_OP); /* read */
-               ctrl_outw(i*2, EEPROM_ADR);
-               ctrl_outw(0x1, EEPROM_STRT);
+               __raw_writew(0x0, EEPROM_OP); /* read */
+               __raw_writew(i*2, EEPROM_ADR);
+               __raw_writew(0x1, EEPROM_STRT);
                if (!sh_eth_is_eeprom_ready())
                        return;
 
-               mac[i] = ctrl_inw(EEPROM_DATA);
-               mac[i] = ((mac[i] & 0xFF) << 8) | (mac[i] >> 8); /* swap */
+               mac = __raw_readw(EEPROM_DATA);
+               sh_eth_plat.mac_addr[i << 1] = mac & 0xff;
+               sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8;
        }
-
-       /* reset sh-eth */
-       ctrl_outl(0x1, SH_ETH_ADDR + 0x0);
-
-       /* set MAC addr */
-       ctrl_outl(((mac[0] << 16) | (mac[1])), SH_ETH_MAHR);
-       ctrl_outl((mac[2]), SH_ETH_MALR);
 }
 
 #define SW4140    0xBA201000
@@ -405,23 +597,60 @@ static void __init sh_eth_init(void)
 #define SW41_G    0x4000
 #define SW41_H    0x8000
 
-static int __init devices_setup(void)
+extern char ms7724se_sdram_enter_start;
+extern char ms7724se_sdram_enter_end;
+extern char ms7724se_sdram_leave_start;
+extern char ms7724se_sdram_leave_end;
+
+
+static int __init arch_setup(void)
 {
-       u16 sw = ctrl_inw(SW4140); /* select camera, monitor */
+       /* enable I2C device */
+       i2c_register_board_info(0, i2c0_devices,
+                               ARRAY_SIZE(i2c0_devices));
+       return 0;
+}
+arch_initcall(arch_setup);
 
+static int __init devices_setup(void)
+{
+       u16 sw = __raw_readw(SW4140); /* select camera, monitor */
+       struct clk *clk;
+
+       /* register board specific self-refresh code */
+       sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+                                       SUSP_SH_RSTANDBY,
+                                       &ms7724se_sdram_enter_start,
+                                       &ms7724se_sdram_enter_end,
+                                       &ms7724se_sdram_leave_start,
+                                       &ms7724se_sdram_leave_end);
        /* Reset Release */
-       ctrl_outw(ctrl_inw(FPGA_OUT) &
+       __raw_writew(__raw_readw(FPGA_OUT) &
                  ~((1 << 1)  | /* LAN */
                    (1 << 6)  | /* VIDEO DAC */
+                   (1 << 7)  | /* AK4643 */
+                   (1 << 8)  | /* IrDA */
                    (1 << 12) | /* USB0 */
                    (1 << 14)), /* RMII */
                  FPGA_OUT);
 
        /* turn on USB clocks, use external clock */
-       ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+       __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+
+       /* Let LED9 show STATUS2 */
+       gpio_request(GPIO_FN_STATUS2, NULL);
+
+       /* Lit LED10 show STATUS0 */
+       gpio_request(GPIO_FN_STATUS0, NULL);
+
+       /* Lit LED11 show PDSTATUS */
+       gpio_request(GPIO_FN_PDSTATUS, NULL);
 
        /* enable USB0 port */
-       ctrl_outw(0x0600, 0xa40501d4);
+       __raw_writew(0x0600, 0xa40501d4);
+
+       /* enable USB1 port */
+       __raw_writew(0x0600, 0xa4050192);
 
        /* enable IRQ 0,1,2 */
        gpio_request(GPIO_FN_INTC_IRQ0, NULL);
@@ -469,7 +698,7 @@ static int __init devices_setup(void)
        gpio_request(GPIO_FN_LCDVCPWC, NULL);
        gpio_request(GPIO_FN_LCDRD,    NULL);
        gpio_request(GPIO_FN_LCDLCLK,  NULL);
-       ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+       __raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);
 
        /* enable CEU0 */
        gpio_request(GPIO_FN_VIO0_D15, NULL);
@@ -522,6 +751,61 @@ static int __init devices_setup(void)
        gpio_request(GPIO_FN_KEYOUT1,     NULL);
        gpio_request(GPIO_FN_KEYOUT0,     NULL);
 
+       /* enable FSI */
+       gpio_request(GPIO_FN_FSIMCKB,    NULL);
+       gpio_request(GPIO_FN_FSIMCKA,    NULL);
+       gpio_request(GPIO_FN_FSIOASD,    NULL);
+       gpio_request(GPIO_FN_FSIIABCK,   NULL);
+       gpio_request(GPIO_FN_FSIIALRCK,  NULL);
+       gpio_request(GPIO_FN_FSIOABCK,   NULL);
+       gpio_request(GPIO_FN_FSIOALRCK,  NULL);
+       gpio_request(GPIO_FN_CLKAUDIOAO, NULL);
+       gpio_request(GPIO_FN_FSIIBSD,    NULL);
+       gpio_request(GPIO_FN_FSIOBSD,    NULL);
+       gpio_request(GPIO_FN_FSIIBBCK,   NULL);
+       gpio_request(GPIO_FN_FSIIBLRCK,  NULL);
+       gpio_request(GPIO_FN_FSIOBBCK,   NULL);
+       gpio_request(GPIO_FN_FSIOBLRCK,  NULL);
+       gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
+       gpio_request(GPIO_FN_FSIIASD,    NULL);
+
+       /* set SPU2 clock to 83.4 MHz */
+       clk = clk_get(NULL, "spu_clk");
+       clk_set_rate(clk, clk_round_rate(clk, 83333333));
+       clk_put(clk);
+
+       /* change parent of FSI A */
+       clk = clk_get(NULL, "fsia_clk");
+       clk_register(&fsimcka_clk);
+       clk_set_parent(clk, &fsimcka_clk);
+       clk_set_rate(clk, 11000);
+       clk_set_rate(&fsimcka_clk, 11000);
+       clk_put(clk);
+
+       /* SDHI0 connected to cn7 */
+       gpio_request(GPIO_FN_SDHI0CD, NULL);
+       gpio_request(GPIO_FN_SDHI0WP, NULL);
+       gpio_request(GPIO_FN_SDHI0D3, NULL);
+       gpio_request(GPIO_FN_SDHI0D2, NULL);
+       gpio_request(GPIO_FN_SDHI0D1, NULL);
+       gpio_request(GPIO_FN_SDHI0D0, NULL);
+       gpio_request(GPIO_FN_SDHI0CMD, NULL);
+       gpio_request(GPIO_FN_SDHI0CLK, NULL);
+
+       /* SDHI1 connected to cn8 */
+       gpio_request(GPIO_FN_SDHI1CD, NULL);
+       gpio_request(GPIO_FN_SDHI1WP, NULL);
+       gpio_request(GPIO_FN_SDHI1D3, NULL);
+       gpio_request(GPIO_FN_SDHI1D2, NULL);
+       gpio_request(GPIO_FN_SDHI1D1, NULL);
+       gpio_request(GPIO_FN_SDHI1D0, NULL);
+       gpio_request(GPIO_FN_SDHI1CMD, NULL);
+       gpio_request(GPIO_FN_SDHI1CLK, NULL);
+
+       /* enable IrDA */
+       gpio_request(GPIO_FN_IRDA_OUT, NULL);
+       gpio_request(GPIO_FN_IRDA_IN,  NULL);
+
        /*
         * enable SH-Eth
         *
@@ -545,15 +829,15 @@ static int __init devices_setup(void)
        sh_eth_init();
 
        if (sw & SW41_B) {
-               /* SVGA */
-               lcdc_info.ch[0].lcd_cfg.xres         = 800;
-               lcdc_info.ch[0].lcd_cfg.yres         = 600;
-               lcdc_info.ch[0].lcd_cfg.left_margin  = 142;
-               lcdc_info.ch[0].lcd_cfg.right_margin = 52;
-               lcdc_info.ch[0].lcd_cfg.hsync_len    = 96;
-               lcdc_info.ch[0].lcd_cfg.upper_margin = 24;
-               lcdc_info.ch[0].lcd_cfg.lower_margin = 2;
-               lcdc_info.ch[0].lcd_cfg.vsync_len    = 2;
+               /* 720p */
+               lcdc_info.ch[0].lcd_cfg.xres         = 1280;
+               lcdc_info.ch[0].lcd_cfg.yres         = 720;
+               lcdc_info.ch[0].lcd_cfg.left_margin  = 220;
+               lcdc_info.ch[0].lcd_cfg.right_margin = 110;
+               lcdc_info.ch[0].lcd_cfg.hsync_len    = 40;
+               lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
+               lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
+               lcdc_info.ch[0].lcd_cfg.vsync_len    = 5;
        } else {
                /* VGA */
                lcdc_info.ch[0].lcd_cfg.xres         = 640;