]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/sh/boards/board-ap325rxa.c
sh: add support FLCTL for ap325rxa board
[linux-2.6-omap-h63xx.git] / 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_PUCR       0xA4050142
149 #define PORT_PVCR       0xA4050144
150 #define PORT_PXCR       0xA4050148
151 #define PORT_HIZCRC     0xA405015C
152 #define PORT_DRVCRA     0xA405018A
153 #define PORT_DRVCRB     0xA405018C
154 #define PORT_PXDR       0xA4050168
155 #define PORT_PSELC      0xA4050152
156
157 static void ap320_wvga_power_on(void *board_data)
158 {
159         msleep(100);
160
161         /* ASD AP-320/325 LCD ON */
162         ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
163
164         /* backlight */
165         gpio_set_value(GPIO_PTS3, 0);
166         ctrl_outw(0x100, FPGA_BKLREG);
167 }
168
169 static struct sh_mobile_lcdc_info lcdc_info = {
170         .clock_source = LCDC_CLK_EXTERNAL,
171         .ch[0] = {
172                 .chan = LCDC_CHAN_MAINLCD,
173                 .bpp = 16,
174                 .interface_type = RGB18,
175                 .clock_divider = 1,
176                 .lcd_cfg = {
177                         .name = "LB070WV1",
178                         .xres = 800,
179                         .yres = 480,
180                         .left_margin = 40,
181                         .right_margin = 160,
182                         .hsync_len = 8,
183                         .upper_margin = 63,
184                         .lower_margin = 80,
185                         .vsync_len = 1,
186                         .sync = 0, /* hsync and vsync are active low */
187                 },
188                 .lcd_size_cfg = { /* 7.0 inch */
189                         .width = 152,
190                         .height = 91,
191                 },
192                 .board_cfg = {
193                         .display_on = ap320_wvga_power_on,
194                 },
195         }
196 };
197
198 static struct resource lcdc_resources[] = {
199         [0] = {
200                 .name   = "LCDC",
201                 .start  = 0xfe940000, /* P4-only space */
202                 .end    = 0xfe941fff,
203                 .flags  = IORESOURCE_MEM,
204         },
205 };
206
207 static struct platform_device lcdc_device = {
208         .name           = "sh_mobile_lcdc_fb",
209         .num_resources  = ARRAY_SIZE(lcdc_resources),
210         .resource       = lcdc_resources,
211         .dev            = {
212                 .platform_data  = &lcdc_info,
213         },
214 };
215
216 #ifdef CONFIG_I2C
217 static unsigned char camera_ncm03j_magic[] =
218 {
219         0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
220         0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
221         0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
222         0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
223         0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
224         0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
225         0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
226         0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
227         0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
228         0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
229         0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
230         0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
231         0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
232         0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
233         0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
234         0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
235 };
236
237 static int camera_set_capture(struct soc_camera_platform_info *info,
238                               int enable)
239 {
240         struct i2c_adapter *a = i2c_get_adapter(0);
241         struct i2c_msg msg;
242         int ret = 0;
243         int i;
244
245         if (!enable)
246                 return 0; /* no disable for now */
247
248         for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
249                 u_int8_t buf[8];
250
251                 msg.addr = 0x6e;
252                 msg.buf = buf;
253                 msg.len = 2;
254                 msg.flags = 0;
255
256                 buf[0] = camera_ncm03j_magic[i];
257                 buf[1] = camera_ncm03j_magic[i + 1];
258
259                 ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
260         }
261
262         return ret;
263 }
264
265 static struct soc_camera_platform_info camera_info = {
266         .iface = 0,
267         .format_name = "UYVY",
268         .format_depth = 16,
269         .format = {
270                 .pixelformat = V4L2_PIX_FMT_UYVY,
271                 .colorspace = V4L2_COLORSPACE_SMPTE170M,
272                 .width = 640,
273                 .height = 480,
274         },
275         .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
276         SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
277         .set_capture = camera_set_capture,
278 };
279
280 static struct platform_device camera_device = {
281         .name           = "soc_camera_platform",
282         .dev            = {
283                 .platform_data  = &camera_info,
284         },
285 };
286 #endif /* CONFIG_I2C */
287
288 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
289         .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
290         SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
291 };
292
293 static struct resource ceu_resources[] = {
294         [0] = {
295                 .name   = "CEU",
296                 .start  = 0xfe910000,
297                 .end    = 0xfe91009f,
298                 .flags  = IORESOURCE_MEM,
299         },
300         [1] = {
301                 .start  = 52,
302                 .flags  = IORESOURCE_IRQ,
303         },
304         [2] = {
305                 /* place holder for contiguous memory */
306         },
307 };
308
309 static struct platform_device ceu_device = {
310         .name           = "sh_mobile_ceu",
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         clk_always_enable("mstp200");
353         gpio_request(GPIO_FN_LCDD15, NULL);
354         gpio_request(GPIO_FN_LCDD14, NULL);
355         gpio_request(GPIO_FN_LCDD13, NULL);
356         gpio_request(GPIO_FN_LCDD12, NULL);
357         gpio_request(GPIO_FN_LCDD11, NULL);
358         gpio_request(GPIO_FN_LCDD10, NULL);
359         gpio_request(GPIO_FN_LCDD9, NULL);
360         gpio_request(GPIO_FN_LCDD8, NULL);
361         gpio_request(GPIO_FN_LCDD7, NULL);
362         gpio_request(GPIO_FN_LCDD6, NULL);
363         gpio_request(GPIO_FN_LCDD5, NULL);
364         gpio_request(GPIO_FN_LCDD4, NULL);
365         gpio_request(GPIO_FN_LCDD3, NULL);
366         gpio_request(GPIO_FN_LCDD2, NULL);
367         gpio_request(GPIO_FN_LCDD1, NULL);
368         gpio_request(GPIO_FN_LCDD0, NULL);
369         gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
370         gpio_request(GPIO_FN_LCDDCK, NULL);
371         gpio_request(GPIO_FN_LCDVEPWC, NULL);
372         gpio_request(GPIO_FN_LCDVCPWC, NULL);
373         gpio_request(GPIO_FN_LCDVSYN, NULL);
374         gpio_request(GPIO_FN_LCDHSYN, NULL);
375         gpio_request(GPIO_FN_LCDDISP, NULL);
376         gpio_request(GPIO_FN_LCDDON, NULL);
377
378         /* LCD backlight */
379         gpio_request(GPIO_PTS3, NULL);
380         gpio_direction_output(GPIO_PTS3, 1);
381
382         /* CEU */
383         clk_always_enable("mstp203");
384         gpio_request(GPIO_FN_VIO_CLK2, NULL);
385         gpio_request(GPIO_FN_VIO_VD2, NULL);
386         gpio_request(GPIO_FN_VIO_HD2, NULL);
387         gpio_request(GPIO_FN_VIO_FLD, NULL);
388         gpio_request(GPIO_FN_VIO_CKO, NULL);
389         gpio_request(GPIO_FN_VIO_D15, NULL);
390         gpio_request(GPIO_FN_VIO_D14, NULL);
391         gpio_request(GPIO_FN_VIO_D13, NULL);
392         gpio_request(GPIO_FN_VIO_D12, NULL);
393         gpio_request(GPIO_FN_VIO_D11, NULL);
394         gpio_request(GPIO_FN_VIO_D10, NULL);
395         gpio_request(GPIO_FN_VIO_D9, NULL);
396         gpio_request(GPIO_FN_VIO_D8, NULL);
397
398         gpio_request(GPIO_PTZ7, NULL);
399         gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
400         gpio_request(GPIO_PTZ6, NULL);
401         gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
402         gpio_request(GPIO_PTZ5, NULL);
403         gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */
404         gpio_request(GPIO_PTZ4, NULL);
405         gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
406
407         ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
408
409         /* FLCTL */
410         ctrl_outw(0, PORT_PUCR);
411         ctrl_outw(0, PORT_PVCR);
412         ctrl_outw(0, PORT_PSELC);
413
414         ctrl_outw(0, PORT_HIZCRC);
415         ctrl_outw(0xFFFF, PORT_DRVCRA);
416         ctrl_outw(0xFFFF, PORT_DRVCRB);
417
418         ctrl_outw((ctrl_inw(PORT_PXCR) & 0x3fff) | 0x4000, PORT_PXCR);
419         ctrl_outb(0x80, PORT_PXDR);
420
421         platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
422
423         i2c_register_board_info(0, ap325rxa_i2c_devices,
424                                 ARRAY_SIZE(ap325rxa_i2c_devices));
425
426         return platform_add_devices(ap325rxa_devices,
427                                 ARRAY_SIZE(ap325rxa_devices));
428 }
429 device_initcall(ap325rxa_devices_setup);
430
431 static struct sh_machine_vector mv_ap325rxa __initmv = {
432         .mv_name = "AP-325RXA",
433 };