gianfar: Revive VLAN support
[safe/jmp/linux-2.6] / arch / sh / boards / board-ap325rxa.c
1 /*
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>
15 #include <linux/interrupt.h>
16 #include <linux/platform_device.h>
17 #include <linux/mtd/physmap.h>
18 #include <linux/mtd/sh_flctl.h>
19 #include <linux/delay.h>
20 #include <linux/i2c.h>
21 #include <linux/smc911x.h>
22 #include <linux/gpio.h>
23 #include <media/soc_camera_platform.h>
24 #include <media/sh_mobile_ceu.h>
25 #include <video/sh_mobile_lcdc.h>
26 #include <asm/io.h>
27 #include <asm/clock.h>
28 #include <cpu/sh7723.h>
29
30 static struct smc911x_platdata smc911x_info = {
31         .flags = SMC911X_USE_32BIT,
32         .irq_flags = IRQF_TRIGGER_LOW,
33 };
34
35 static struct resource smc9118_resources[] = {
36         [0] = {
37                 .start  = 0xb6080000,
38                 .end    = 0xb60fffff,
39                 .flags  = IORESOURCE_MEM,
40         },
41         [1] = {
42                 .start  = 35,
43                 .end    = 35,
44                 .flags  = IORESOURCE_IRQ,
45         }
46 };
47
48 static struct platform_device smc9118_device = {
49         .name           = "smc911x",
50         .id             = -1,
51         .num_resources  = ARRAY_SIZE(smc9118_resources),
52         .resource       = smc9118_resources,
53         .dev            = {
54                 .platform_data = &smc911x_info,
55         },
56 };
57
58 /*
59  * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
60  * If this area erased, this board can not boot.
61  */
62 static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
63         {
64                 .name = "uboot",
65                 .offset = 0,
66                 .size = (1 * 1024 * 1024),
67                 .mask_flags = MTD_WRITEABLE,    /* Read-only */
68         }, {
69                 .name = "kernel",
70                 .offset = MTDPART_OFS_APPEND,
71                 .size = (2 * 1024 * 1024),
72         }, {
73                 .name = "free-area0",
74                 .offset = MTDPART_OFS_APPEND,
75                 .size = ((7 * 1024 * 1024) + (512 * 1024)),
76         }, {
77                 .name = "CPLD-Data",
78                 .offset = MTDPART_OFS_APPEND,
79                 .mask_flags = MTD_WRITEABLE,    /* Read-only */
80                 .size = (1024 * 128 * 2),
81         }, {
82                 .name = "free-area1",
83                 .offset = MTDPART_OFS_APPEND,
84                 .size = MTDPART_SIZ_FULL,
85         },
86 };
87
88 static struct physmap_flash_data ap325rxa_nor_flash_data = {
89         .width          = 2,
90         .parts          = ap325rxa_nor_flash_partitions,
91         .nr_parts       = ARRAY_SIZE(ap325rxa_nor_flash_partitions),
92 };
93
94 static struct resource ap325rxa_nor_flash_resources[] = {
95         [0] = {
96                 .name   = "NOR Flash",
97                 .start  = 0x00000000,
98                 .end    = 0x00ffffff,
99                 .flags  = IORESOURCE_MEM,
100         }
101 };
102
103 static struct platform_device ap325rxa_nor_flash_device = {
104         .name           = "physmap-flash",
105         .resource       = ap325rxa_nor_flash_resources,
106         .num_resources  = ARRAY_SIZE(ap325rxa_nor_flash_resources),
107         .dev            = {
108                 .platform_data = &ap325rxa_nor_flash_data,
109         },
110 };
111
112 static struct mtd_partition nand_partition_info[] = {
113         {
114                 .name   = "nand_data",
115                 .offset = 0,
116                 .size   = MTDPART_SIZ_FULL,
117         },
118 };
119
120 static struct resource nand_flash_resources[] = {
121         [0] = {
122                 .start  = 0xa4530000,
123                 .end    = 0xa45300ff,
124                 .flags  = IORESOURCE_MEM,
125         }
126 };
127
128 static struct sh_flctl_platform_data nand_flash_data = {
129         .parts          = nand_partition_info,
130         .nr_parts       = ARRAY_SIZE(nand_partition_info),
131         .flcmncr_val    = FCKSEL_E | TYPESEL_SET | NANWF_E,
132         .has_hwecc      = 1,
133 };
134
135 static struct platform_device nand_flash_device = {
136         .name           = "sh_flctl",
137         .resource       = nand_flash_resources,
138         .num_resources  = ARRAY_SIZE(nand_flash_resources),
139         .dev            = {
140                 .platform_data = &nand_flash_data,
141         },
142 };
143
144 #define FPGA_LCDREG     0xB4100180
145 #define FPGA_BKLREG     0xB4100212
146 #define FPGA_LCDREG_VAL 0x0018
147 #define PORT_MSELCRB    0xA4050182
148 #define PORT_HIZCRC     0xA405015C
149 #define PORT_DRVCRA     0xA405018A
150 #define PORT_DRVCRB     0xA405018C
151
152 static void ap320_wvga_power_on(void *board_data)
153 {
154         msleep(100);
155
156         /* ASD AP-320/325 LCD ON */
157         ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
158
159         /* backlight */
160         gpio_set_value(GPIO_PTS3, 0);
161         ctrl_outw(0x100, FPGA_BKLREG);
162 }
163
164 static struct sh_mobile_lcdc_info lcdc_info = {
165         .clock_source = LCDC_CLK_EXTERNAL,
166         .ch[0] = {
167                 .chan = LCDC_CHAN_MAINLCD,
168                 .bpp = 16,
169                 .interface_type = RGB18,
170                 .clock_divider = 1,
171                 .lcd_cfg = {
172                         .name = "LB070WV1",
173                         .xres = 800,
174                         .yres = 480,
175                         .left_margin = 40,
176                         .right_margin = 160,
177                         .hsync_len = 8,
178                         .upper_margin = 63,
179                         .lower_margin = 80,
180                         .vsync_len = 1,
181                         .sync = 0, /* hsync and vsync are active low */
182                 },
183                 .lcd_size_cfg = { /* 7.0 inch */
184                         .width = 152,
185                         .height = 91,
186                 },
187                 .board_cfg = {
188                         .display_on = ap320_wvga_power_on,
189                 },
190         }
191 };
192
193 static struct resource lcdc_resources[] = {
194         [0] = {
195                 .name   = "LCDC",
196                 .start  = 0xfe940000, /* P4-only space */
197                 .end    = 0xfe941fff,
198                 .flags  = IORESOURCE_MEM,
199         },
200         [1] = {
201                 .start  = 28,
202                 .flags  = IORESOURCE_IRQ,
203         },
204 };
205
206 static struct platform_device lcdc_device = {
207         .name           = "sh_mobile_lcdc_fb",
208         .num_resources  = ARRAY_SIZE(lcdc_resources),
209         .resource       = lcdc_resources,
210         .dev            = {
211                 .platform_data  = &lcdc_info,
212         },
213 };
214
215 #ifdef CONFIG_I2C
216 static unsigned char camera_ncm03j_magic[] =
217 {
218         0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
219         0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
220         0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
221         0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
222         0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
223         0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
224         0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
225         0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
226         0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
227         0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
228         0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
229         0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
230         0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
231         0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
232         0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
233         0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
234 };
235
236 static int camera_set_capture(struct soc_camera_platform_info *info,
237                               int enable)
238 {
239         struct i2c_adapter *a = i2c_get_adapter(0);
240         struct i2c_msg msg;
241         int ret = 0;
242         int i;
243
244         if (!enable)
245                 return 0; /* no disable for now */
246
247         for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
248                 u_int8_t buf[8];
249
250                 msg.addr = 0x6e;
251                 msg.buf = buf;
252                 msg.len = 2;
253                 msg.flags = 0;
254
255                 buf[0] = camera_ncm03j_magic[i];
256                 buf[1] = camera_ncm03j_magic[i + 1];
257
258                 ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
259         }
260
261         return ret;
262 }
263
264 static struct soc_camera_platform_info camera_info = {
265         .iface = 0,
266         .format_name = "UYVY",
267         .format_depth = 16,
268         .format = {
269                 .pixelformat = V4L2_PIX_FMT_UYVY,
270                 .colorspace = V4L2_COLORSPACE_SMPTE170M,
271                 .width = 640,
272                 .height = 480,
273         },
274         .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
275         SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
276         .set_capture = camera_set_capture,
277 };
278
279 static struct platform_device camera_device = {
280         .name           = "soc_camera_platform",
281         .dev            = {
282                 .platform_data  = &camera_info,
283         },
284 };
285 #endif /* CONFIG_I2C */
286
287 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
288         .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
289         SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
290 };
291
292 static struct resource ceu_resources[] = {
293         [0] = {
294                 .name   = "CEU",
295                 .start  = 0xfe910000,
296                 .end    = 0xfe91009f,
297                 .flags  = IORESOURCE_MEM,
298         },
299         [1] = {
300                 .start  = 52,
301                 .flags  = IORESOURCE_IRQ,
302         },
303         [2] = {
304                 /* place holder for contiguous memory */
305         },
306 };
307
308 static struct platform_device ceu_device = {
309         .name           = "sh_mobile_ceu",
310         .id             = 0, /* "ceu0" clock */
311         .num_resources  = ARRAY_SIZE(ceu_resources),
312         .resource       = ceu_resources,
313         .dev            = {
314                 .platform_data  = &sh_mobile_ceu_info,
315         },
316 };
317
318 static struct platform_device *ap325rxa_devices[] __initdata = {
319         &smc9118_device,
320         &ap325rxa_nor_flash_device,
321         &lcdc_device,
322         &ceu_device,
323 #ifdef CONFIG_I2C
324         &camera_device,
325 #endif
326         &nand_flash_device,
327 };
328
329 static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
330         {
331                 I2C_BOARD_INFO("pcf8563", 0x51),
332         },
333 };
334
335 static int __init ap325rxa_devices_setup(void)
336 {
337         /* LD3 and LD4 LEDs */
338         gpio_request(GPIO_PTX5, NULL); /* RUN */
339         gpio_direction_output(GPIO_PTX5, 1);
340         gpio_export(GPIO_PTX5, 0);
341
342         gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
343         gpio_direction_output(GPIO_PTX4, 0);
344         gpio_export(GPIO_PTX4, 0);
345
346         /* SW1 input */
347         gpio_request(GPIO_PTF7, NULL); /* MODE */
348         gpio_direction_input(GPIO_PTF7);
349         gpio_export(GPIO_PTF7, 0);
350
351         /* LCDC */
352         gpio_request(GPIO_FN_LCDD15, NULL);
353         gpio_request(GPIO_FN_LCDD14, NULL);
354         gpio_request(GPIO_FN_LCDD13, NULL);
355         gpio_request(GPIO_FN_LCDD12, NULL);
356         gpio_request(GPIO_FN_LCDD11, NULL);
357         gpio_request(GPIO_FN_LCDD10, NULL);
358         gpio_request(GPIO_FN_LCDD9, NULL);
359         gpio_request(GPIO_FN_LCDD8, NULL);
360         gpio_request(GPIO_FN_LCDD7, NULL);
361         gpio_request(GPIO_FN_LCDD6, NULL);
362         gpio_request(GPIO_FN_LCDD5, NULL);
363         gpio_request(GPIO_FN_LCDD4, NULL);
364         gpio_request(GPIO_FN_LCDD3, NULL);
365         gpio_request(GPIO_FN_LCDD2, NULL);
366         gpio_request(GPIO_FN_LCDD1, NULL);
367         gpio_request(GPIO_FN_LCDD0, NULL);
368         gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
369         gpio_request(GPIO_FN_LCDDCK, NULL);
370         gpio_request(GPIO_FN_LCDVEPWC, NULL);
371         gpio_request(GPIO_FN_LCDVCPWC, NULL);
372         gpio_request(GPIO_FN_LCDVSYN, NULL);
373         gpio_request(GPIO_FN_LCDHSYN, NULL);
374         gpio_request(GPIO_FN_LCDDISP, NULL);
375         gpio_request(GPIO_FN_LCDDON, NULL);
376
377         /* LCD backlight */
378         gpio_request(GPIO_PTS3, NULL);
379         gpio_direction_output(GPIO_PTS3, 1);
380
381         /* CEU */
382         gpio_request(GPIO_FN_VIO_CLK2, NULL);
383         gpio_request(GPIO_FN_VIO_VD2, NULL);
384         gpio_request(GPIO_FN_VIO_HD2, NULL);
385         gpio_request(GPIO_FN_VIO_FLD, NULL);
386         gpio_request(GPIO_FN_VIO_CKO, NULL);
387         gpio_request(GPIO_FN_VIO_D15, NULL);
388         gpio_request(GPIO_FN_VIO_D14, NULL);
389         gpio_request(GPIO_FN_VIO_D13, NULL);
390         gpio_request(GPIO_FN_VIO_D12, NULL);
391         gpio_request(GPIO_FN_VIO_D11, NULL);
392         gpio_request(GPIO_FN_VIO_D10, NULL);
393         gpio_request(GPIO_FN_VIO_D9, NULL);
394         gpio_request(GPIO_FN_VIO_D8, NULL);
395
396         gpio_request(GPIO_PTZ7, NULL);
397         gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
398         gpio_request(GPIO_PTZ6, NULL);
399         gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
400         gpio_request(GPIO_PTZ5, NULL);
401         gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */
402         gpio_request(GPIO_PTZ4, NULL);
403         gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
404
405         ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
406
407         /* FLCTL */
408         gpio_request(GPIO_FN_FCE, NULL);
409         gpio_request(GPIO_FN_NAF7, NULL);
410         gpio_request(GPIO_FN_NAF6, NULL);
411         gpio_request(GPIO_FN_NAF5, NULL);
412         gpio_request(GPIO_FN_NAF4, NULL);
413         gpio_request(GPIO_FN_NAF3, NULL);
414         gpio_request(GPIO_FN_NAF2, NULL);
415         gpio_request(GPIO_FN_NAF1, NULL);
416         gpio_request(GPIO_FN_NAF0, NULL);
417         gpio_request(GPIO_FN_FCDE, NULL);
418         gpio_request(GPIO_FN_FOE, NULL);
419         gpio_request(GPIO_FN_FSC, NULL);
420         gpio_request(GPIO_FN_FWE, NULL);
421         gpio_request(GPIO_FN_FRB, NULL);
422
423         ctrl_outw(0, PORT_HIZCRC);
424         ctrl_outw(0xFFFF, PORT_DRVCRA);
425         ctrl_outw(0xFFFF, PORT_DRVCRB);
426
427         platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
428
429         i2c_register_board_info(0, ap325rxa_i2c_devices,
430                                 ARRAY_SIZE(ap325rxa_i2c_devices));
431
432         return platform_add_devices(ap325rxa_devices,
433                                 ARRAY_SIZE(ap325rxa_devices));
434 }
435 device_initcall(ap325rxa_devices_setup);
436
437 static struct sh_machine_vector mv_ap325rxa __initmv = {
438         .mv_name = "AP-325RXA",
439 };