Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
[sfrench/cifs-2.6.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_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 };
201
202 static struct platform_device lcdc_device = {
203         .name           = "sh_mobile_lcdc_fb",
204         .num_resources  = ARRAY_SIZE(lcdc_resources),
205         .resource       = lcdc_resources,
206         .dev            = {
207                 .platform_data  = &lcdc_info,
208         },
209 };
210
211 #ifdef CONFIG_I2C
212 static unsigned char camera_ncm03j_magic[] =
213 {
214         0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
215         0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
216         0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
217         0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
218         0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
219         0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
220         0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
221         0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
222         0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
223         0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
224         0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
225         0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
226         0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
227         0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
228         0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
229         0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
230 };
231
232 static int camera_set_capture(struct soc_camera_platform_info *info,
233                               int enable)
234 {
235         struct i2c_adapter *a = i2c_get_adapter(0);
236         struct i2c_msg msg;
237         int ret = 0;
238         int i;
239
240         if (!enable)
241                 return 0; /* no disable for now */
242
243         for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
244                 u_int8_t buf[8];
245
246                 msg.addr = 0x6e;
247                 msg.buf = buf;
248                 msg.len = 2;
249                 msg.flags = 0;
250
251                 buf[0] = camera_ncm03j_magic[i];
252                 buf[1] = camera_ncm03j_magic[i + 1];
253
254                 ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
255         }
256
257         return ret;
258 }
259
260 static struct soc_camera_platform_info camera_info = {
261         .iface = 0,
262         .format_name = "UYVY",
263         .format_depth = 16,
264         .format = {
265                 .pixelformat = V4L2_PIX_FMT_UYVY,
266                 .colorspace = V4L2_COLORSPACE_SMPTE170M,
267                 .width = 640,
268                 .height = 480,
269         },
270         .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
271         SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
272         .set_capture = camera_set_capture,
273 };
274
275 static struct platform_device camera_device = {
276         .name           = "soc_camera_platform",
277         .dev            = {
278                 .platform_data  = &camera_info,
279         },
280 };
281 #endif /* CONFIG_I2C */
282
283 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
284         .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
285         SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
286 };
287
288 static struct resource ceu_resources[] = {
289         [0] = {
290                 .name   = "CEU",
291                 .start  = 0xfe910000,
292                 .end    = 0xfe91009f,
293                 .flags  = IORESOURCE_MEM,
294         },
295         [1] = {
296                 .start  = 52,
297                 .flags  = IORESOURCE_IRQ,
298         },
299         [2] = {
300                 /* place holder for contiguous memory */
301         },
302 };
303
304 static struct platform_device ceu_device = {
305         .name           = "sh_mobile_ceu",
306         .num_resources  = ARRAY_SIZE(ceu_resources),
307         .resource       = ceu_resources,
308         .dev            = {
309                 .platform_data  = &sh_mobile_ceu_info,
310         },
311 };
312
313 static struct platform_device *ap325rxa_devices[] __initdata = {
314         &smc9118_device,
315         &ap325rxa_nor_flash_device,
316         &lcdc_device,
317         &ceu_device,
318 #ifdef CONFIG_I2C
319         &camera_device,
320 #endif
321         &nand_flash_device,
322 };
323
324 static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
325         {
326                 I2C_BOARD_INFO("pcf8563", 0x51),
327         },
328 };
329
330 static int __init ap325rxa_devices_setup(void)
331 {
332         /* LD3 and LD4 LEDs */
333         gpio_request(GPIO_PTX5, NULL); /* RUN */
334         gpio_direction_output(GPIO_PTX5, 1);
335         gpio_export(GPIO_PTX5, 0);
336
337         gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
338         gpio_direction_output(GPIO_PTX4, 0);
339         gpio_export(GPIO_PTX4, 0);
340
341         /* SW1 input */
342         gpio_request(GPIO_PTF7, NULL); /* MODE */
343         gpio_direction_input(GPIO_PTF7);
344         gpio_export(GPIO_PTF7, 0);
345
346         /* LCDC */
347         clk_always_enable("mstp200");
348         gpio_request(GPIO_FN_LCDD15, NULL);
349         gpio_request(GPIO_FN_LCDD14, NULL);
350         gpio_request(GPIO_FN_LCDD13, NULL);
351         gpio_request(GPIO_FN_LCDD12, NULL);
352         gpio_request(GPIO_FN_LCDD11, NULL);
353         gpio_request(GPIO_FN_LCDD10, NULL);
354         gpio_request(GPIO_FN_LCDD9, NULL);
355         gpio_request(GPIO_FN_LCDD8, NULL);
356         gpio_request(GPIO_FN_LCDD7, NULL);
357         gpio_request(GPIO_FN_LCDD6, NULL);
358         gpio_request(GPIO_FN_LCDD5, NULL);
359         gpio_request(GPIO_FN_LCDD4, NULL);
360         gpio_request(GPIO_FN_LCDD3, NULL);
361         gpio_request(GPIO_FN_LCDD2, NULL);
362         gpio_request(GPIO_FN_LCDD1, NULL);
363         gpio_request(GPIO_FN_LCDD0, NULL);
364         gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
365         gpio_request(GPIO_FN_LCDDCK, NULL);
366         gpio_request(GPIO_FN_LCDVEPWC, NULL);
367         gpio_request(GPIO_FN_LCDVCPWC, NULL);
368         gpio_request(GPIO_FN_LCDVSYN, NULL);
369         gpio_request(GPIO_FN_LCDHSYN, NULL);
370         gpio_request(GPIO_FN_LCDDISP, NULL);
371         gpio_request(GPIO_FN_LCDDON, NULL);
372
373         /* LCD backlight */
374         gpio_request(GPIO_PTS3, NULL);
375         gpio_direction_output(GPIO_PTS3, 1);
376
377         /* CEU */
378         clk_always_enable("mstp203");
379         gpio_request(GPIO_FN_VIO_CLK2, NULL);
380         gpio_request(GPIO_FN_VIO_VD2, NULL);
381         gpio_request(GPIO_FN_VIO_HD2, NULL);
382         gpio_request(GPIO_FN_VIO_FLD, NULL);
383         gpio_request(GPIO_FN_VIO_CKO, NULL);
384         gpio_request(GPIO_FN_VIO_D15, NULL);
385         gpio_request(GPIO_FN_VIO_D14, NULL);
386         gpio_request(GPIO_FN_VIO_D13, NULL);
387         gpio_request(GPIO_FN_VIO_D12, NULL);
388         gpio_request(GPIO_FN_VIO_D11, NULL);
389         gpio_request(GPIO_FN_VIO_D10, NULL);
390         gpio_request(GPIO_FN_VIO_D9, NULL);
391         gpio_request(GPIO_FN_VIO_D8, NULL);
392
393         gpio_request(GPIO_PTZ7, NULL);
394         gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
395         gpio_request(GPIO_PTZ6, NULL);
396         gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
397         gpio_request(GPIO_PTZ5, NULL);
398         gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */
399         gpio_request(GPIO_PTZ4, NULL);
400         gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
401
402         ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
403
404         /* FLCTL */
405         gpio_request(GPIO_FN_FCE, NULL);
406         gpio_request(GPIO_FN_NAF7, NULL);
407         gpio_request(GPIO_FN_NAF6, NULL);
408         gpio_request(GPIO_FN_NAF5, NULL);
409         gpio_request(GPIO_FN_NAF4, NULL);
410         gpio_request(GPIO_FN_NAF3, NULL);
411         gpio_request(GPIO_FN_NAF2, NULL);
412         gpio_request(GPIO_FN_NAF1, NULL);
413         gpio_request(GPIO_FN_NAF0, NULL);
414         gpio_request(GPIO_FN_FCDE, NULL);
415         gpio_request(GPIO_FN_FOE, NULL);
416         gpio_request(GPIO_FN_FSC, NULL);
417         gpio_request(GPIO_FN_FWE, NULL);
418         gpio_request(GPIO_FN_FRB, NULL);
419
420         ctrl_outw(0, PORT_HIZCRC);
421         ctrl_outw(0xFFFF, PORT_DRVCRA);
422         ctrl_outw(0xFFFF, PORT_DRVCRB);
423
424         platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
425
426         i2c_register_board_info(0, ap325rxa_i2c_devices,
427                                 ARRAY_SIZE(ap325rxa_i2c_devices));
428
429         return platform_add_devices(ap325rxa_devices,
430                                 ARRAY_SIZE(ap325rxa_devices));
431 }
432 device_initcall(ap325rxa_devices_setup);
433
434 static struct sh_machine_vector mv_ap325rxa __initmv = {
435         .mv_name = "AP-325RXA",
436 };