• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/smsc911x.h>
22 #include <linux/gpio.h>
23 #include <linux/spi/spi.h>
24 #include <linux/spi/spi_gpio.h>
25 #include <media/soc_camera.h>
26 #include <media/soc_camera_platform.h>
27 #include <media/sh_mobile_ceu.h>
28 #include <video/sh_mobile_lcdc.h>
29 #include <asm/io.h>
30 #include <asm/clock.h>
31 #include <cpu/sh7723.h>
32 
33 static struct smsc911x_platform_config smsc911x_config = {
34 	.phy_interface	= PHY_INTERFACE_MODE_MII,
35 	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
36 	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
37 	.flags		= SMSC911X_USE_32BIT,
38 };
39 
40 static struct resource smsc9118_resources[] = {
41 	[0] = {
42 		.start	= 0xb6080000,
43 		.end	= 0xb60fffff,
44 		.flags	= IORESOURCE_MEM,
45 	},
46 	[1] = {
47 		.start	= 35,
48 		.end	= 35,
49 		.flags	= IORESOURCE_IRQ,
50 	}
51 };
52 
53 static struct platform_device smsc9118_device = {
54 	.name		= "smsc911x",
55 	.id		= -1,
56 	.num_resources	= ARRAY_SIZE(smsc9118_resources),
57 	.resource	= smsc9118_resources,
58 	.dev		= {
59 		.platform_data = &smsc911x_config,
60 	},
61 };
62 
63 /*
64  * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
65  * If this area erased, this board can not boot.
66  */
67 static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
68 	{
69 		.name = "uboot",
70 		.offset = 0,
71 		.size = (1 * 1024 * 1024),
72 		.mask_flags = MTD_WRITEABLE,	/* Read-only */
73 	}, {
74 		.name = "kernel",
75 		.offset = MTDPART_OFS_APPEND,
76 		.size = (2 * 1024 * 1024),
77 	}, {
78 		.name = "free-area0",
79 		.offset = MTDPART_OFS_APPEND,
80 		.size = ((7 * 1024 * 1024) + (512 * 1024)),
81 	}, {
82 		.name = "CPLD-Data",
83 		.offset = MTDPART_OFS_APPEND,
84 		.mask_flags = MTD_WRITEABLE,	/* Read-only */
85 		.size = (1024 * 128 * 2),
86 	}, {
87 		.name = "free-area1",
88 		.offset = MTDPART_OFS_APPEND,
89 		.size = MTDPART_SIZ_FULL,
90 	},
91 };
92 
93 static struct physmap_flash_data ap325rxa_nor_flash_data = {
94 	.width		= 2,
95 	.parts		= ap325rxa_nor_flash_partitions,
96 	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
97 };
98 
99 static struct resource ap325rxa_nor_flash_resources[] = {
100 	[0] = {
101 		.name	= "NOR Flash",
102 		.start	= 0x00000000,
103 		.end	= 0x00ffffff,
104 		.flags	= IORESOURCE_MEM,
105 	}
106 };
107 
108 static struct platform_device ap325rxa_nor_flash_device = {
109 	.name		= "physmap-flash",
110 	.resource	= ap325rxa_nor_flash_resources,
111 	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
112 	.dev		= {
113 		.platform_data = &ap325rxa_nor_flash_data,
114 	},
115 };
116 
117 static struct mtd_partition nand_partition_info[] = {
118 	{
119 		.name	= "nand_data",
120 		.offset	= 0,
121 		.size	= MTDPART_SIZ_FULL,
122 	},
123 };
124 
125 static struct resource nand_flash_resources[] = {
126 	[0] = {
127 		.start	= 0xa4530000,
128 		.end	= 0xa45300ff,
129 		.flags	= IORESOURCE_MEM,
130 	}
131 };
132 
133 static struct sh_flctl_platform_data nand_flash_data = {
134 	.parts		= nand_partition_info,
135 	.nr_parts	= ARRAY_SIZE(nand_partition_info),
136 	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
137 	.has_hwecc	= 1,
138 };
139 
140 static struct platform_device nand_flash_device = {
141 	.name		= "sh_flctl",
142 	.resource	= nand_flash_resources,
143 	.num_resources	= ARRAY_SIZE(nand_flash_resources),
144 	.dev		= {
145 		.platform_data = &nand_flash_data,
146 	},
147 };
148 
149 #define FPGA_LCDREG	0xB4100180
150 #define FPGA_BKLREG	0xB4100212
151 #define FPGA_LCDREG_VAL	0x0018
152 #define PORT_MSELCRB	0xA4050182
153 #define PORT_HIZCRC	0xA405015C
154 #define PORT_DRVCRA	0xA405018A
155 #define PORT_DRVCRB	0xA405018C
156 
ap320_wvga_power_on(void * board_data)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 	[1] = {
206 		.start	= 28,
207 		.flags	= IORESOURCE_IRQ,
208 	},
209 };
210 
211 static struct platform_device lcdc_device = {
212 	.name		= "sh_mobile_lcdc_fb",
213 	.num_resources	= ARRAY_SIZE(lcdc_resources),
214 	.resource	= lcdc_resources,
215 	.dev		= {
216 		.platform_data	= &lcdc_info,
217 	},
218 };
219 
camera_power(int val)220 static void camera_power(int val)
221 {
222 	gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
223 	mdelay(10);
224 }
225 
226 #ifdef CONFIG_I2C
227 static unsigned char camera_ncm03j_magic[] =
228 {
229 	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
230 	0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
231 	0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
232 	0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
233 	0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
234 	0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
235 	0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
236 	0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
237 	0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
238 	0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
239 	0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
240 	0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
241 	0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
242 	0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
243 	0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
244 	0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
245 };
246 
camera_set_capture(struct soc_camera_platform_info * info,int enable)247 static int camera_set_capture(struct soc_camera_platform_info *info,
248 			      int enable)
249 {
250 	struct i2c_adapter *a = i2c_get_adapter(0);
251 	struct i2c_msg msg;
252 	int ret = 0;
253 	int i;
254 
255 	camera_power(0);
256 	if (!enable)
257 		return 0; /* no disable for now */
258 
259 	camera_power(1);
260 	for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
261 		u_int8_t buf[8];
262 
263 		msg.addr = 0x6e;
264 		msg.buf = buf;
265 		msg.len = 2;
266 		msg.flags = 0;
267 
268 		buf[0] = camera_ncm03j_magic[i];
269 		buf[1] = camera_ncm03j_magic[i + 1];
270 
271 		ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
272 	}
273 
274 	return ret;
275 }
276 
277 static struct soc_camera_platform_info camera_info = {
278 	.iface = 0,
279 	.format_name = "UYVY",
280 	.format_depth = 16,
281 	.format = {
282 		.pixelformat = V4L2_PIX_FMT_UYVY,
283 		.colorspace = V4L2_COLORSPACE_SMPTE170M,
284 		.width = 640,
285 		.height = 480,
286 	},
287 	.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
288 	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
289 	.set_capture = camera_set_capture,
290 };
291 
292 static struct platform_device camera_device = {
293 	.name		= "soc_camera_platform",
294 	.dev		= {
295 		.platform_data	= &camera_info,
296 	},
297 };
298 #endif /* CONFIG_I2C */
299 
300 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
301 	.flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
302 	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
303 };
304 
305 static struct resource ceu_resources[] = {
306 	[0] = {
307 		.name	= "CEU",
308 		.start	= 0xfe910000,
309 		.end	= 0xfe91009f,
310 		.flags	= IORESOURCE_MEM,
311 	},
312 	[1] = {
313 		.start  = 52,
314 		.flags  = IORESOURCE_IRQ,
315 	},
316 	[2] = {
317 		/* place holder for contiguous memory */
318 	},
319 };
320 
321 static struct platform_device ceu_device = {
322 	.name		= "sh_mobile_ceu",
323 	.id             = 0, /* "ceu0" clock */
324 	.num_resources	= ARRAY_SIZE(ceu_resources),
325 	.resource	= ceu_resources,
326 	.dev		= {
327 		.platform_data	= &sh_mobile_ceu_info,
328 	},
329 };
330 
331 struct spi_gpio_platform_data sdcard_cn3_platform_data = {
332 	.sck = GPIO_PTD0,
333 	.mosi = GPIO_PTD1,
334 	.miso = GPIO_PTD2,
335 	.num_chipselect = 1,
336 };
337 
338 static struct platform_device sdcard_cn3_device = {
339 	.name		= "spi_gpio",
340 	.dev	= {
341 		.platform_data	= &sdcard_cn3_platform_data,
342 	},
343 };
344 
345 static struct platform_device *ap325rxa_devices[] __initdata = {
346 	&smsc9118_device,
347 	&ap325rxa_nor_flash_device,
348 	&lcdc_device,
349 	&ceu_device,
350 #ifdef CONFIG_I2C
351 	&camera_device,
352 #endif
353 	&nand_flash_device,
354 	&sdcard_cn3_device,
355 };
356 
357 static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
358 	{
359 		I2C_BOARD_INFO("pcf8563", 0x51),
360 	},
361 };
362 
363 static struct spi_board_info ap325rxa_spi_devices[] = {
364 	{
365 		.modalias = "mmc_spi",
366 		.max_speed_hz = 5000000,
367 		.chip_select = 0,
368 		.controller_data = (void *) GPIO_PTD5,
369 	},
370 };
371 
ap325rxa_devices_setup(void)372 static int __init ap325rxa_devices_setup(void)
373 {
374 	/* LD3 and LD4 LEDs */
375 	gpio_request(GPIO_PTX5, NULL); /* RUN */
376 	gpio_direction_output(GPIO_PTX5, 1);
377 	gpio_export(GPIO_PTX5, 0);
378 
379 	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
380 	gpio_direction_output(GPIO_PTX4, 0);
381 	gpio_export(GPIO_PTX4, 0);
382 
383 	/* SW1 input */
384 	gpio_request(GPIO_PTF7, NULL); /* MODE */
385 	gpio_direction_input(GPIO_PTF7);
386 	gpio_export(GPIO_PTF7, 0);
387 
388 	/* LCDC */
389 	gpio_request(GPIO_FN_LCDD15, NULL);
390 	gpio_request(GPIO_FN_LCDD14, NULL);
391 	gpio_request(GPIO_FN_LCDD13, NULL);
392 	gpio_request(GPIO_FN_LCDD12, NULL);
393 	gpio_request(GPIO_FN_LCDD11, NULL);
394 	gpio_request(GPIO_FN_LCDD10, NULL);
395 	gpio_request(GPIO_FN_LCDD9, NULL);
396 	gpio_request(GPIO_FN_LCDD8, NULL);
397 	gpio_request(GPIO_FN_LCDD7, NULL);
398 	gpio_request(GPIO_FN_LCDD6, NULL);
399 	gpio_request(GPIO_FN_LCDD5, NULL);
400 	gpio_request(GPIO_FN_LCDD4, NULL);
401 	gpio_request(GPIO_FN_LCDD3, NULL);
402 	gpio_request(GPIO_FN_LCDD2, NULL);
403 	gpio_request(GPIO_FN_LCDD1, NULL);
404 	gpio_request(GPIO_FN_LCDD0, NULL);
405 	gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
406 	gpio_request(GPIO_FN_LCDDCK, NULL);
407 	gpio_request(GPIO_FN_LCDVEPWC, NULL);
408 	gpio_request(GPIO_FN_LCDVCPWC, NULL);
409 	gpio_request(GPIO_FN_LCDVSYN, NULL);
410 	gpio_request(GPIO_FN_LCDHSYN, NULL);
411 	gpio_request(GPIO_FN_LCDDISP, NULL);
412 	gpio_request(GPIO_FN_LCDDON, NULL);
413 
414 	/* LCD backlight */
415 	gpio_request(GPIO_PTS3, NULL);
416 	gpio_direction_output(GPIO_PTS3, 1);
417 
418 	/* CEU */
419 	gpio_request(GPIO_FN_VIO_CLK2, NULL);
420 	gpio_request(GPIO_FN_VIO_VD2, NULL);
421 	gpio_request(GPIO_FN_VIO_HD2, NULL);
422 	gpio_request(GPIO_FN_VIO_FLD, NULL);
423 	gpio_request(GPIO_FN_VIO_CKO, NULL);
424 	gpio_request(GPIO_FN_VIO_D15, NULL);
425 	gpio_request(GPIO_FN_VIO_D14, NULL);
426 	gpio_request(GPIO_FN_VIO_D13, NULL);
427 	gpio_request(GPIO_FN_VIO_D12, NULL);
428 	gpio_request(GPIO_FN_VIO_D11, NULL);
429 	gpio_request(GPIO_FN_VIO_D10, NULL);
430 	gpio_request(GPIO_FN_VIO_D9, NULL);
431 	gpio_request(GPIO_FN_VIO_D8, NULL);
432 
433 	gpio_request(GPIO_PTZ7, NULL);
434 	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
435 	gpio_request(GPIO_PTZ6, NULL);
436 	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
437 	gpio_request(GPIO_PTZ5, NULL);
438 	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
439 	gpio_request(GPIO_PTZ4, NULL);
440 	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
441 
442 	ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
443 
444 	/* FLCTL */
445 	gpio_request(GPIO_FN_FCE, NULL);
446 	gpio_request(GPIO_FN_NAF7, NULL);
447 	gpio_request(GPIO_FN_NAF6, NULL);
448 	gpio_request(GPIO_FN_NAF5, NULL);
449 	gpio_request(GPIO_FN_NAF4, NULL);
450 	gpio_request(GPIO_FN_NAF3, NULL);
451 	gpio_request(GPIO_FN_NAF2, NULL);
452 	gpio_request(GPIO_FN_NAF1, NULL);
453 	gpio_request(GPIO_FN_NAF0, NULL);
454 	gpio_request(GPIO_FN_FCDE, NULL);
455 	gpio_request(GPIO_FN_FOE, NULL);
456 	gpio_request(GPIO_FN_FSC, NULL);
457 	gpio_request(GPIO_FN_FWE, NULL);
458 	gpio_request(GPIO_FN_FRB, NULL);
459 
460 	ctrl_outw(0, PORT_HIZCRC);
461 	ctrl_outw(0xFFFF, PORT_DRVCRA);
462 	ctrl_outw(0xFFFF, PORT_DRVCRB);
463 
464 	platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
465 
466 	i2c_register_board_info(0, ap325rxa_i2c_devices,
467 				ARRAY_SIZE(ap325rxa_i2c_devices));
468 
469 	spi_register_board_info(ap325rxa_spi_devices,
470 				ARRAY_SIZE(ap325rxa_spi_devices));
471 
472 	return platform_add_devices(ap325rxa_devices,
473 				ARRAY_SIZE(ap325rxa_devices));
474 }
475 device_initcall(ap325rxa_devices_setup);
476 
477 static struct sh_machine_vector mv_ap325rxa __initmv = {
478 	.mv_name = "AP-325RXA",
479 };
480