#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 */
[0] = {
.name = "LCDC",
.start = 0xfe940000,
- .end = 0xfe941fff,
+ .end = 0xfe942fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.dev = {
.platform_data = &lcdc_info,
},
+ .archdata = {
+ .hwblk_id = HWBLK_LCDC,
+ },
};
/* CEU0 */
.dev = {
.platform_data = &sh_mobile_ceu0_info,
},
+ .archdata = {
+ .hwblk_id = HWBLK_CEU0,
+ },
};
/* CEU1 */
.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,
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,
},
};
.dev = {
.platform_data = &keysc_info,
},
+ .archdata = {
+ .hwblk_id = HWBLK_KEYSC,
+ },
};
/* SH Eth */
},
.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] = {
},
.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 = {
&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
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");
static void __init sh_eth_init(void)
{
int i;
- u16 mac[3];
+ u16 mac;
/* check EEPROM status */
if (!sh_eth_is_eeprom_ready())
/* 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
#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);
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);
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
*
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;