2 * Renesas System Solutions Asia Pte. Ltd - Migo-R
4 * Copyright (C) 2008 Magnus Damm
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
10 #include <linux/init.h>
11 #include <linux/platform_device.h>
12 #include <linux/interrupt.h>
13 #include <linux/input.h>
14 #include <linux/mtd/physmap.h>
15 #include <linux/mtd/nand.h>
16 #include <linux/i2c.h>
17 #include <linux/smc91x.h>
18 #include <linux/delay.h>
19 #include <linux/clk.h>
20 #include <linux/gpio.h>
21 #include <media/soc_camera_platform.h>
22 #include <media/sh_mobile_ceu.h>
23 #include <video/sh_mobile_lcdc.h>
24 #include <asm/clock.h>
25 #include <asm/machvec.h>
27 #include <asm/sh_keysc.h>
28 #include <mach/migor.h>
29 #include <cpu/sh7722.h>
31 /* Address IRQ Size Bus Description
32 * 0x00000000 64MB 16 NOR Flash (SP29PL256N)
33 * 0x0c000000 64MB 64 SDRAM (2xK4M563233G)
34 * 0x10000000 IRQ0 16 Ethernet (SMC91C111)
35 * 0x14000000 IRQ4 16 USB 2.0 Host Controller (M66596)
36 * 0x18000000 8GB 8 NAND Flash (K9K8G08U0A)
39 static struct smc91x_platdata smc91x_info = {
40 .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
43 static struct resource smc91x_eth_resources[] = {
48 .flags = IORESOURCE_MEM,
51 .start = 32, /* IRQ0 */
52 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
56 static struct platform_device smc91x_eth_device = {
58 .num_resources = ARRAY_SIZE(smc91x_eth_resources),
59 .resource = smc91x_eth_resources,
61 .platform_data = &smc91x_info,
65 static struct sh_keysc_info sh_keysc_info = {
66 .mode = SH_KEYSC_MODE_2, /* KEYOUT0->4, KEYIN1->5 */
70 0, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER,
71 0, KEY_F, KEY_C, KEY_D, KEY_H, KEY_1,
72 0, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
73 0, KEY_7, KEY_8, KEY_9, KEY_S, KEY_0,
74 0, KEY_P, KEY_STOP, KEY_REWIND, KEY_PLAY, KEY_FASTFORWARD,
78 static struct resource sh_keysc_resources[] = {
82 .flags = IORESOURCE_MEM,
86 .flags = IORESOURCE_IRQ,
90 static struct platform_device sh_keysc_device = {
92 .num_resources = ARRAY_SIZE(sh_keysc_resources),
93 .resource = sh_keysc_resources,
95 .platform_data = &sh_keysc_info,
99 static struct mtd_partition migor_nor_flash_partitions[] =
104 .size = (1 * 1024 * 1024),
105 .mask_flags = MTD_WRITEABLE, /* Read-only */
109 .offset = MTDPART_OFS_APPEND,
110 .size = (15 * 1024 * 1024),
114 .offset = MTDPART_OFS_APPEND,
115 .size = MTDPART_SIZ_FULL,
119 static struct physmap_flash_data migor_nor_flash_data = {
121 .parts = migor_nor_flash_partitions,
122 .nr_parts = ARRAY_SIZE(migor_nor_flash_partitions),
125 static struct resource migor_nor_flash_resources[] = {
130 .flags = IORESOURCE_MEM,
134 static struct platform_device migor_nor_flash_device = {
135 .name = "physmap-flash",
136 .resource = migor_nor_flash_resources,
137 .num_resources = ARRAY_SIZE(migor_nor_flash_resources),
139 .platform_data = &migor_nor_flash_data,
143 static struct mtd_partition migor_nand_flash_partitions[] = {
147 .size = 512 * 1024 * 1024,
151 .offset = MTDPART_OFS_APPEND,
152 .size = 512 * 1024 * 1024,
156 static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd,
159 struct nand_chip *chip = mtd->priv;
161 if (cmd == NAND_CMD_NONE)
165 writeb(cmd, chip->IO_ADDR_W + 0x00400000);
166 else if (ctrl & NAND_ALE)
167 writeb(cmd, chip->IO_ADDR_W + 0x00800000);
169 writeb(cmd, chip->IO_ADDR_W);
172 static int migor_nand_flash_ready(struct mtd_info *mtd)
174 return gpio_get_value(GPIO_PTA1); /* NAND_RBn */
177 struct platform_nand_data migor_nand_flash_data = {
180 .partitions = migor_nand_flash_partitions,
181 .nr_partitions = ARRAY_SIZE(migor_nand_flash_partitions),
183 .part_probe_types = (const char *[]) { "cmdlinepart", NULL },
186 .dev_ready = migor_nand_flash_ready,
187 .cmd_ctrl = migor_nand_flash_cmd_ctl,
191 static struct resource migor_nand_flash_resources[] = {
193 .name = "NAND Flash",
196 .flags = IORESOURCE_MEM,
200 static struct platform_device migor_nand_flash_device = {
202 .resource = migor_nand_flash_resources,
203 .num_resources = ARRAY_SIZE(migor_nand_flash_resources),
205 .platform_data = &migor_nand_flash_data,
209 static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
210 #ifdef CONFIG_SH_MIGOR_RTA_WVGA
211 .clock_source = LCDC_CLK_BUS,
213 .chan = LCDC_CHAN_MAINLCD,
215 .interface_type = RGB16,
229 .lcd_size_cfg = { /* 7.0 inch */
235 #ifdef CONFIG_SH_MIGOR_QVGA
236 .clock_source = LCDC_CLK_PERIPHERAL,
238 .chan = LCDC_CHAN_MAINLCD,
240 .interface_type = SYS16A,
252 .sync = FB_SYNC_HOR_HIGH_ACT,
254 .lcd_size_cfg = { /* 2.4 inch */
259 .setup_sys = migor_lcd_qvga_setup,
262 .ldmt2r = 0x06000a09,
263 .ldmt3r = 0x180e3418,
269 static struct resource migor_lcdc_resources[] = {
272 .start = 0xfe940000, /* P4-only space */
274 .flags = IORESOURCE_MEM,
278 static struct platform_device migor_lcdc_device = {
279 .name = "sh_mobile_lcdc_fb",
280 .num_resources = ARRAY_SIZE(migor_lcdc_resources),
281 .resource = migor_lcdc_resources,
283 .platform_data = &sh_mobile_lcdc_info,
287 static struct clk *camera_clk;
289 static void camera_power_on(void)
291 /* Use 10 MHz VIO_CKO instead of 24 MHz to work
292 * around signal quality issues on Panel Board V2.1.
294 camera_clk = clk_get(NULL, "video_clk");
295 clk_set_rate(camera_clk, 10000000);
296 clk_enable(camera_clk); /* start VIO_CKO */
298 /* use VIO_RST to take camera out of reset */
300 gpio_set_value(GPIO_PTT3, 0);
302 gpio_set_value(GPIO_PTT3, 1);
305 static void camera_power_off(void)
307 clk_disable(camera_clk); /* stop VIO_CKO */
310 gpio_set_value(GPIO_PTT3, 0);
313 static void camera_power(int mode)
322 static unsigned char camera_ov772x_magic[] =
324 0x09, 0x01, 0x0c, 0x20, 0x0d, 0x41, 0x0e, 0x01,
325 0x12, 0x00, 0x13, 0x8F, 0x14, 0x4A, 0x15, 0x00,
326 0x16, 0x00, 0x17, 0x23, 0x18, 0xa0, 0x19, 0x07,
327 0x1a, 0xf0, 0x1b, 0x40, 0x1f, 0x00, 0x20, 0x10,
328 0x22, 0xff, 0x23, 0x01, 0x28, 0x00, 0x29, 0xa0,
329 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0xf0, 0x2d, 0x00,
330 0x2e, 0x00, 0x30, 0x80, 0x31, 0x60, 0x32, 0x00,
331 0x33, 0x00, 0x34, 0x00, 0x3d, 0x80, 0x3e, 0xe2,
332 0x3f, 0x1f, 0x42, 0x80, 0x43, 0x80, 0x44, 0x80,
333 0x45, 0x80, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00,
334 0x49, 0x50, 0x4a, 0x30, 0x4b, 0x50, 0x4c, 0x50,
335 0x4d, 0x00, 0x4e, 0xef, 0x4f, 0x10, 0x50, 0x60,
336 0x51, 0x00, 0x52, 0x00, 0x53, 0x24, 0x54, 0x7a,
337 0x55, 0xfc, 0x62, 0xff, 0x63, 0xf0, 0x64, 0x1f,
338 0x65, 0x00, 0x66, 0x10, 0x67, 0x00, 0x68, 0x00,
339 0x69, 0x5c, 0x6a, 0x11, 0x6b, 0xa2, 0x6c, 0x01,
340 0x6d, 0x50, 0x6e, 0x80, 0x6f, 0x80, 0x70, 0x0f,
341 0x71, 0x00, 0x72, 0x00, 0x73, 0x0f, 0x74, 0x0f,
342 0x75, 0xff, 0x78, 0x10, 0x79, 0x70, 0x7a, 0x70,
343 0x7b, 0xf0, 0x7c, 0xf0, 0x7d, 0xf0, 0x7e, 0x0e,
344 0x7f, 0x1a, 0x80, 0x31, 0x81, 0x5a, 0x82, 0x69,
345 0x83, 0x75, 0x84, 0x7e, 0x85, 0x88, 0x86, 0x8f,
346 0x87, 0x96, 0x88, 0xa3, 0x89, 0xaf, 0x8a, 0xc4,
347 0x8b, 0xd7, 0x8c, 0xe8, 0x8d, 0x20, 0x8e, 0x00,
348 0x8f, 0x00, 0x90, 0x08, 0x91, 0x10, 0x92, 0x1f,
349 0x93, 0x01, 0x94, 0x2c, 0x95, 0x24, 0x96, 0x08,
350 0x97, 0x14, 0x98, 0x24, 0x99, 0x38, 0x9a, 0x9e,
351 0x9b, 0x00, 0x9c, 0x40, 0x9e, 0x11, 0x9f, 0x02,
352 0xa0, 0x00, 0xa1, 0x40, 0xa2, 0x40, 0xa3, 0x06,
353 0xa4, 0x00, 0xa6, 0x00, 0xa7, 0x40, 0xa8, 0x40,
354 0xa9, 0x80, 0xaa, 0x80, 0xab, 0x06, 0xac, 0xff,
355 0x12, 0x06, 0x64, 0x3f, 0x12, 0x46, 0x17, 0x3f,
356 0x18, 0x50, 0x19, 0x03, 0x1a, 0x78, 0x29, 0x50,
360 static int ov772x_set_capture(struct soc_camera_platform_info *info,
363 struct i2c_adapter *a = i2c_get_adapter(0);
369 return 0; /* camera_power_off() is enough */
371 for (i = 0; i < ARRAY_SIZE(camera_ov772x_magic); i += 2) {
379 buf[0] = camera_ov772x_magic[i];
380 buf[1] = camera_ov772x_magic[i + 1];
382 ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
388 static struct soc_camera_platform_info ov772x_info = {
390 .format_name = "RGB565",
393 .pixelformat = V4L2_PIX_FMT_RGB565,
394 .colorspace = V4L2_COLORSPACE_SRGB,
398 .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
399 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
400 .power = camera_power,
401 .set_capture = ov772x_set_capture,
404 static struct platform_device migor_camera_device = {
405 .name = "soc_camera_platform",
407 .platform_data = &ov772x_info,
410 #endif /* CONFIG_I2C */
412 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
413 .flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING \
414 | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH,
417 static struct resource migor_ceu_resources[] = {
422 .flags = IORESOURCE_MEM,
426 .flags = IORESOURCE_IRQ,
429 /* place holder for contiguous memory */
433 static struct platform_device migor_ceu_device = {
434 .name = "sh_mobile_ceu",
435 .num_resources = ARRAY_SIZE(migor_ceu_resources),
436 .resource = migor_ceu_resources,
438 .platform_data = &sh_mobile_ceu_info,
442 static struct platform_device *migor_devices[] __initdata = {
448 &migor_camera_device,
450 &migor_nor_flash_device,
451 &migor_nand_flash_device,
454 static struct i2c_board_info migor_i2c_devices[] = {
456 I2C_BOARD_INFO("rs5c372b", 0x32),
459 I2C_BOARD_INFO("migor_ts", 0x51),
460 .irq = 38, /* IRQ6 */
464 static int __init migor_devices_setup(void)
467 gpio_request(GPIO_PTJ7, NULL);
468 gpio_direction_output(GPIO_PTJ7, 1);
469 gpio_export(GPIO_PTJ7, 0);
472 gpio_request(GPIO_PTJ5, NULL);
473 gpio_direction_output(GPIO_PTJ5, 1);
474 gpio_export(GPIO_PTJ5, 0);
476 /* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */
477 gpio_request(GPIO_FN_IRQ0, NULL);
478 ctrl_outl(0x00003400, BSC_CS4BCR);
479 ctrl_outl(0x00110080, BSC_CS4WCR);
482 clk_always_enable("mstp214"); /* KEYSC */
483 gpio_request(GPIO_FN_KEYOUT0, NULL);
484 gpio_request(GPIO_FN_KEYOUT1, NULL);
485 gpio_request(GPIO_FN_KEYOUT2, NULL);
486 gpio_request(GPIO_FN_KEYOUT3, NULL);
487 gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
488 gpio_request(GPIO_FN_KEYIN1, NULL);
489 gpio_request(GPIO_FN_KEYIN2, NULL);
490 gpio_request(GPIO_FN_KEYIN3, NULL);
491 gpio_request(GPIO_FN_KEYIN4, NULL);
492 gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
495 gpio_request(GPIO_FN_CS6A_CE2B, NULL);
496 ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR);
497 gpio_request(GPIO_PTA1, NULL);
498 gpio_direction_input(GPIO_PTA1);
501 gpio_request(GPIO_FN_IRQ6, NULL);
504 clk_always_enable("mstp200"); /* LCDC */
505 #ifdef CONFIG_SH_MIGOR_QVGA /* LCDC - QVGA - Enable SYS Interface signals */
506 gpio_request(GPIO_FN_LCDD17, NULL);
507 gpio_request(GPIO_FN_LCDD16, NULL);
508 gpio_request(GPIO_FN_LCDD15, NULL);
509 gpio_request(GPIO_FN_LCDD14, NULL);
510 gpio_request(GPIO_FN_LCDD13, NULL);
511 gpio_request(GPIO_FN_LCDD12, NULL);
512 gpio_request(GPIO_FN_LCDD11, NULL);
513 gpio_request(GPIO_FN_LCDD10, NULL);
514 gpio_request(GPIO_FN_LCDD8, NULL);
515 gpio_request(GPIO_FN_LCDD7, NULL);
516 gpio_request(GPIO_FN_LCDD6, NULL);
517 gpio_request(GPIO_FN_LCDD5, NULL);
518 gpio_request(GPIO_FN_LCDD4, NULL);
519 gpio_request(GPIO_FN_LCDD3, NULL);
520 gpio_request(GPIO_FN_LCDD2, NULL);
521 gpio_request(GPIO_FN_LCDD1, NULL);
522 gpio_request(GPIO_FN_LCDRS, NULL);
523 gpio_request(GPIO_FN_LCDCS, NULL);
524 gpio_request(GPIO_FN_LCDRD, NULL);
525 gpio_request(GPIO_FN_LCDWR, NULL);
526 gpio_request(GPIO_PTH2, NULL); /* LCD_DON */
527 gpio_direction_output(GPIO_PTH2, 1);
529 #ifdef CONFIG_SH_MIGOR_RTA_WVGA /* LCDC - WVGA - Enable RGB Interface signals */
530 gpio_request(GPIO_FN_LCDD15, NULL);
531 gpio_request(GPIO_FN_LCDD14, NULL);
532 gpio_request(GPIO_FN_LCDD13, NULL);
533 gpio_request(GPIO_FN_LCDD12, NULL);
534 gpio_request(GPIO_FN_LCDD11, NULL);
535 gpio_request(GPIO_FN_LCDD10, NULL);
536 gpio_request(GPIO_FN_LCDD9, NULL);
537 gpio_request(GPIO_FN_LCDD8, NULL);
538 gpio_request(GPIO_FN_LCDD7, NULL);
539 gpio_request(GPIO_FN_LCDD6, NULL);
540 gpio_request(GPIO_FN_LCDD5, NULL);
541 gpio_request(GPIO_FN_LCDD4, NULL);
542 gpio_request(GPIO_FN_LCDD3, NULL);
543 gpio_request(GPIO_FN_LCDD2, NULL);
544 gpio_request(GPIO_FN_LCDD1, NULL);
545 gpio_request(GPIO_FN_LCDD0, NULL);
546 gpio_request(GPIO_FN_LCDLCLK, NULL);
547 gpio_request(GPIO_FN_LCDDCK, NULL);
548 gpio_request(GPIO_FN_LCDVEPWC, NULL);
549 gpio_request(GPIO_FN_LCDVCPWC, NULL);
550 gpio_request(GPIO_FN_LCDVSYN, NULL);
551 gpio_request(GPIO_FN_LCDHSYN, NULL);
552 gpio_request(GPIO_FN_LCDDISP, NULL);
553 gpio_request(GPIO_FN_LCDDON, NULL);
557 clk_always_enable("mstp203"); /* CEU */
558 gpio_request(GPIO_FN_VIO_CLK2, NULL);
559 gpio_request(GPIO_FN_VIO_VD2, NULL);
560 gpio_request(GPIO_FN_VIO_HD2, NULL);
561 gpio_request(GPIO_FN_VIO_FLD, NULL);
562 gpio_request(GPIO_FN_VIO_CKO, NULL);
563 gpio_request(GPIO_FN_VIO_D15, NULL);
564 gpio_request(GPIO_FN_VIO_D14, NULL);
565 gpio_request(GPIO_FN_VIO_D13, NULL);
566 gpio_request(GPIO_FN_VIO_D12, NULL);
567 gpio_request(GPIO_FN_VIO_D11, NULL);
568 gpio_request(GPIO_FN_VIO_D10, NULL);
569 gpio_request(GPIO_FN_VIO_D9, NULL);
570 gpio_request(GPIO_FN_VIO_D8, NULL);
572 gpio_request(GPIO_PTT3, NULL); /* VIO_RST */
573 gpio_direction_output(GPIO_PTT3, 0);
574 gpio_request(GPIO_PTT2, NULL); /* TV_IN_EN */
575 gpio_direction_output(GPIO_PTT2, 1);
576 gpio_request(GPIO_PTT0, NULL); /* CAM_EN */
577 #ifdef CONFIG_SH_MIGOR_RTA_WVGA
578 gpio_direction_output(GPIO_PTT0, 0);
580 gpio_direction_output(GPIO_PTT0, 1);
582 ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */
584 platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20);
586 i2c_register_board_info(0, migor_i2c_devices,
587 ARRAY_SIZE(migor_i2c_devices));
589 return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
591 __initcall(migor_devices_setup);
593 static void __init migor_setup(char **cmdline_p)
597 static struct sh_machine_vector mv_migor __initmv = {
599 .mv_setup = migor_setup,