blob: 7c7874e6ac36c744b508b523201bfc87a68fe64f [file] [log] [blame]
Yusuke Goda04e917b2008-06-06 17:03:23 +09001/*
2 * Renesas - AP-325RXA
3 * (Compatible with Algo System ., LTD. - AP-320A)
4 *
5 * Copyright (C) 2008 Renesas Solutions Corp.
6 * Author : Yusuke Goda <goda.yuske@renesas.com>
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/init.h>
14#include <linux/device.h>
Magnus Damm4875ea22008-07-28 19:11:07 +090015#include <linux/interrupt.h>
Yusuke Goda04e917b2008-06-06 17:03:23 +090016#include <linux/platform_device.h>
17#include <linux/mtd/physmap.h>
18#include <linux/delay.h>
Magnus Damm026953d2008-07-05 12:32:44 +090019#include <linux/i2c.h>
Magnus Damm4875ea22008-07-28 19:11:07 +090020#include <linux/smc911x.h>
Magnus Damm16587c42008-10-08 20:42:20 +090021#include <linux/gpio.h>
Magnus Damm8b2224d2008-07-28 19:14:35 +090022#include <media/soc_camera_platform.h>
23#include <media/sh_mobile_ceu.h>
Paul Mundt225c9a82008-10-01 16:24:32 +090024#include <video/sh_mobile_lcdc.h>
Yusuke Goda04e917b2008-06-06 17:03:23 +090025#include <asm/io.h>
Magnus Damm69689802008-07-28 19:07:04 +090026#include <asm/clock.h>
Paul Mundtf7275652008-10-20 12:04:53 +090027#include <cpu/sh7723.h>
Yusuke Goda04e917b2008-06-06 17:03:23 +090028
Magnus Damm4875ea22008-07-28 19:11:07 +090029static struct smc911x_platdata smc911x_info = {
30 .flags = SMC911X_USE_32BIT,
31 .irq_flags = IRQF_TRIGGER_LOW,
32};
33
Yusuke Goda04e917b2008-06-06 17:03:23 +090034static struct resource smc9118_resources[] = {
35 [0] = {
36 .start = 0xb6080000,
37 .end = 0xb60fffff,
38 .flags = IORESOURCE_MEM,
39 },
40 [1] = {
41 .start = 35,
42 .end = 35,
43 .flags = IORESOURCE_IRQ,
44 }
45};
46
47static struct platform_device smc9118_device = {
48 .name = "smc911x",
49 .id = -1,
50 .num_resources = ARRAY_SIZE(smc9118_resources),
51 .resource = smc9118_resources,
Magnus Damm4875ea22008-07-28 19:11:07 +090052 .dev = {
53 .platform_data = &smc911x_info,
54 },
Yusuke Goda04e917b2008-06-06 17:03:23 +090055};
56
Nobuhiro Iwamatsuaa88f162008-09-24 11:46:48 +090057/*
58 * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
59 * If this area erased, this board can not boot.
60 */
Yusuke Goda04e917b2008-06-06 17:03:23 +090061static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
62 {
Nobuhiro Iwamatsuaa88f162008-09-24 11:46:48 +090063 .name = "uboot",
64 .offset = 0,
65 .size = (1 * 1024 * 1024),
66 .mask_flags = MTD_WRITEABLE, /* Read-only */
Yusuke Goda04e917b2008-06-06 17:03:23 +090067 }, {
Nobuhiro Iwamatsuaa88f162008-09-24 11:46:48 +090068 .name = "kernel",
69 .offset = MTDPART_OFS_APPEND,
70 .size = (2 * 1024 * 1024),
Yusuke Goda04e917b2008-06-06 17:03:23 +090071 }, {
Nobuhiro Iwamatsuaa88f162008-09-24 11:46:48 +090072 .name = "free-area0",
73 .offset = MTDPART_OFS_APPEND,
74 .size = ((7 * 1024 * 1024) + (512 * 1024)),
75 }, {
76 .name = "CPLD-Data",
77 .offset = MTDPART_OFS_APPEND,
78 .mask_flags = MTD_WRITEABLE, /* Read-only */
79 .size = (1024 * 128 * 2),
80 }, {
81 .name = "free-area1",
82 .offset = MTDPART_OFS_APPEND,
83 .size = MTDPART_SIZ_FULL,
Yusuke Goda04e917b2008-06-06 17:03:23 +090084 },
85};
86
87static struct physmap_flash_data ap325rxa_nor_flash_data = {
88 .width = 2,
89 .parts = ap325rxa_nor_flash_partitions,
90 .nr_parts = ARRAY_SIZE(ap325rxa_nor_flash_partitions),
91};
92
93static struct resource ap325rxa_nor_flash_resources[] = {
94 [0] = {
95 .name = "NOR Flash",
96 .start = 0x00000000,
97 .end = 0x00ffffff,
98 .flags = IORESOURCE_MEM,
99 }
100};
101
102static struct platform_device ap325rxa_nor_flash_device = {
103 .name = "physmap-flash",
104 .resource = ap325rxa_nor_flash_resources,
105 .num_resources = ARRAY_SIZE(ap325rxa_nor_flash_resources),
106 .dev = {
107 .platform_data = &ap325rxa_nor_flash_data,
108 },
109};
110
Magnus Damm69689802008-07-28 19:07:04 +0900111#define FPGA_LCDREG 0xB4100180
112#define FPGA_BKLREG 0xB4100212
113#define FPGA_LCDREG_VAL 0x0018
Magnus Damm8b2224d2008-07-28 19:14:35 +0900114#define PORT_MSELCRB 0xA4050182
Magnus Damm69689802008-07-28 19:07:04 +0900115
116static void ap320_wvga_power_on(void *board_data)
117{
118 msleep(100);
119
120 /* ASD AP-320/325 LCD ON */
121 ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
122
123 /* backlight */
Magnus Damm16587c42008-10-08 20:42:20 +0900124 gpio_set_value(GPIO_PTS3, 0);
Magnus Damm69689802008-07-28 19:07:04 +0900125 ctrl_outw(0x100, FPGA_BKLREG);
126}
127
128static struct sh_mobile_lcdc_info lcdc_info = {
129 .clock_source = LCDC_CLK_EXTERNAL,
130 .ch[0] = {
131 .chan = LCDC_CHAN_MAINLCD,
132 .bpp = 16,
133 .interface_type = RGB18,
134 .clock_divider = 1,
135 .lcd_cfg = {
136 .name = "LB070WV1",
137 .xres = 800,
138 .yres = 480,
139 .left_margin = 40,
140 .right_margin = 160,
141 .hsync_len = 8,
142 .upper_margin = 63,
143 .lower_margin = 80,
144 .vsync_len = 1,
145 .sync = 0, /* hsync and vsync are active low */
146 },
Magnus Dammce9c0082008-08-11 15:26:00 +0900147 .lcd_size_cfg = { /* 7.0 inch */
148 .width = 152,
149 .height = 91,
150 },
Magnus Damm69689802008-07-28 19:07:04 +0900151 .board_cfg = {
152 .display_on = ap320_wvga_power_on,
153 },
154 }
155};
156
157static struct resource lcdc_resources[] = {
158 [0] = {
159 .name = "LCDC",
160 .start = 0xfe940000, /* P4-only space */
161 .end = 0xfe941fff,
162 .flags = IORESOURCE_MEM,
163 },
164};
165
166static struct platform_device lcdc_device = {
167 .name = "sh_mobile_lcdc_fb",
168 .num_resources = ARRAY_SIZE(lcdc_resources),
169 .resource = lcdc_resources,
170 .dev = {
171 .platform_data = &lcdc_info,
172 },
173};
174
Magnus Damme565b512008-07-29 20:57:38 +0900175#ifdef CONFIG_I2C
Magnus Damm8b2224d2008-07-28 19:14:35 +0900176static unsigned char camera_ncm03j_magic[] =
177{
178 0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
179 0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
180 0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
181 0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
182 0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
183 0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
184 0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
185 0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
186 0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
187 0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
188 0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
189 0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
190 0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
191 0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
192 0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
193 0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
194};
195
196static int camera_set_capture(struct soc_camera_platform_info *info,
197 int enable)
198{
199 struct i2c_adapter *a = i2c_get_adapter(0);
200 struct i2c_msg msg;
201 int ret = 0;
202 int i;
203
204 if (!enable)
205 return 0; /* no disable for now */
206
207 for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
208 u_int8_t buf[8];
209
210 msg.addr = 0x6e;
211 msg.buf = buf;
212 msg.len = 2;
213 msg.flags = 0;
214
215 buf[0] = camera_ncm03j_magic[i];
216 buf[1] = camera_ncm03j_magic[i + 1];
217
218 ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
219 }
220
221 return ret;
222}
223
224static struct soc_camera_platform_info camera_info = {
225 .iface = 0,
226 .format_name = "UYVY",
227 .format_depth = 16,
228 .format = {
229 .pixelformat = V4L2_PIX_FMT_UYVY,
230 .colorspace = V4L2_COLORSPACE_SMPTE170M,
231 .width = 640,
232 .height = 480,
233 },
234 .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
235 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
236 .set_capture = camera_set_capture,
237};
238
239static struct platform_device camera_device = {
240 .name = "soc_camera_platform",
241 .dev = {
242 .platform_data = &camera_info,
243 },
244};
Magnus Damme565b512008-07-29 20:57:38 +0900245#endif /* CONFIG_I2C */
Magnus Damm8b2224d2008-07-28 19:14:35 +0900246
247static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
248 .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
249 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
250};
251
252static struct resource ceu_resources[] = {
253 [0] = {
254 .name = "CEU",
255 .start = 0xfe910000,
256 .end = 0xfe91009f,
257 .flags = IORESOURCE_MEM,
258 },
259 [1] = {
260 .start = 52,
261 .flags = IORESOURCE_IRQ,
262 },
263 [2] = {
264 /* place holder for contiguous memory */
265 },
266};
267
268static struct platform_device ceu_device = {
269 .name = "sh_mobile_ceu",
270 .num_resources = ARRAY_SIZE(ceu_resources),
271 .resource = ceu_resources,
272 .dev = {
273 .platform_data = &sh_mobile_ceu_info,
274 },
275};
276
Yusuke Goda04e917b2008-06-06 17:03:23 +0900277static struct platform_device *ap325rxa_devices[] __initdata = {
278 &smc9118_device,
Magnus Damm69689802008-07-28 19:07:04 +0900279 &ap325rxa_nor_flash_device,
280 &lcdc_device,
Magnus Damm8b2224d2008-07-28 19:14:35 +0900281 &ceu_device,
Magnus Damme565b512008-07-29 20:57:38 +0900282#ifdef CONFIG_I2C
Magnus Damm8b2224d2008-07-28 19:14:35 +0900283 &camera_device,
Magnus Damme565b512008-07-29 20:57:38 +0900284#endif
Yusuke Goda04e917b2008-06-06 17:03:23 +0900285};
286
Magnus Damm026953d2008-07-05 12:32:44 +0900287static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
Nobuhiro Iwamatsua3e02702008-10-17 16:53:57 +0900288 {
289 I2C_BOARD_INFO("pcf8563", 0x51),
290 },
Magnus Damm026953d2008-07-05 12:32:44 +0900291};
292
Yusuke Goda04e917b2008-06-06 17:03:23 +0900293static int __init ap325rxa_devices_setup(void)
294{
Magnus Damm16587c42008-10-08 20:42:20 +0900295 /* LD3 and LD4 LEDs */
296 gpio_request(GPIO_PTX5, NULL); /* RUN */
297 gpio_direction_output(GPIO_PTX5, 1);
298 gpio_export(GPIO_PTX5, 0);
299
300 gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
301 gpio_direction_output(GPIO_PTX4, 0);
302 gpio_export(GPIO_PTX4, 0);
303
304 /* SW1 input */
305 gpio_request(GPIO_PTF7, NULL); /* MODE */
306 gpio_direction_input(GPIO_PTF7);
307 gpio_export(GPIO_PTF7, 0);
308
309 /* LCDC */
310 clk_always_enable("mstp200");
311 gpio_request(GPIO_FN_LCDD15, NULL);
312 gpio_request(GPIO_FN_LCDD14, NULL);
313 gpio_request(GPIO_FN_LCDD13, NULL);
314 gpio_request(GPIO_FN_LCDD12, NULL);
315 gpio_request(GPIO_FN_LCDD11, NULL);
316 gpio_request(GPIO_FN_LCDD10, NULL);
317 gpio_request(GPIO_FN_LCDD9, NULL);
318 gpio_request(GPIO_FN_LCDD8, NULL);
319 gpio_request(GPIO_FN_LCDD7, NULL);
320 gpio_request(GPIO_FN_LCDD6, NULL);
321 gpio_request(GPIO_FN_LCDD5, NULL);
322 gpio_request(GPIO_FN_LCDD4, NULL);
323 gpio_request(GPIO_FN_LCDD3, NULL);
324 gpio_request(GPIO_FN_LCDD2, NULL);
325 gpio_request(GPIO_FN_LCDD1, NULL);
326 gpio_request(GPIO_FN_LCDD0, NULL);
327 gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
328 gpio_request(GPIO_FN_LCDDCK, NULL);
329 gpio_request(GPIO_FN_LCDVEPWC, NULL);
330 gpio_request(GPIO_FN_LCDVCPWC, NULL);
331 gpio_request(GPIO_FN_LCDVSYN, NULL);
332 gpio_request(GPIO_FN_LCDHSYN, NULL);
333 gpio_request(GPIO_FN_LCDDISP, NULL);
334 gpio_request(GPIO_FN_LCDDON, NULL);
335
336 /* LCD backlight */
337 gpio_request(GPIO_PTS3, NULL);
338 gpio_direction_output(GPIO_PTS3, 1);
339
340 /* CEU */
341 clk_always_enable("mstp203");
342 gpio_request(GPIO_FN_VIO_CLK2, NULL);
343 gpio_request(GPIO_FN_VIO_VD2, NULL);
344 gpio_request(GPIO_FN_VIO_HD2, NULL);
345 gpio_request(GPIO_FN_VIO_FLD, NULL);
346 gpio_request(GPIO_FN_VIO_CKO, NULL);
347 gpio_request(GPIO_FN_VIO_D15, NULL);
348 gpio_request(GPIO_FN_VIO_D14, NULL);
349 gpio_request(GPIO_FN_VIO_D13, NULL);
350 gpio_request(GPIO_FN_VIO_D12, NULL);
351 gpio_request(GPIO_FN_VIO_D11, NULL);
352 gpio_request(GPIO_FN_VIO_D10, NULL);
353 gpio_request(GPIO_FN_VIO_D9, NULL);
354 gpio_request(GPIO_FN_VIO_D8, NULL);
355
356 gpio_request(GPIO_PTZ7, NULL);
357 gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
358 gpio_request(GPIO_PTZ6, NULL);
359 gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
360 gpio_request(GPIO_PTZ5, NULL);
361 gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */
362 gpio_request(GPIO_PTZ4, NULL);
363 gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
364
365 ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
Magnus Damm8b2224d2008-07-28 19:14:35 +0900366
367 platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
Magnus Damm69689802008-07-28 19:07:04 +0900368
Magnus Damm026953d2008-07-05 12:32:44 +0900369 i2c_register_board_info(0, ap325rxa_i2c_devices,
370 ARRAY_SIZE(ap325rxa_i2c_devices));
371
Yusuke Goda04e917b2008-06-06 17:03:23 +0900372 return platform_add_devices(ap325rxa_devices,
373 ARRAY_SIZE(ap325rxa_devices));
374}
375device_initcall(ap325rxa_devices_setup);
376
Yusuke Goda04e917b2008-06-06 17:03:23 +0900377static void __init ap325rxa_setup(char **cmdline_p)
378{
Yusuke Goda04e917b2008-06-06 17:03:23 +0900379}
380
381static struct sh_machine_vector mv_ap325rxa __initmv = {
382 .mv_name = "AP-325RXA",
383 .mv_setup = ap325rxa_setup,
384};