blob: 1e6daa36e5a724d75d7e5ba23ac10c50f9e2b7c9 [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>
Magnus Damm16587c42008-10-08 20:42:20 +090027#include <asm/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[] = {
288};
289
Yusuke Goda04e917b2008-06-06 17:03:23 +0900290static int __init ap325rxa_devices_setup(void)
291{
Magnus Damm16587c42008-10-08 20:42:20 +0900292 /* LD3 and LD4 LEDs */
293 gpio_request(GPIO_PTX5, NULL); /* RUN */
294 gpio_direction_output(GPIO_PTX5, 1);
295 gpio_export(GPIO_PTX5, 0);
296
297 gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
298 gpio_direction_output(GPIO_PTX4, 0);
299 gpio_export(GPIO_PTX4, 0);
300
301 /* SW1 input */
302 gpio_request(GPIO_PTF7, NULL); /* MODE */
303 gpio_direction_input(GPIO_PTF7);
304 gpio_export(GPIO_PTF7, 0);
305
306 /* LCDC */
307 clk_always_enable("mstp200");
308 gpio_request(GPIO_FN_LCDD15, NULL);
309 gpio_request(GPIO_FN_LCDD14, NULL);
310 gpio_request(GPIO_FN_LCDD13, NULL);
311 gpio_request(GPIO_FN_LCDD12, NULL);
312 gpio_request(GPIO_FN_LCDD11, NULL);
313 gpio_request(GPIO_FN_LCDD10, NULL);
314 gpio_request(GPIO_FN_LCDD9, NULL);
315 gpio_request(GPIO_FN_LCDD8, NULL);
316 gpio_request(GPIO_FN_LCDD7, NULL);
317 gpio_request(GPIO_FN_LCDD6, NULL);
318 gpio_request(GPIO_FN_LCDD5, NULL);
319 gpio_request(GPIO_FN_LCDD4, NULL);
320 gpio_request(GPIO_FN_LCDD3, NULL);
321 gpio_request(GPIO_FN_LCDD2, NULL);
322 gpio_request(GPIO_FN_LCDD1, NULL);
323 gpio_request(GPIO_FN_LCDD0, NULL);
324 gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
325 gpio_request(GPIO_FN_LCDDCK, NULL);
326 gpio_request(GPIO_FN_LCDVEPWC, NULL);
327 gpio_request(GPIO_FN_LCDVCPWC, NULL);
328 gpio_request(GPIO_FN_LCDVSYN, NULL);
329 gpio_request(GPIO_FN_LCDHSYN, NULL);
330 gpio_request(GPIO_FN_LCDDISP, NULL);
331 gpio_request(GPIO_FN_LCDDON, NULL);
332
333 /* LCD backlight */
334 gpio_request(GPIO_PTS3, NULL);
335 gpio_direction_output(GPIO_PTS3, 1);
336
337 /* CEU */
338 clk_always_enable("mstp203");
339 gpio_request(GPIO_FN_VIO_CLK2, NULL);
340 gpio_request(GPIO_FN_VIO_VD2, NULL);
341 gpio_request(GPIO_FN_VIO_HD2, NULL);
342 gpio_request(GPIO_FN_VIO_FLD, NULL);
343 gpio_request(GPIO_FN_VIO_CKO, NULL);
344 gpio_request(GPIO_FN_VIO_D15, NULL);
345 gpio_request(GPIO_FN_VIO_D14, NULL);
346 gpio_request(GPIO_FN_VIO_D13, NULL);
347 gpio_request(GPIO_FN_VIO_D12, NULL);
348 gpio_request(GPIO_FN_VIO_D11, NULL);
349 gpio_request(GPIO_FN_VIO_D10, NULL);
350 gpio_request(GPIO_FN_VIO_D9, NULL);
351 gpio_request(GPIO_FN_VIO_D8, NULL);
352
353 gpio_request(GPIO_PTZ7, NULL);
354 gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
355 gpio_request(GPIO_PTZ6, NULL);
356 gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
357 gpio_request(GPIO_PTZ5, NULL);
358 gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */
359 gpio_request(GPIO_PTZ4, NULL);
360 gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
361
362 ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
Magnus Damm8b2224d2008-07-28 19:14:35 +0900363
364 platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
Magnus Damm69689802008-07-28 19:07:04 +0900365
Magnus Damm026953d2008-07-05 12:32:44 +0900366 i2c_register_board_info(0, ap325rxa_i2c_devices,
367 ARRAY_SIZE(ap325rxa_i2c_devices));
368
Yusuke Goda04e917b2008-06-06 17:03:23 +0900369 return platform_add_devices(ap325rxa_devices,
370 ARRAY_SIZE(ap325rxa_devices));
371}
372device_initcall(ap325rxa_devices_setup);
373
Yusuke Goda04e917b2008-06-06 17:03:23 +0900374static void __init ap325rxa_setup(char **cmdline_p)
375{
Yusuke Goda04e917b2008-06-06 17:03:23 +0900376}
377
378static struct sh_machine_vector mv_ap325rxa __initmv = {
379 .mv_name = "AP-325RXA",
380 .mv_setup = ap325rxa_setup,
381};