diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-07-29 08:01:19 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-07-29 08:01:19 -0400 |
commit | da2014a2b080e7f3024a4eb6917d47069ad9620b (patch) | |
tree | cfde12c6d4b5baa222966b14a676f107992cf786 /arch/sh/boards/mach-migor | |
parent | 71b8064e7df5698520d73b4c1566a3dbc98eb9ef (diff) |
sh: Shuffle the board directories in to mach groups.
This flattens out the board directories in to individual mach groups,
we will use this for getting rid of unneeded directories, simplifying
the build system, and becoming more coherent with the refactored
arch/sh/include topology.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/boards/mach-migor')
-rw-r--r-- | arch/sh/boards/mach-migor/Kconfig | 15 | ||||
-rw-r--r-- | arch/sh/boards/mach-migor/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/boards/mach-migor/lcd_qvga.c | 165 | ||||
-rw-r--r-- | arch/sh/boards/mach-migor/setup.c | 523 |
4 files changed, 705 insertions, 0 deletions
diff --git a/arch/sh/boards/mach-migor/Kconfig b/arch/sh/boards/mach-migor/Kconfig new file mode 100644 index 000000000000..a7b3b728ec3c --- /dev/null +++ b/arch/sh/boards/mach-migor/Kconfig | |||
@@ -0,0 +1,15 @@ | |||
1 | if SH_MIGOR | ||
2 | |||
3 | choice | ||
4 | prompt "Migo-R LCD Panel Board Selection" | ||
5 | default SH_MIGOR_QVGA | ||
6 | |||
7 | config SH_MIGOR_QVGA | ||
8 | bool "QVGA (320x240)" | ||
9 | |||
10 | config SH_MIGOR_RTA_WVGA | ||
11 | bool "RTA WVGA (800x480)" | ||
12 | |||
13 | endchoice | ||
14 | |||
15 | endif | ||
diff --git a/arch/sh/boards/mach-migor/Makefile b/arch/sh/boards/mach-migor/Makefile new file mode 100644 index 000000000000..5f231dd25c0e --- /dev/null +++ b/arch/sh/boards/mach-migor/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-y := setup.o | ||
2 | obj-$(CONFIG_SH_MIGOR_QVGA) += lcd_qvga.o | ||
diff --git a/arch/sh/boards/mach-migor/lcd_qvga.c b/arch/sh/boards/mach-migor/lcd_qvga.c new file mode 100644 index 000000000000..6e9609596448 --- /dev/null +++ b/arch/sh/boards/mach-migor/lcd_qvga.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Support for SuperH MigoR Quarter VGA LCD Panel | ||
3 | * | ||
4 | * Copyright (C) 2008 Magnus Damm | ||
5 | * | ||
6 | * Based on lcd_powertip.c from Kenati Technologies Pvt Ltd. | ||
7 | * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>, | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/fb.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <asm/sh_mobile_lcdc.h> | ||
21 | #include <asm/migor.h> | ||
22 | |||
23 | /* LCD Module is a PH240320T according to board schematics. This module | ||
24 | * is made up of a 240x320 LCD hooked up to a R61505U (or HX8347-A01?) | ||
25 | * Driver IC. This IC is connected to the SH7722 built-in LCDC using a | ||
26 | * SYS-80 interface configured in 16 bit mode. | ||
27 | * | ||
28 | * Index 0: "Device Code Read" returns 0x1505. | ||
29 | */ | ||
30 | |||
31 | static void reset_lcd_module(void) | ||
32 | { | ||
33 | ctrl_outb(ctrl_inb(PORT_PHDR) & ~0x04, PORT_PHDR); | ||
34 | mdelay(2); | ||
35 | ctrl_outb(ctrl_inb(PORT_PHDR) | 0x04, PORT_PHDR); | ||
36 | mdelay(1); | ||
37 | } | ||
38 | |||
39 | /* DB0-DB7 are connected to D1-D8, and DB8-DB15 to D10-D17 */ | ||
40 | |||
41 | static unsigned long adjust_reg18(unsigned short data) | ||
42 | { | ||
43 | unsigned long tmp1, tmp2; | ||
44 | |||
45 | tmp1 = (data<<1 | 0x00000001) & 0x000001FF; | ||
46 | tmp2 = (data<<2 | 0x00000200) & 0x0003FE00; | ||
47 | return tmp1 | tmp2; | ||
48 | } | ||
49 | |||
50 | static void write_reg(void *sys_ops_handle, | ||
51 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops, | ||
52 | unsigned short reg, unsigned short data) | ||
53 | { | ||
54 | sys_ops->write_index(sys_ops_handle, adjust_reg18(reg << 8 | data)); | ||
55 | } | ||
56 | |||
57 | static void write_reg16(void *sys_ops_handle, | ||
58 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops, | ||
59 | unsigned short reg, unsigned short data) | ||
60 | { | ||
61 | sys_ops->write_index(sys_ops_handle, adjust_reg18(reg)); | ||
62 | sys_ops->write_data(sys_ops_handle, adjust_reg18(data)); | ||
63 | } | ||
64 | |||
65 | static unsigned long read_reg16(void *sys_ops_handle, | ||
66 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops, | ||
67 | unsigned short reg) | ||
68 | { | ||
69 | unsigned long data; | ||
70 | |||
71 | sys_ops->write_index(sys_ops_handle, adjust_reg18(reg)); | ||
72 | data = sys_ops->read_data(sys_ops_handle); | ||
73 | return ((data >> 1) & 0xff) | ((data >> 2) & 0xff00); | ||
74 | } | ||
75 | |||
76 | static void migor_lcd_qvga_seq(void *sys_ops_handle, | ||
77 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops, | ||
78 | unsigned short const *data, int no_data) | ||
79 | { | ||
80 | int i; | ||
81 | |||
82 | for (i = 0; i < no_data; i += 2) | ||
83 | write_reg16(sys_ops_handle, sys_ops, data[i], data[i + 1]); | ||
84 | } | ||
85 | |||
86 | static const unsigned short sync_data[] = { | ||
87 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
88 | }; | ||
89 | |||
90 | static const unsigned short magic0_data[] = { | ||
91 | 0x0060, 0x2700, 0x0008, 0x0808, 0x0090, 0x001A, 0x0007, 0x0001, | ||
92 | 0x0017, 0x0001, 0x0019, 0x0000, 0x0010, 0x17B0, 0x0011, 0x0116, | ||
93 | 0x0012, 0x0198, 0x0013, 0x1400, 0x0029, 0x000C, 0x0012, 0x01B8, | ||
94 | }; | ||
95 | |||
96 | static const unsigned short magic1_data[] = { | ||
97 | 0x0030, 0x0307, 0x0031, 0x0303, 0x0032, 0x0603, 0x0033, 0x0202, | ||
98 | 0x0034, 0x0202, 0x0035, 0x0202, 0x0036, 0x1F1F, 0x0037, 0x0303, | ||
99 | 0x0038, 0x0303, 0x0039, 0x0603, 0x003A, 0x0202, 0x003B, 0x0102, | ||
100 | 0x003C, 0x0204, 0x003D, 0x0000, 0x0001, 0x0100, 0x0002, 0x0300, | ||
101 | 0x0003, 0x5028, 0x0020, 0x00ef, 0x0021, 0x0000, 0x0004, 0x0000, | ||
102 | 0x0009, 0x0000, 0x000A, 0x0008, 0x000C, 0x0000, 0x000D, 0x0000, | ||
103 | 0x0015, 0x8000, | ||
104 | }; | ||
105 | |||
106 | static const unsigned short magic2_data[] = { | ||
107 | 0x0061, 0x0001, 0x0092, 0x0100, 0x0093, 0x0001, 0x0007, 0x0021, | ||
108 | }; | ||
109 | |||
110 | static const unsigned short magic3_data[] = { | ||
111 | 0x0010, 0x16B0, 0x0011, 0x0111, 0x0007, 0x0061, | ||
112 | }; | ||
113 | |||
114 | int migor_lcd_qvga_setup(void *board_data, void *sohandle, | ||
115 | struct sh_mobile_lcdc_sys_bus_ops *so) | ||
116 | { | ||
117 | unsigned long xres = 320; | ||
118 | unsigned long yres = 240; | ||
119 | int k; | ||
120 | |||
121 | reset_lcd_module(); | ||
122 | migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data)); | ||
123 | |||
124 | if (read_reg16(sohandle, so, 0) != 0x1505) | ||
125 | return -ENODEV; | ||
126 | |||
127 | pr_info("Migo-R QVGA LCD Module detected.\n"); | ||
128 | |||
129 | migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data)); | ||
130 | write_reg16(sohandle, so, 0x00A4, 0x0001); | ||
131 | mdelay(10); | ||
132 | |||
133 | migor_lcd_qvga_seq(sohandle, so, magic0_data, ARRAY_SIZE(magic0_data)); | ||
134 | mdelay(100); | ||
135 | |||
136 | migor_lcd_qvga_seq(sohandle, so, magic1_data, ARRAY_SIZE(magic1_data)); | ||
137 | write_reg16(sohandle, so, 0x0050, 0xef - (yres - 1)); | ||
138 | write_reg16(sohandle, so, 0x0051, 0x00ef); | ||
139 | write_reg16(sohandle, so, 0x0052, 0x0000); | ||
140 | write_reg16(sohandle, so, 0x0053, xres - 1); | ||
141 | |||
142 | migor_lcd_qvga_seq(sohandle, so, magic2_data, ARRAY_SIZE(magic2_data)); | ||
143 | mdelay(10); | ||
144 | |||
145 | migor_lcd_qvga_seq(sohandle, so, magic3_data, ARRAY_SIZE(magic3_data)); | ||
146 | mdelay(40); | ||
147 | |||
148 | /* clear GRAM to avoid displaying garbage */ | ||
149 | |||
150 | write_reg16(sohandle, so, 0x0020, 0x0000); /* horiz addr */ | ||
151 | write_reg16(sohandle, so, 0x0021, 0x0000); /* vert addr */ | ||
152 | |||
153 | for (k = 0; k < (xres * 256); k++) /* yes, 256 words per line */ | ||
154 | write_reg16(sohandle, so, 0x0022, 0x0000); | ||
155 | |||
156 | write_reg16(sohandle, so, 0x0020, 0x0000); /* reset horiz addr */ | ||
157 | write_reg16(sohandle, so, 0x0021, 0x0000); /* reset vert addr */ | ||
158 | write_reg16(sohandle, so, 0x0007, 0x0173); | ||
159 | mdelay(40); | ||
160 | |||
161 | /* enable display */ | ||
162 | write_reg(sohandle, so, 0x00, 0x22); | ||
163 | mdelay(100); | ||
164 | return 0; | ||
165 | } | ||
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c new file mode 100644 index 000000000000..7bd365ad2d06 --- /dev/null +++ b/arch/sh/boards/mach-migor/setup.c | |||
@@ -0,0 +1,523 @@ | |||
1 | /* | ||
2 | * Renesas System Solutions Asia Pte. Ltd - Migo-R | ||
3 | * | ||
4 | * Copyright (C) 2008 Magnus Damm | ||
5 | * | ||
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 | ||
8 | * for more details. | ||
9 | */ | ||
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 <media/soc_camera_platform.h> | ||
21 | #include <media/sh_mobile_ceu.h> | ||
22 | #include <asm/clock.h> | ||
23 | #include <asm/machvec.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/sh_keysc.h> | ||
26 | #include <asm/sh_mobile_lcdc.h> | ||
27 | #include <asm/migor.h> | ||
28 | |||
29 | /* Address IRQ Size Bus Description | ||
30 | * 0x00000000 64MB 16 NOR Flash (SP29PL256N) | ||
31 | * 0x0c000000 64MB 64 SDRAM (2xK4M563233G) | ||
32 | * 0x10000000 IRQ0 16 Ethernet (SMC91C111) | ||
33 | * 0x14000000 IRQ4 16 USB 2.0 Host Controller (M66596) | ||
34 | * 0x18000000 8GB 8 NAND Flash (K9K8G08U0A) | ||
35 | */ | ||
36 | |||
37 | static struct smc91x_platdata smc91x_info = { | ||
38 | .flags = SMC91X_USE_16BIT, | ||
39 | }; | ||
40 | |||
41 | static struct resource smc91x_eth_resources[] = { | ||
42 | [0] = { | ||
43 | .name = "SMC91C111" , | ||
44 | .start = 0x10000300, | ||
45 | .end = 0x1000030f, | ||
46 | .flags = IORESOURCE_MEM, | ||
47 | }, | ||
48 | [1] = { | ||
49 | .start = 32, /* IRQ0 */ | ||
50 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static struct platform_device smc91x_eth_device = { | ||
55 | .name = "smc91x", | ||
56 | .num_resources = ARRAY_SIZE(smc91x_eth_resources), | ||
57 | .resource = smc91x_eth_resources, | ||
58 | .dev = { | ||
59 | .platform_data = &smc91x_info, | ||
60 | }, | ||
61 | }; | ||
62 | |||
63 | static struct sh_keysc_info sh_keysc_info = { | ||
64 | .mode = SH_KEYSC_MODE_2, /* KEYOUT0->4, KEYIN1->5 */ | ||
65 | .scan_timing = 3, | ||
66 | .delay = 5, | ||
67 | .keycodes = { | ||
68 | 0, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER, | ||
69 | 0, KEY_F, KEY_C, KEY_D, KEY_H, KEY_1, | ||
70 | 0, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, | ||
71 | 0, KEY_7, KEY_8, KEY_9, KEY_S, KEY_0, | ||
72 | 0, KEY_P, KEY_STOP, KEY_REWIND, KEY_PLAY, KEY_FASTFORWARD, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | static struct resource sh_keysc_resources[] = { | ||
77 | [0] = { | ||
78 | .start = 0x044b0000, | ||
79 | .end = 0x044b000f, | ||
80 | .flags = IORESOURCE_MEM, | ||
81 | }, | ||
82 | [1] = { | ||
83 | .start = 79, | ||
84 | .flags = IORESOURCE_IRQ, | ||
85 | }, | ||
86 | }; | ||
87 | |||
88 | static struct platform_device sh_keysc_device = { | ||
89 | .name = "sh_keysc", | ||
90 | .num_resources = ARRAY_SIZE(sh_keysc_resources), | ||
91 | .resource = sh_keysc_resources, | ||
92 | .dev = { | ||
93 | .platform_data = &sh_keysc_info, | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | static struct mtd_partition migor_nor_flash_partitions[] = | ||
98 | { | ||
99 | { | ||
100 | .name = "uboot", | ||
101 | .offset = 0, | ||
102 | .size = (1 * 1024 * 1024), | ||
103 | .mask_flags = MTD_WRITEABLE, /* Read-only */ | ||
104 | }, | ||
105 | { | ||
106 | .name = "rootfs", | ||
107 | .offset = MTDPART_OFS_APPEND, | ||
108 | .size = (15 * 1024 * 1024), | ||
109 | }, | ||
110 | { | ||
111 | .name = "other", | ||
112 | .offset = MTDPART_OFS_APPEND, | ||
113 | .size = MTDPART_SIZ_FULL, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static struct physmap_flash_data migor_nor_flash_data = { | ||
118 | .width = 2, | ||
119 | .parts = migor_nor_flash_partitions, | ||
120 | .nr_parts = ARRAY_SIZE(migor_nor_flash_partitions), | ||
121 | }; | ||
122 | |||
123 | static struct resource migor_nor_flash_resources[] = { | ||
124 | [0] = { | ||
125 | .name = "NOR Flash", | ||
126 | .start = 0x00000000, | ||
127 | .end = 0x03ffffff, | ||
128 | .flags = IORESOURCE_MEM, | ||
129 | } | ||
130 | }; | ||
131 | |||
132 | static struct platform_device migor_nor_flash_device = { | ||
133 | .name = "physmap-flash", | ||
134 | .resource = migor_nor_flash_resources, | ||
135 | .num_resources = ARRAY_SIZE(migor_nor_flash_resources), | ||
136 | .dev = { | ||
137 | .platform_data = &migor_nor_flash_data, | ||
138 | }, | ||
139 | }; | ||
140 | |||
141 | static struct mtd_partition migor_nand_flash_partitions[] = { | ||
142 | { | ||
143 | .name = "nanddata1", | ||
144 | .offset = 0x0, | ||
145 | .size = 512 * 1024 * 1024, | ||
146 | }, | ||
147 | { | ||
148 | .name = "nanddata2", | ||
149 | .offset = MTDPART_OFS_APPEND, | ||
150 | .size = 512 * 1024 * 1024, | ||
151 | }, | ||
152 | }; | ||
153 | |||
154 | static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd, | ||
155 | unsigned int ctrl) | ||
156 | { | ||
157 | struct nand_chip *chip = mtd->priv; | ||
158 | |||
159 | if (cmd == NAND_CMD_NONE) | ||
160 | return; | ||
161 | |||
162 | if (ctrl & NAND_CLE) | ||
163 | writeb(cmd, chip->IO_ADDR_W + 0x00400000); | ||
164 | else if (ctrl & NAND_ALE) | ||
165 | writeb(cmd, chip->IO_ADDR_W + 0x00800000); | ||
166 | else | ||
167 | writeb(cmd, chip->IO_ADDR_W); | ||
168 | } | ||
169 | |||
170 | static int migor_nand_flash_ready(struct mtd_info *mtd) | ||
171 | { | ||
172 | return ctrl_inb(PORT_PADR) & 0x02; /* PTA1 */ | ||
173 | } | ||
174 | |||
175 | struct platform_nand_data migor_nand_flash_data = { | ||
176 | .chip = { | ||
177 | .nr_chips = 1, | ||
178 | .partitions = migor_nand_flash_partitions, | ||
179 | .nr_partitions = ARRAY_SIZE(migor_nand_flash_partitions), | ||
180 | .chip_delay = 20, | ||
181 | .part_probe_types = (const char *[]) { "cmdlinepart", NULL }, | ||
182 | }, | ||
183 | .ctrl = { | ||
184 | .dev_ready = migor_nand_flash_ready, | ||
185 | .cmd_ctrl = migor_nand_flash_cmd_ctl, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static struct resource migor_nand_flash_resources[] = { | ||
190 | [0] = { | ||
191 | .name = "NAND Flash", | ||
192 | .start = 0x18000000, | ||
193 | .end = 0x18ffffff, | ||
194 | .flags = IORESOURCE_MEM, | ||
195 | }, | ||
196 | }; | ||
197 | |||
198 | static struct platform_device migor_nand_flash_device = { | ||
199 | .name = "gen_nand", | ||
200 | .resource = migor_nand_flash_resources, | ||
201 | .num_resources = ARRAY_SIZE(migor_nand_flash_resources), | ||
202 | .dev = { | ||
203 | .platform_data = &migor_nand_flash_data, | ||
204 | } | ||
205 | }; | ||
206 | |||
207 | static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = { | ||
208 | #ifdef CONFIG_SH_MIGOR_RTA_WVGA | ||
209 | .clock_source = LCDC_CLK_BUS, | ||
210 | .ch[0] = { | ||
211 | .chan = LCDC_CHAN_MAINLCD, | ||
212 | .bpp = 16, | ||
213 | .interface_type = RGB16, | ||
214 | .clock_divider = 2, | ||
215 | .lcd_cfg = { | ||
216 | .name = "LB070WV1", | ||
217 | .xres = 800, | ||
218 | .yres = 480, | ||
219 | .left_margin = 64, | ||
220 | .right_margin = 16, | ||
221 | .hsync_len = 120, | ||
222 | .upper_margin = 1, | ||
223 | .lower_margin = 17, | ||
224 | .vsync_len = 2, | ||
225 | .sync = 0, | ||
226 | }, | ||
227 | } | ||
228 | #endif | ||
229 | #ifdef CONFIG_SH_MIGOR_QVGA | ||
230 | .clock_source = LCDC_CLK_PERIPHERAL, | ||
231 | .ch[0] = { | ||
232 | .chan = LCDC_CHAN_MAINLCD, | ||
233 | .bpp = 16, | ||
234 | .interface_type = SYS16A, | ||
235 | .clock_divider = 10, | ||
236 | .lcd_cfg = { | ||
237 | .name = "PH240320T", | ||
238 | .xres = 320, | ||
239 | .yres = 240, | ||
240 | .left_margin = 0, | ||
241 | .right_margin = 16, | ||
242 | .hsync_len = 8, | ||
243 | .upper_margin = 1, | ||
244 | .lower_margin = 17, | ||
245 | .vsync_len = 2, | ||
246 | .sync = FB_SYNC_HOR_HIGH_ACT, | ||
247 | }, | ||
248 | .board_cfg = { | ||
249 | .setup_sys = migor_lcd_qvga_setup, | ||
250 | }, | ||
251 | .sys_bus_cfg = { | ||
252 | .ldmt2r = 0x06000a09, | ||
253 | .ldmt3r = 0x180e3418, | ||
254 | }, | ||
255 | } | ||
256 | #endif | ||
257 | }; | ||
258 | |||
259 | static struct resource migor_lcdc_resources[] = { | ||
260 | [0] = { | ||
261 | .name = "LCDC", | ||
262 | .start = 0xfe940000, /* P4-only space */ | ||
263 | .end = 0xfe941fff, | ||
264 | .flags = IORESOURCE_MEM, | ||
265 | }, | ||
266 | }; | ||
267 | |||
268 | static struct platform_device migor_lcdc_device = { | ||
269 | .name = "sh_mobile_lcdc_fb", | ||
270 | .num_resources = ARRAY_SIZE(migor_lcdc_resources), | ||
271 | .resource = migor_lcdc_resources, | ||
272 | .dev = { | ||
273 | .platform_data = &sh_mobile_lcdc_info, | ||
274 | }, | ||
275 | }; | ||
276 | |||
277 | static struct clk *camera_clk; | ||
278 | |||
279 | static void camera_power_on(void) | ||
280 | { | ||
281 | unsigned char value; | ||
282 | |||
283 | camera_clk = clk_get(NULL, "video_clk"); | ||
284 | clk_set_rate(camera_clk, 24000000); | ||
285 | clk_enable(camera_clk); /* start VIO_CKO */ | ||
286 | |||
287 | mdelay(10); | ||
288 | value = ctrl_inb(PORT_PTDR); | ||
289 | value &= ~0x09; | ||
290 | #ifndef CONFIG_SH_MIGOR_RTA_WVGA | ||
291 | value |= 0x01; | ||
292 | #endif | ||
293 | ctrl_outb(value, PORT_PTDR); | ||
294 | mdelay(10); | ||
295 | |||
296 | ctrl_outb(value | 8, PORT_PTDR); | ||
297 | } | ||
298 | |||
299 | static void camera_power_off(void) | ||
300 | { | ||
301 | clk_disable(camera_clk); /* stop VIO_CKO */ | ||
302 | clk_put(camera_clk); | ||
303 | |||
304 | ctrl_outb(ctrl_inb(PORT_PTDR) & ~0x08, PORT_PTDR); | ||
305 | } | ||
306 | |||
307 | static unsigned char camera_ov772x_magic[] = | ||
308 | { | ||
309 | 0x09, 0x01, 0x0c, 0x10, 0x0d, 0x41, 0x0e, 0x01, | ||
310 | 0x12, 0x00, 0x13, 0x8F, 0x14, 0x4A, 0x15, 0x00, | ||
311 | 0x16, 0x00, 0x17, 0x23, 0x18, 0xa0, 0x19, 0x07, | ||
312 | 0x1a, 0xf0, 0x1b, 0x40, 0x1f, 0x00, 0x20, 0x10, | ||
313 | 0x22, 0xff, 0x23, 0x01, 0x28, 0x00, 0x29, 0xa0, | ||
314 | 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0xf0, 0x2d, 0x00, | ||
315 | 0x2e, 0x00, 0x30, 0x80, 0x31, 0x60, 0x32, 0x00, | ||
316 | 0x33, 0x00, 0x34, 0x00, 0x3d, 0x80, 0x3e, 0xe2, | ||
317 | 0x3f, 0x1f, 0x42, 0x80, 0x43, 0x80, 0x44, 0x80, | ||
318 | 0x45, 0x80, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, | ||
319 | 0x49, 0x50, 0x4a, 0x30, 0x4b, 0x50, 0x4c, 0x50, | ||
320 | 0x4d, 0x00, 0x4e, 0xef, 0x4f, 0x10, 0x50, 0x60, | ||
321 | 0x51, 0x00, 0x52, 0x00, 0x53, 0x24, 0x54, 0x7a, | ||
322 | 0x55, 0xfc, 0x62, 0xff, 0x63, 0xf0, 0x64, 0x1f, | ||
323 | 0x65, 0x00, 0x66, 0x10, 0x67, 0x00, 0x68, 0x00, | ||
324 | 0x69, 0x5c, 0x6a, 0x11, 0x6b, 0xa2, 0x6c, 0x01, | ||
325 | 0x6d, 0x50, 0x6e, 0x80, 0x6f, 0x80, 0x70, 0x0f, | ||
326 | 0x71, 0x00, 0x72, 0x00, 0x73, 0x0f, 0x74, 0x0f, | ||
327 | 0x75, 0xff, 0x78, 0x10, 0x79, 0x70, 0x7a, 0x70, | ||
328 | 0x7b, 0xf0, 0x7c, 0xf0, 0x7d, 0xf0, 0x7e, 0x0e, | ||
329 | 0x7f, 0x1a, 0x80, 0x31, 0x81, 0x5a, 0x82, 0x69, | ||
330 | 0x83, 0x75, 0x84, 0x7e, 0x85, 0x88, 0x86, 0x8f, | ||
331 | 0x87, 0x96, 0x88, 0xa3, 0x89, 0xaf, 0x8a, 0xc4, | ||
332 | 0x8b, 0xd7, 0x8c, 0xe8, 0x8d, 0x20, 0x8e, 0x00, | ||
333 | 0x8f, 0x00, 0x90, 0x08, 0x91, 0x10, 0x92, 0x1f, | ||
334 | 0x93, 0x01, 0x94, 0x2c, 0x95, 0x24, 0x96, 0x08, | ||
335 | 0x97, 0x14, 0x98, 0x24, 0x99, 0x38, 0x9a, 0x9e, | ||
336 | 0x9b, 0x00, 0x9c, 0x40, 0x9e, 0x11, 0x9f, 0x02, | ||
337 | 0xa0, 0x00, 0xa1, 0x40, 0xa2, 0x40, 0xa3, 0x06, | ||
338 | 0xa4, 0x00, 0xa6, 0x00, 0xa7, 0x40, 0xa8, 0x40, | ||
339 | 0xa9, 0x80, 0xaa, 0x80, 0xab, 0x06, 0xac, 0xff, | ||
340 | 0x12, 0x06, 0x64, 0x3f, 0x12, 0x46, 0x17, 0x3f, | ||
341 | 0x18, 0x50, 0x19, 0x03, 0x1a, 0x78, 0x29, 0x50, | ||
342 | 0x2c, 0x78, | ||
343 | }; | ||
344 | |||
345 | static int ov772x_set_capture(struct soc_camera_platform_info *info, | ||
346 | int enable) | ||
347 | { | ||
348 | struct i2c_adapter *a = i2c_get_adapter(0); | ||
349 | struct i2c_msg msg; | ||
350 | int ret = 0; | ||
351 | int i; | ||
352 | |||
353 | if (!enable) | ||
354 | return 0; /* camera_power_off() is enough */ | ||
355 | |||
356 | for (i = 0; i < ARRAY_SIZE(camera_ov772x_magic); i += 2) { | ||
357 | u_int8_t buf[8]; | ||
358 | |||
359 | msg.addr = 0x21; | ||
360 | msg.buf = buf; | ||
361 | msg.len = 2; | ||
362 | msg.flags = 0; | ||
363 | |||
364 | buf[0] = camera_ov772x_magic[i]; | ||
365 | buf[1] = camera_ov772x_magic[i + 1]; | ||
366 | |||
367 | ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1); | ||
368 | } | ||
369 | |||
370 | return ret; | ||
371 | } | ||
372 | |||
373 | static struct soc_camera_platform_info ov772x_info = { | ||
374 | .iface = 0, | ||
375 | .format_name = "RGB565", | ||
376 | .format_depth = 16, | ||
377 | .format = { | ||
378 | .pixelformat = V4L2_PIX_FMT_RGB565, | ||
379 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
380 | .width = 320, | ||
381 | .height = 240, | ||
382 | }, | ||
383 | .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | | ||
384 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, | ||
385 | .set_capture = ov772x_set_capture, | ||
386 | }; | ||
387 | |||
388 | static struct platform_device migor_camera_device = { | ||
389 | .name = "soc_camera_platform", | ||
390 | .dev = { | ||
391 | .platform_data = &ov772x_info, | ||
392 | }, | ||
393 | }; | ||
394 | |||
395 | static struct sh_mobile_ceu_info sh_mobile_ceu_info = { | ||
396 | .flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING \ | ||
397 | | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH, | ||
398 | .enable_camera = camera_power_on, | ||
399 | .disable_camera = camera_power_off, | ||
400 | }; | ||
401 | |||
402 | static struct resource migor_ceu_resources[] = { | ||
403 | [0] = { | ||
404 | .name = "CEU", | ||
405 | .start = 0xfe910000, | ||
406 | .end = 0xfe91009f, | ||
407 | .flags = IORESOURCE_MEM, | ||
408 | }, | ||
409 | [1] = { | ||
410 | .start = 52, | ||
411 | .flags = IORESOURCE_IRQ, | ||
412 | }, | ||
413 | [2] = { | ||
414 | /* place holder for contiguous memory */ | ||
415 | }, | ||
416 | }; | ||
417 | |||
418 | static struct platform_device migor_ceu_device = { | ||
419 | .name = "sh_mobile_ceu", | ||
420 | .num_resources = ARRAY_SIZE(migor_ceu_resources), | ||
421 | .resource = migor_ceu_resources, | ||
422 | .dev = { | ||
423 | .platform_data = &sh_mobile_ceu_info, | ||
424 | }, | ||
425 | }; | ||
426 | |||
427 | static struct platform_device *migor_devices[] __initdata = { | ||
428 | &smc91x_eth_device, | ||
429 | &sh_keysc_device, | ||
430 | &migor_lcdc_device, | ||
431 | &migor_ceu_device, | ||
432 | &migor_camera_device, | ||
433 | &migor_nor_flash_device, | ||
434 | &migor_nand_flash_device, | ||
435 | }; | ||
436 | |||
437 | static struct i2c_board_info migor_i2c_devices[] = { | ||
438 | { | ||
439 | I2C_BOARD_INFO("rs5c372b", 0x32), | ||
440 | }, | ||
441 | { | ||
442 | I2C_BOARD_INFO("migor_ts", 0x51), | ||
443 | .irq = 38, /* IRQ6 */ | ||
444 | }, | ||
445 | }; | ||
446 | |||
447 | static int __init migor_devices_setup(void) | ||
448 | { | ||
449 | clk_always_enable("mstp214"); /* KEYSC */ | ||
450 | clk_always_enable("mstp200"); /* LCDC */ | ||
451 | clk_always_enable("mstp203"); /* CEU */ | ||
452 | |||
453 | platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20); | ||
454 | |||
455 | i2c_register_board_info(0, migor_i2c_devices, | ||
456 | ARRAY_SIZE(migor_i2c_devices)); | ||
457 | |||
458 | return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); | ||
459 | } | ||
460 | __initcall(migor_devices_setup); | ||
461 | |||
462 | static void __init migor_setup(char **cmdline_p) | ||
463 | { | ||
464 | /* SMC91C111 - Enable IRQ0 */ | ||
465 | ctrl_outw(ctrl_inw(PORT_PJCR) & ~0x0003, PORT_PJCR); | ||
466 | |||
467 | /* KEYSC */ | ||
468 | ctrl_outw(ctrl_inw(PORT_PYCR) & ~0x0fff, PORT_PYCR); | ||
469 | ctrl_outw(ctrl_inw(PORT_PZCR) & ~0x0ff0, PORT_PZCR); | ||
470 | ctrl_outw(ctrl_inw(PORT_PSELA) & ~0x4100, PORT_PSELA); | ||
471 | ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA); | ||
472 | ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC); | ||
473 | |||
474 | /* NAND Flash */ | ||
475 | ctrl_outw(ctrl_inw(PORT_PXCR) & 0x0fff, PORT_PXCR); | ||
476 | ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x00000600) | 0x00000200, | ||
477 | BSC_CS6ABCR); | ||
478 | |||
479 | /* Touch Panel - Enable IRQ6 */ | ||
480 | ctrl_outw(ctrl_inw(PORT_PZCR) & ~0xc, PORT_PZCR); | ||
481 | ctrl_outw((ctrl_inw(PORT_PSELA) | 0x8000), PORT_PSELA); | ||
482 | ctrl_outw((ctrl_inw(PORT_HIZCRC) & ~0x4000), PORT_HIZCRC); | ||
483 | |||
484 | #ifdef CONFIG_SH_MIGOR_RTA_WVGA | ||
485 | /* LCDC - WVGA - Enable RGB Interface signals */ | ||
486 | ctrl_outw(ctrl_inw(PORT_PACR) & ~0x0003, PORT_PACR); | ||
487 | ctrl_outw(0x0000, PORT_PHCR); | ||
488 | ctrl_outw(0x0000, PORT_PLCR); | ||
489 | ctrl_outw(0x0000, PORT_PMCR); | ||
490 | ctrl_outw(ctrl_inw(PORT_PRCR) & ~0x000f, PORT_PRCR); | ||
491 | ctrl_outw((ctrl_inw(PORT_PSELD) & ~0x000d) | 0x0400, PORT_PSELD); | ||
492 | ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0100, PORT_MSELCRB); | ||
493 | ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x01e0, PORT_HIZCRA); | ||
494 | #endif | ||
495 | #ifdef CONFIG_SH_MIGOR_QVGA | ||
496 | /* LCDC - QVGA - Enable SYS Interface signals */ | ||
497 | ctrl_outw(ctrl_inw(PORT_PACR) & ~0x0003, PORT_PACR); | ||
498 | ctrl_outw((ctrl_inw(PORT_PHCR) & ~0xcfff) | 0x0010, PORT_PHCR); | ||
499 | ctrl_outw(0x0000, PORT_PLCR); | ||
500 | ctrl_outw(0x0000, PORT_PMCR); | ||
501 | ctrl_outw(ctrl_inw(PORT_PRCR) & ~0x030f, PORT_PRCR); | ||
502 | ctrl_outw((ctrl_inw(PORT_PSELD) & ~0x0001) | 0x0420, PORT_PSELD); | ||
503 | ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x0100, PORT_MSELCRB); | ||
504 | ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x01e0, PORT_HIZCRA); | ||
505 | #endif | ||
506 | |||
507 | /* CEU */ | ||
508 | ctrl_outw((ctrl_inw(PORT_PTCR) & ~0x03c3) | 0x0051, PORT_PTCR); | ||
509 | ctrl_outw(ctrl_inw(PORT_PUCR) & ~0x03ff, PORT_PUCR); | ||
510 | ctrl_outw(ctrl_inw(PORT_PVCR) & ~0x03ff, PORT_PVCR); | ||
511 | ctrl_outw(ctrl_inw(PORT_PWCR) & ~0x3c00, PORT_PWCR); | ||
512 | ctrl_outw(ctrl_inw(PORT_PSELC) | 0x0001, PORT_PSELC); | ||
513 | ctrl_outw(ctrl_inw(PORT_PSELD) & ~0x2000, PORT_PSELD); | ||
514 | ctrl_outw(ctrl_inw(PORT_PSELE) | 0x000f, PORT_PSELE); | ||
515 | ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x2200, PORT_MSELCRB); | ||
516 | ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x0a00, PORT_HIZCRA); | ||
517 | ctrl_outw(ctrl_inw(PORT_HIZCRB) & ~0x0003, PORT_HIZCRB); | ||
518 | } | ||
519 | |||
520 | static struct sh_machine_vector mv_migor __initmv = { | ||
521 | .mv_name = "Migo-R", | ||
522 | .mv_setup = migor_setup, | ||
523 | }; | ||