Linux Audio

Check our new training course

Loading...
v3.15
 
  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/mmc/host.h>
 18#include <linux/mmc/sh_mobile_sdhi.h>
 19#include <linux/mtd/physmap.h>
 20#include <linux/mtd/sh_flctl.h>
 21#include <linux/delay.h>
 22#include <linux/i2c.h>
 23#include <linux/regulator/fixed.h>
 24#include <linux/regulator/machine.h>
 
 25#include <linux/smsc911x.h>
 26#include <linux/gpio.h>
 27#include <linux/videodev2.h>
 28#include <linux/sh_intc.h>
 29#include <media/ov772x.h>
 30#include <media/soc_camera.h>
 31#include <media/soc_camera_platform.h>
 32#include <media/sh_mobile_ceu.h>
 33#include <video/sh_mobile_lcdc.h>
 34#include <asm/io.h>
 35#include <asm/clock.h>
 36#include <asm/suspend.h>
 37#include <cpu/sh7723.h>
 38
 39/* Dummy supplies, where voltage doesn't matter */
 40static struct regulator_consumer_supply dummy_supplies[] = {
 41	REGULATOR_SUPPLY("vddvario", "smsc911x"),
 42	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
 43};
 44
 45static struct smsc911x_platform_config smsc911x_config = {
 46	.phy_interface	= PHY_INTERFACE_MODE_MII,
 47	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
 48	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
 49	.flags		= SMSC911X_USE_32BIT,
 50};
 51
 52static struct resource smsc9118_resources[] = {
 53	[0] = {
 54		.start	= 0xb6080000,
 55		.end	= 0xb60fffff,
 56		.flags	= IORESOURCE_MEM,
 57	},
 58	[1] = {
 59		.start	= evt2irq(0x660),
 60		.end	= evt2irq(0x660),
 61		.flags	= IORESOURCE_IRQ,
 62	}
 63};
 64
 65static struct platform_device smsc9118_device = {
 66	.name		= "smsc911x",
 67	.id		= -1,
 68	.num_resources	= ARRAY_SIZE(smsc9118_resources),
 69	.resource	= smsc9118_resources,
 70	.dev		= {
 71		.platform_data = &smsc911x_config,
 72	},
 73};
 74
 75/*
 76 * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
 77 * If this area erased, this board can not boot.
 78 */
 79static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
 80	{
 81		.name = "uboot",
 82		.offset = 0,
 83		.size = (1 * 1024 * 1024),
 84		.mask_flags = MTD_WRITEABLE,	/* Read-only */
 85	}, {
 86		.name = "kernel",
 87		.offset = MTDPART_OFS_APPEND,
 88		.size = (2 * 1024 * 1024),
 89	}, {
 90		.name = "free-area0",
 91		.offset = MTDPART_OFS_APPEND,
 92		.size = ((7 * 1024 * 1024) + (512 * 1024)),
 93	}, {
 94		.name = "CPLD-Data",
 95		.offset = MTDPART_OFS_APPEND,
 96		.mask_flags = MTD_WRITEABLE,	/* Read-only */
 97		.size = (1024 * 128 * 2),
 98	}, {
 99		.name = "free-area1",
100		.offset = MTDPART_OFS_APPEND,
101		.size = MTDPART_SIZ_FULL,
102	},
103};
104
105static struct physmap_flash_data ap325rxa_nor_flash_data = {
106	.width		= 2,
107	.parts		= ap325rxa_nor_flash_partitions,
108	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
109};
110
111static struct resource ap325rxa_nor_flash_resources[] = {
112	[0] = {
113		.name	= "NOR Flash",
114		.start	= 0x00000000,
115		.end	= 0x00ffffff,
116		.flags	= IORESOURCE_MEM,
117	}
118};
119
120static struct platform_device ap325rxa_nor_flash_device = {
121	.name		= "physmap-flash",
122	.resource	= ap325rxa_nor_flash_resources,
123	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
124	.dev		= {
125		.platform_data = &ap325rxa_nor_flash_data,
126	},
127};
128
129static struct mtd_partition nand_partition_info[] = {
130	{
131		.name	= "nand_data",
132		.offset	= 0,
133		.size	= MTDPART_SIZ_FULL,
134	},
135};
136
137static struct resource nand_flash_resources[] = {
138	[0] = {
139		.start	= 0xa4530000,
140		.end	= 0xa45300ff,
141		.flags	= IORESOURCE_MEM,
142	}
143};
144
145static struct sh_flctl_platform_data nand_flash_data = {
146	.parts		= nand_partition_info,
147	.nr_parts	= ARRAY_SIZE(nand_partition_info),
148	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
149	.has_hwecc	= 1,
150};
151
152static struct platform_device nand_flash_device = {
153	.name		= "sh_flctl",
154	.resource	= nand_flash_resources,
155	.num_resources	= ARRAY_SIZE(nand_flash_resources),
156	.dev		= {
157		.platform_data = &nand_flash_data,
158	},
159};
160
161#define FPGA_LCDREG	0xB4100180
162#define FPGA_BKLREG	0xB4100212
163#define FPGA_LCDREG_VAL	0x0018
164#define PORT_MSELCRB	0xA4050182
165#define PORT_HIZCRC	0xA405015C
166#define PORT_DRVCRA	0xA405018A
167#define PORT_DRVCRB	0xA405018C
168
169static int ap320_wvga_set_brightness(int brightness)
170{
171	if (brightness) {
172		gpio_set_value(GPIO_PTS3, 0);
173		__raw_writew(0x100, FPGA_BKLREG);
174	} else {
175		__raw_writew(0, FPGA_BKLREG);
176		gpio_set_value(GPIO_PTS3, 1);
177	}
178
179	return 0;
180}
181
182static void ap320_wvga_power_on(void)
183{
184	msleep(100);
185
186	/* ASD AP-320/325 LCD ON */
187	__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
188}
189
190static void ap320_wvga_power_off(void)
191{
192	/* ASD AP-320/325 LCD OFF */
193	__raw_writew(0, FPGA_LCDREG);
194}
195
196static const struct fb_videomode ap325rxa_lcdc_modes[] = {
197	{
198		.name = "LB070WV1",
199		.xres = 800,
200		.yres = 480,
201		.left_margin = 32,
202		.right_margin = 160,
203		.hsync_len = 8,
204		.upper_margin = 63,
205		.lower_margin = 80,
206		.vsync_len = 1,
207		.sync = 0, /* hsync and vsync are active low */
208	},
209};
210
211static struct sh_mobile_lcdc_info lcdc_info = {
212	.clock_source = LCDC_CLK_EXTERNAL,
213	.ch[0] = {
214		.chan = LCDC_CHAN_MAINLCD,
215		.fourcc = V4L2_PIX_FMT_RGB565,
216		.interface_type = RGB18,
217		.clock_divider = 1,
218		.lcd_modes = ap325rxa_lcdc_modes,
219		.num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes),
220		.panel_cfg = {
221			.width = 152,	/* 7.0 inch */
222			.height = 91,
223			.display_on = ap320_wvga_power_on,
224			.display_off = ap320_wvga_power_off,
225		},
226		.bl_info = {
227			.name = "sh_mobile_lcdc_bl",
228			.max_brightness = 1,
229			.set_brightness = ap320_wvga_set_brightness,
230		},
231	}
232};
233
234static struct resource lcdc_resources[] = {
235	[0] = {
236		.name	= "LCDC",
237		.start	= 0xfe940000, /* P4-only space */
238		.end	= 0xfe942fff,
239		.flags	= IORESOURCE_MEM,
240	},
241	[1] = {
242		.start	= evt2irq(0x580),
243		.flags	= IORESOURCE_IRQ,
244	},
245};
246
247static struct platform_device lcdc_device = {
248	.name		= "sh_mobile_lcdc_fb",
249	.num_resources	= ARRAY_SIZE(lcdc_resources),
250	.resource	= lcdc_resources,
251	.dev		= {
252		.platform_data	= &lcdc_info,
253	},
254};
255
256static void camera_power(int val)
257{
258	gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
259	mdelay(10);
260}
261
262#ifdef CONFIG_I2C
263/* support for the old ncm03j camera */
264static unsigned char camera_ncm03j_magic[] =
265{
266	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
267	0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
268	0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
269	0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
270	0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
271	0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
272	0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
273	0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
274	0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
275	0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
276	0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
277	0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
278	0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
279	0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
280	0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
281	0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
282};
283
284static int camera_probe(void)
285{
286	struct i2c_adapter *a = i2c_get_adapter(0);
287	struct i2c_msg msg;
288	int ret;
289
290	if (!a)
291		return -ENODEV;
292
293	camera_power(1);
294	msg.addr = 0x6e;
295	msg.buf = camera_ncm03j_magic;
296	msg.len = 2;
297	msg.flags = 0;
298	ret = i2c_transfer(a, &msg, 1);
299	camera_power(0);
300
301	return ret;
302}
303
304static int camera_set_capture(struct soc_camera_platform_info *info,
305			      int enable)
306{
307	struct i2c_adapter *a = i2c_get_adapter(0);
308	struct i2c_msg msg;
309	int ret = 0;
310	int i;
311
312	camera_power(0);
313	if (!enable)
314		return 0; /* no disable for now */
315
316	camera_power(1);
317	for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
318		u_int8_t buf[8];
319
320		msg.addr = 0x6e;
321		msg.buf = buf;
322		msg.len = 2;
323		msg.flags = 0;
324
325		buf[0] = camera_ncm03j_magic[i];
326		buf[1] = camera_ncm03j_magic[i + 1];
327
328		ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
329	}
330
331	return ret;
332}
333
334static int ap325rxa_camera_add(struct soc_camera_device *icd);
335static void ap325rxa_camera_del(struct soc_camera_device *icd);
336
337static struct soc_camera_platform_info camera_info = {
338	.format_name = "UYVY",
339	.format_depth = 16,
340	.format = {
341		.code = V4L2_MBUS_FMT_UYVY8_2X8,
342		.colorspace = V4L2_COLORSPACE_SMPTE170M,
343		.field = V4L2_FIELD_NONE,
344		.width = 640,
345		.height = 480,
346	},
347	.mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
348	V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
349	V4L2_MBUS_DATA_ACTIVE_HIGH,
350	.mbus_type = V4L2_MBUS_PARALLEL,
351	.set_capture = camera_set_capture,
352};
353
354static struct soc_camera_link camera_link = {
355	.bus_id		= 0,
356	.add_device	= ap325rxa_camera_add,
357	.del_device	= ap325rxa_camera_del,
358	.module_name	= "soc_camera_platform",
359	.priv		= &camera_info,
360};
361
362static struct platform_device *camera_device;
363
364static void ap325rxa_camera_release(struct device *dev)
365{
366	soc_camera_platform_release(&camera_device);
367}
368
369static int ap325rxa_camera_add(struct soc_camera_device *icd)
370{
371	int ret = soc_camera_platform_add(icd, &camera_device, &camera_link,
372					  ap325rxa_camera_release, 0);
373	if (ret < 0)
374		return ret;
375
376	ret = camera_probe();
377	if (ret < 0)
378		soc_camera_platform_del(icd, camera_device, &camera_link);
379
380	return ret;
381}
382
383static void ap325rxa_camera_del(struct soc_camera_device *icd)
384{
385	soc_camera_platform_del(icd, camera_device, &camera_link);
386}
387#endif /* CONFIG_I2C */
388
389static int ov7725_power(struct device *dev, int mode)
390{
391	camera_power(0);
392	if (mode)
393		camera_power(1);
394
395	return 0;
396}
397
398static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
399	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
400};
401
402static struct resource ceu_resources[] = {
403	[0] = {
404		.name	= "CEU",
405		.start	= 0xfe910000,
406		.end	= 0xfe91009f,
407		.flags	= IORESOURCE_MEM,
408	},
409	[1] = {
410		.start  = evt2irq(0x880),
411		.flags  = IORESOURCE_IRQ,
412	},
413	[2] = {
414		/* place holder for contiguous memory */
415	},
416};
417
418static struct platform_device ceu_device = {
419	.name		= "sh_mobile_ceu",
420	.id             = 0, /* "ceu0" clock */
421	.num_resources	= ARRAY_SIZE(ceu_resources),
422	.resource	= ceu_resources,
423	.dev		= {
424		.platform_data	= &sh_mobile_ceu_info,
425	},
426};
427
428/* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */
429static struct regulator_consumer_supply fixed3v3_power_consumers[] =
430{
431	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
432	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
433	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
434	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
435};
436
437static struct resource sdhi0_cn3_resources[] = {
438	[0] = {
439		.name	= "SDHI0",
440		.start	= 0x04ce0000,
441		.end	= 0x04ce00ff,
442		.flags	= IORESOURCE_MEM,
443	},
444	[1] = {
445		.start	= evt2irq(0xe80),
446		.flags  = IORESOURCE_IRQ,
447	},
448};
449
450static struct sh_mobile_sdhi_info sdhi0_cn3_data = {
451	.tmio_caps      = MMC_CAP_SDIO_IRQ,
452};
453
454static struct platform_device sdhi0_cn3_device = {
455	.name		= "sh_mobile_sdhi",
456	.id             = 0, /* "sdhi0" clock */
457	.num_resources	= ARRAY_SIZE(sdhi0_cn3_resources),
458	.resource	= sdhi0_cn3_resources,
459	.dev = {
460		.platform_data = &sdhi0_cn3_data,
461	},
462};
463
464static struct resource sdhi1_cn7_resources[] = {
465	[0] = {
466		.name	= "SDHI1",
467		.start	= 0x04cf0000,
468		.end	= 0x04cf00ff,
469		.flags	= IORESOURCE_MEM,
470	},
471	[1] = {
472		.start	= evt2irq(0x4e0),
473		.flags  = IORESOURCE_IRQ,
474	},
475};
476
477static struct sh_mobile_sdhi_info sdhi1_cn7_data = {
478	.tmio_caps      = MMC_CAP_SDIO_IRQ,
479};
480
481static struct platform_device sdhi1_cn7_device = {
482	.name		= "sh_mobile_sdhi",
483	.id             = 1, /* "sdhi1" clock */
484	.num_resources	= ARRAY_SIZE(sdhi1_cn7_resources),
485	.resource	= sdhi1_cn7_resources,
486	.dev = {
487		.platform_data = &sdhi1_cn7_data,
488	},
489};
490
491static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
492	{
493		I2C_BOARD_INFO("pcf8563", 0x51),
494	},
495};
496
497static struct i2c_board_info ap325rxa_i2c_camera[] = {
498	{
499		I2C_BOARD_INFO("ov772x", 0x21),
500	},
501};
502
503static struct ov772x_camera_info ov7725_info = {
504	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
505	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
506};
507
508static struct soc_camera_link ov7725_link = {
509	.bus_id		= 0,
510	.power		= ov7725_power,
511	.board_info	= &ap325rxa_i2c_camera[0],
512	.i2c_adapter_id	= 0,
513	.priv		= &ov7725_info,
514};
515
516static struct platform_device ap325rxa_camera[] = {
517	{
518		.name	= "soc-camera-pdrv",
519		.id	= 0,
520		.dev	= {
521			.platform_data = &ov7725_link,
522		},
523	}, {
524		.name	= "soc-camera-pdrv",
525		.id	= 1,
526		.dev	= {
527			.platform_data = &camera_link,
528		},
529	},
530};
531
532static struct platform_device *ap325rxa_devices[] __initdata = {
533	&smsc9118_device,
534	&ap325rxa_nor_flash_device,
535	&lcdc_device,
536	&ceu_device,
537	&nand_flash_device,
538	&sdhi0_cn3_device,
539	&sdhi1_cn7_device,
540	&ap325rxa_camera[0],
541	&ap325rxa_camera[1],
542};
543
544extern char ap325rxa_sdram_enter_start;
545extern char ap325rxa_sdram_enter_end;
546extern char ap325rxa_sdram_leave_start;
547extern char ap325rxa_sdram_leave_end;
548
549static int __init ap325rxa_devices_setup(void)
550{
551	/* register board specific self-refresh code */
552	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
553					&ap325rxa_sdram_enter_start,
554					&ap325rxa_sdram_enter_end,
555					&ap325rxa_sdram_leave_start,
556					&ap325rxa_sdram_leave_end);
557
558	regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
559				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
560	regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies));
561
562	/* LD3 and LD4 LEDs */
563	gpio_request(GPIO_PTX5, NULL); /* RUN */
564	gpio_direction_output(GPIO_PTX5, 1);
565	gpio_export(GPIO_PTX5, 0);
566
567	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
568	gpio_direction_output(GPIO_PTX4, 0);
569	gpio_export(GPIO_PTX4, 0);
570
571	/* SW1 input */
572	gpio_request(GPIO_PTF7, NULL); /* MODE */
573	gpio_direction_input(GPIO_PTF7);
574	gpio_export(GPIO_PTF7, 0);
575
576	/* LCDC */
577	gpio_request(GPIO_FN_LCDD15, NULL);
578	gpio_request(GPIO_FN_LCDD14, NULL);
579	gpio_request(GPIO_FN_LCDD13, NULL);
580	gpio_request(GPIO_FN_LCDD12, NULL);
581	gpio_request(GPIO_FN_LCDD11, NULL);
582	gpio_request(GPIO_FN_LCDD10, NULL);
583	gpio_request(GPIO_FN_LCDD9, NULL);
584	gpio_request(GPIO_FN_LCDD8, NULL);
585	gpio_request(GPIO_FN_LCDD7, NULL);
586	gpio_request(GPIO_FN_LCDD6, NULL);
587	gpio_request(GPIO_FN_LCDD5, NULL);
588	gpio_request(GPIO_FN_LCDD4, NULL);
589	gpio_request(GPIO_FN_LCDD3, NULL);
590	gpio_request(GPIO_FN_LCDD2, NULL);
591	gpio_request(GPIO_FN_LCDD1, NULL);
592	gpio_request(GPIO_FN_LCDD0, NULL);
593	gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
594	gpio_request(GPIO_FN_LCDDCK, NULL);
595	gpio_request(GPIO_FN_LCDVEPWC, NULL);
596	gpio_request(GPIO_FN_LCDVCPWC, NULL);
597	gpio_request(GPIO_FN_LCDVSYN, NULL);
598	gpio_request(GPIO_FN_LCDHSYN, NULL);
599	gpio_request(GPIO_FN_LCDDISP, NULL);
600	gpio_request(GPIO_FN_LCDDON, NULL);
601
602	/* LCD backlight */
603	gpio_request(GPIO_PTS3, NULL);
604	gpio_direction_output(GPIO_PTS3, 1);
605
606	/* CEU */
607	gpio_request(GPIO_FN_VIO_CLK2, NULL);
608	gpio_request(GPIO_FN_VIO_VD2, NULL);
609	gpio_request(GPIO_FN_VIO_HD2, NULL);
610	gpio_request(GPIO_FN_VIO_FLD, NULL);
611	gpio_request(GPIO_FN_VIO_CKO, NULL);
612	gpio_request(GPIO_FN_VIO_D15, NULL);
613	gpio_request(GPIO_FN_VIO_D14, NULL);
614	gpio_request(GPIO_FN_VIO_D13, NULL);
615	gpio_request(GPIO_FN_VIO_D12, NULL);
616	gpio_request(GPIO_FN_VIO_D11, NULL);
617	gpio_request(GPIO_FN_VIO_D10, NULL);
618	gpio_request(GPIO_FN_VIO_D9, NULL);
619	gpio_request(GPIO_FN_VIO_D8, NULL);
620
621	gpio_request(GPIO_PTZ7, NULL);
622	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
623	gpio_request(GPIO_PTZ6, NULL);
624	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
625	gpio_request(GPIO_PTZ5, NULL);
626	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
627	gpio_request(GPIO_PTZ4, NULL);
628	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
629
630	__raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
631
632	/* FLCTL */
633	gpio_request(GPIO_FN_FCE, NULL);
634	gpio_request(GPIO_FN_NAF7, NULL);
635	gpio_request(GPIO_FN_NAF6, NULL);
636	gpio_request(GPIO_FN_NAF5, NULL);
637	gpio_request(GPIO_FN_NAF4, NULL);
638	gpio_request(GPIO_FN_NAF3, NULL);
639	gpio_request(GPIO_FN_NAF2, NULL);
640	gpio_request(GPIO_FN_NAF1, NULL);
641	gpio_request(GPIO_FN_NAF0, NULL);
642	gpio_request(GPIO_FN_FCDE, NULL);
643	gpio_request(GPIO_FN_FOE, NULL);
644	gpio_request(GPIO_FN_FSC, NULL);
645	gpio_request(GPIO_FN_FWE, NULL);
646	gpio_request(GPIO_FN_FRB, NULL);
647
648	__raw_writew(0, PORT_HIZCRC);
649	__raw_writew(0xFFFF, PORT_DRVCRA);
650	__raw_writew(0xFFFF, PORT_DRVCRB);
651
652	platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
653
654	/* SDHI0 - CN3 - SD CARD */
655	gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
656	gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
657	gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
658	gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
659	gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
660	gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
661	gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
662	gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
663
664	/* SDHI1 - CN7 - MICRO SD CARD */
665	gpio_request(GPIO_FN_SDHI1CD, NULL);
666	gpio_request(GPIO_FN_SDHI1D3, NULL);
667	gpio_request(GPIO_FN_SDHI1D2, NULL);
668	gpio_request(GPIO_FN_SDHI1D1, NULL);
669	gpio_request(GPIO_FN_SDHI1D0, NULL);
670	gpio_request(GPIO_FN_SDHI1CMD, NULL);
671	gpio_request(GPIO_FN_SDHI1CLK, NULL);
672
 
 
 
 
 
 
673	i2c_register_board_info(0, ap325rxa_i2c_devices,
674				ARRAY_SIZE(ap325rxa_i2c_devices));
675
 
 
 
 
 
 
 
 
676	return platform_add_devices(ap325rxa_devices,
677				ARRAY_SIZE(ap325rxa_devices));
678}
679arch_initcall(ap325rxa_devices_setup);
680
681/* Return the board specific boot mode pin configuration */
682static int ap325rxa_mode_pins(void)
683{
684	/* MD0=0, MD1=0, MD2=0: Clock Mode 0
685	 * MD3=0: 16-bit Area0 Bus Width
686	 * MD5=1: Little Endian
687	 * TSTMD=1, MD8=1: Test Mode Disabled
688	 */
689	return MODE_PIN5 | MODE_PIN8;
690}
691
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
692static struct sh_machine_vector mv_ap325rxa __initmv = {
693	.mv_name = "AP-325RXA",
694	.mv_mode_pins = ap325rxa_mode_pins,
 
695};
v6.9.4
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Renesas - AP-325RXA
  4 * (Compatible with Algo System ., LTD. - AP-320A)
  5 *
  6 * Copyright (C) 2008 Renesas Solutions Corp.
  7 * Author : Yusuke Goda <goda.yuske@renesas.com>
 
 
 
 
  8 */
  9
 10#include <asm/clock.h>
 11#include <asm/io.h>
 12#include <asm/suspend.h>
 13
 14#include <cpu/sh7723.h>
 15
 16#include <linux/dma-map-ops.h>
 17#include <linux/clkdev.h>
 18#include <linux/delay.h>
 19#include <linux/device.h>
 20#include <linux/gpio.h>
 21#include <linux/gpio/consumer.h>
 22#include <linux/gpio/machine.h>
 23#include <linux/i2c.h>
 24#include <linux/init.h>
 25#include <linux/interrupt.h>
 26#include <linux/memblock.h>
 27#include <linux/mfd/tmio.h>
 28#include <linux/mmc/host.h>
 
 29#include <linux/mtd/physmap.h>
 30#include <linux/mtd/sh_flctl.h>
 31#include <linux/platform_device.h>
 
 32#include <linux/regulator/fixed.h>
 33#include <linux/regulator/machine.h>
 34#include <linux/sh_intc.h>
 35#include <linux/smsc911x.h>
 
 36#include <linux/videodev2.h>
 37
 38#include <media/drv-intf/renesas-ceu.h>
 39#include <media/i2c/ov772x.h>
 40
 
 41#include <video/sh_mobile_lcdc.h>
 42
 43#define CEU_BUFFER_MEMORY_SIZE		(4 << 20)
 44static phys_addr_t ceu_dma_membase;
 
 45
 46/* Dummy supplies, where voltage doesn't matter */
 47static struct regulator_consumer_supply dummy_supplies[] = {
 48	REGULATOR_SUPPLY("vddvario", "smsc911x"),
 49	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
 50};
 51
 52static struct smsc911x_platform_config smsc911x_config = {
 53	.phy_interface	= PHY_INTERFACE_MODE_MII,
 54	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
 55	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
 56	.flags		= SMSC911X_USE_32BIT,
 57};
 58
 59static struct resource smsc9118_resources[] = {
 60	[0] = {
 61		.start	= 0xb6080000,
 62		.end	= 0xb60fffff,
 63		.flags	= IORESOURCE_MEM,
 64	},
 65	[1] = {
 66		.start	= evt2irq(0x660),
 67		.end	= evt2irq(0x660),
 68		.flags	= IORESOURCE_IRQ,
 69	}
 70};
 71
 72static struct platform_device smsc9118_device = {
 73	.name		= "smsc911x",
 74	.id		= -1,
 75	.num_resources	= ARRAY_SIZE(smsc9118_resources),
 76	.resource	= smsc9118_resources,
 77	.dev		= {
 78		.platform_data = &smsc911x_config,
 79	},
 80};
 81
 82/*
 83 * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
 84 * If this area erased, this board can not boot.
 85 */
 86static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
 87	{
 88		.name = "uboot",
 89		.offset = 0,
 90		.size = (1 * 1024 * 1024),
 91		.mask_flags = MTD_WRITEABLE,	/* Read-only */
 92	}, {
 93		.name = "kernel",
 94		.offset = MTDPART_OFS_APPEND,
 95		.size = (2 * 1024 * 1024),
 96	}, {
 97		.name = "free-area0",
 98		.offset = MTDPART_OFS_APPEND,
 99		.size = ((7 * 1024 * 1024) + (512 * 1024)),
100	}, {
101		.name = "CPLD-Data",
102		.offset = MTDPART_OFS_APPEND,
103		.mask_flags = MTD_WRITEABLE,	/* Read-only */
104		.size = (1024 * 128 * 2),
105	}, {
106		.name = "free-area1",
107		.offset = MTDPART_OFS_APPEND,
108		.size = MTDPART_SIZ_FULL,
109	},
110};
111
112static struct physmap_flash_data ap325rxa_nor_flash_data = {
113	.width		= 2,
114	.parts		= ap325rxa_nor_flash_partitions,
115	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
116};
117
118static struct resource ap325rxa_nor_flash_resources[] = {
119	[0] = {
120		.name	= "NOR Flash",
121		.start	= 0x00000000,
122		.end	= 0x00ffffff,
123		.flags	= IORESOURCE_MEM,
124	}
125};
126
127static struct platform_device ap325rxa_nor_flash_device = {
128	.name		= "physmap-flash",
129	.resource	= ap325rxa_nor_flash_resources,
130	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
131	.dev		= {
132		.platform_data = &ap325rxa_nor_flash_data,
133	},
134};
135
136static struct mtd_partition nand_partition_info[] = {
137	{
138		.name	= "nand_data",
139		.offset	= 0,
140		.size	= MTDPART_SIZ_FULL,
141	},
142};
143
144static struct resource nand_flash_resources[] = {
145	[0] = {
146		.start	= 0xa4530000,
147		.end	= 0xa45300ff,
148		.flags	= IORESOURCE_MEM,
149	}
150};
151
152static struct sh_flctl_platform_data nand_flash_data = {
153	.parts		= nand_partition_info,
154	.nr_parts	= ARRAY_SIZE(nand_partition_info),
155	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
156	.has_hwecc	= 1,
157};
158
159static struct platform_device nand_flash_device = {
160	.name		= "sh_flctl",
161	.resource	= nand_flash_resources,
162	.num_resources	= ARRAY_SIZE(nand_flash_resources),
163	.dev		= {
164		.platform_data = &nand_flash_data,
165	},
166};
167
168#define FPGA_LCDREG	0xB4100180
169#define FPGA_BKLREG	0xB4100212
170#define FPGA_LCDREG_VAL	0x0018
171#define PORT_MSELCRB	0xA4050182
172#define PORT_HIZCRC	0xA405015C
173#define PORT_DRVCRA	0xA405018A
174#define PORT_DRVCRB	0xA405018C
175
176static int ap320_wvga_set_brightness(int brightness)
177{
178	if (brightness) {
179		gpio_set_value(GPIO_PTS3, 0);
180		__raw_writew(0x100, FPGA_BKLREG);
181	} else {
182		__raw_writew(0, FPGA_BKLREG);
183		gpio_set_value(GPIO_PTS3, 1);
184	}
185
186	return 0;
187}
188
189static void ap320_wvga_power_on(void)
190{
191	msleep(100);
192
193	/* ASD AP-320/325 LCD ON */
194	__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
195}
196
197static void ap320_wvga_power_off(void)
198{
199	/* ASD AP-320/325 LCD OFF */
200	__raw_writew(0, FPGA_LCDREG);
201}
202
203static const struct fb_videomode ap325rxa_lcdc_modes[] = {
204	{
205		.name = "LB070WV1",
206		.xres = 800,
207		.yres = 480,
208		.left_margin = 32,
209		.right_margin = 160,
210		.hsync_len = 8,
211		.upper_margin = 63,
212		.lower_margin = 80,
213		.vsync_len = 1,
214		.sync = 0, /* hsync and vsync are active low */
215	},
216};
217
218static struct sh_mobile_lcdc_info lcdc_info = {
219	.clock_source = LCDC_CLK_EXTERNAL,
220	.ch[0] = {
221		.chan = LCDC_CHAN_MAINLCD,
222		.fourcc = V4L2_PIX_FMT_RGB565,
223		.interface_type = RGB18,
224		.clock_divider = 1,
225		.lcd_modes = ap325rxa_lcdc_modes,
226		.num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes),
227		.panel_cfg = {
228			.width = 152,	/* 7.0 inch */
229			.height = 91,
230			.display_on = ap320_wvga_power_on,
231			.display_off = ap320_wvga_power_off,
232		},
233		.bl_info = {
234			.name = "sh_mobile_lcdc_bl",
235			.max_brightness = 1,
236			.set_brightness = ap320_wvga_set_brightness,
237		},
238	}
239};
240
241static struct resource lcdc_resources[] = {
242	[0] = {
243		.name	= "LCDC",
244		.start	= 0xfe940000, /* P4-only space */
245		.end	= 0xfe942fff,
246		.flags	= IORESOURCE_MEM,
247	},
248	[1] = {
249		.start	= evt2irq(0x580),
250		.flags	= IORESOURCE_IRQ,
251	},
252};
253
254static struct platform_device lcdc_device = {
255	.name		= "sh_mobile_lcdc_fb",
256	.num_resources	= ARRAY_SIZE(lcdc_resources),
257	.resource	= lcdc_resources,
258	.dev		= {
259		.platform_data	= &lcdc_info,
260	},
261};
262
263/* Powerdown/reset gpios for CEU image sensors */
264static struct gpiod_lookup_table ov7725_gpios = {
265	.dev_id		= "0-0021",
266	.table		= {
267		GPIO_LOOKUP("sh7723_pfc", GPIO_PTZ5, "reset", GPIO_ACTIVE_LOW),
268	},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269};
270
271static struct ceu_platform_data ceu0_pdata = {
272	.num_subdevs			= 1,
273	.subdevs = {
274		{ /* [0] = ov7725  */
275			.flags		= 0,
276			.bus_width	= 8,
277			.bus_shift	= 0,
278			.i2c_adapter_id	= 0,
279			.i2c_address	= 0x21,
280		},
281	},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282};
283
284static struct resource ceu_resources[] = {
285	[0] = {
286		.name	= "CEU",
287		.start	= 0xfe910000,
288		.end	= 0xfe91009f,
289		.flags	= IORESOURCE_MEM,
290	},
291	[1] = {
292		.start  = evt2irq(0x880),
293		.flags  = IORESOURCE_IRQ,
294	},
 
 
 
295};
296
297static struct platform_device ap325rxa_ceu_device = {
298	.name		= "renesas-ceu",
299	.id             = 0, /* "ceu.0" clock */
300	.num_resources	= ARRAY_SIZE(ceu_resources),
301	.resource	= ceu_resources,
302	.dev		= {
303		.platform_data	= &ceu0_pdata,
304	},
305};
306
307/* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */
308static struct regulator_consumer_supply fixed3v3_power_consumers[] =
309{
310	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
311	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
312	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
313	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
314};
315
316static struct resource sdhi0_cn3_resources[] = {
317	[0] = {
318		.name	= "SDHI0",
319		.start	= 0x04ce0000,
320		.end	= 0x04ce00ff,
321		.flags	= IORESOURCE_MEM,
322	},
323	[1] = {
324		.start	= evt2irq(0xe80),
325		.flags  = IORESOURCE_IRQ,
326	},
327};
328
329static struct tmio_mmc_data sdhi0_cn3_data = {
330	.capabilities	= MMC_CAP_SDIO_IRQ,
331};
332
333static struct platform_device sdhi0_cn3_device = {
334	.name		= "sh_mobile_sdhi",
335	.id             = 0, /* "sdhi0" clock */
336	.num_resources	= ARRAY_SIZE(sdhi0_cn3_resources),
337	.resource	= sdhi0_cn3_resources,
338	.dev = {
339		.platform_data = &sdhi0_cn3_data,
340	},
341};
342
343static struct resource sdhi1_cn7_resources[] = {
344	[0] = {
345		.name	= "SDHI1",
346		.start	= 0x04cf0000,
347		.end	= 0x04cf00ff,
348		.flags	= IORESOURCE_MEM,
349	},
350	[1] = {
351		.start	= evt2irq(0x4e0),
352		.flags  = IORESOURCE_IRQ,
353	},
354};
355
356static struct tmio_mmc_data sdhi1_cn7_data = {
357	.capabilities	= MMC_CAP_SDIO_IRQ,
358};
359
360static struct platform_device sdhi1_cn7_device = {
361	.name		= "sh_mobile_sdhi",
362	.id             = 1, /* "sdhi1" clock */
363	.num_resources	= ARRAY_SIZE(sdhi1_cn7_resources),
364	.resource	= sdhi1_cn7_resources,
365	.dev = {
366		.platform_data = &sdhi1_cn7_data,
367	},
368};
369
 
 
 
 
 
 
 
 
 
 
 
 
370static struct ov772x_camera_info ov7725_info = {
371	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
372	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
373};
374
375static struct i2c_board_info ap325rxa_i2c_devices[] __initdata = {
 
 
 
 
 
 
 
 
376	{
377		I2C_BOARD_INFO("pcf8563", 0x51),
378	},
379	{
380		I2C_BOARD_INFO("ov772x", 0x21),
381		.platform_data = &ov7725_info,
 
 
 
 
 
 
382	},
383};
384
385static struct platform_device *ap325rxa_devices[] __initdata = {
386	&smsc9118_device,
387	&ap325rxa_nor_flash_device,
388	&lcdc_device,
 
389	&nand_flash_device,
390	&sdhi0_cn3_device,
391	&sdhi1_cn7_device,
 
 
392};
393
394extern char ap325rxa_sdram_enter_start;
395extern char ap325rxa_sdram_enter_end;
396extern char ap325rxa_sdram_leave_start;
397extern char ap325rxa_sdram_leave_end;
398
399static int __init ap325rxa_devices_setup(void)
400{
401	/* register board specific self-refresh code */
402	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
403					&ap325rxa_sdram_enter_start,
404					&ap325rxa_sdram_enter_end,
405					&ap325rxa_sdram_leave_start,
406					&ap325rxa_sdram_leave_end);
407
408	regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
409				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
410	regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies));
411
412	/* LD3 and LD4 LEDs */
413	gpio_request(GPIO_PTX5, NULL); /* RUN */
414	gpio_direction_output(GPIO_PTX5, 1);
415	gpiod_export(gpio_to_desc(GPIO_PTX5), 0);
416
417	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
418	gpio_direction_output(GPIO_PTX4, 0);
419	gpiod_export(gpio_to_desc(GPIO_PTX4), 0);
420
421	/* SW1 input */
422	gpio_request(GPIO_PTF7, NULL); /* MODE */
423	gpio_direction_input(GPIO_PTF7);
424	gpiod_export(gpio_to_desc(GPIO_PTF7), 0);
425
426	/* LCDC */
427	gpio_request(GPIO_FN_LCDD15, NULL);
428	gpio_request(GPIO_FN_LCDD14, NULL);
429	gpio_request(GPIO_FN_LCDD13, NULL);
430	gpio_request(GPIO_FN_LCDD12, NULL);
431	gpio_request(GPIO_FN_LCDD11, NULL);
432	gpio_request(GPIO_FN_LCDD10, NULL);
433	gpio_request(GPIO_FN_LCDD9, NULL);
434	gpio_request(GPIO_FN_LCDD8, NULL);
435	gpio_request(GPIO_FN_LCDD7, NULL);
436	gpio_request(GPIO_FN_LCDD6, NULL);
437	gpio_request(GPIO_FN_LCDD5, NULL);
438	gpio_request(GPIO_FN_LCDD4, NULL);
439	gpio_request(GPIO_FN_LCDD3, NULL);
440	gpio_request(GPIO_FN_LCDD2, NULL);
441	gpio_request(GPIO_FN_LCDD1, NULL);
442	gpio_request(GPIO_FN_LCDD0, NULL);
443	gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
444	gpio_request(GPIO_FN_LCDDCK, NULL);
445	gpio_request(GPIO_FN_LCDVEPWC, NULL);
446	gpio_request(GPIO_FN_LCDVCPWC, NULL);
447	gpio_request(GPIO_FN_LCDVSYN, NULL);
448	gpio_request(GPIO_FN_LCDHSYN, NULL);
449	gpio_request(GPIO_FN_LCDDISP, NULL);
450	gpio_request(GPIO_FN_LCDDON, NULL);
451
452	/* LCD backlight */
453	gpio_request(GPIO_PTS3, NULL);
454	gpio_direction_output(GPIO_PTS3, 1);
455
456	/* CEU */
457	gpio_request(GPIO_FN_VIO_CLK2, NULL);
458	gpio_request(GPIO_FN_VIO_VD2, NULL);
459	gpio_request(GPIO_FN_VIO_HD2, NULL);
460	gpio_request(GPIO_FN_VIO_FLD, NULL);
461	gpio_request(GPIO_FN_VIO_CKO, NULL);
462	gpio_request(GPIO_FN_VIO_D15, NULL);
463	gpio_request(GPIO_FN_VIO_D14, NULL);
464	gpio_request(GPIO_FN_VIO_D13, NULL);
465	gpio_request(GPIO_FN_VIO_D12, NULL);
466	gpio_request(GPIO_FN_VIO_D11, NULL);
467	gpio_request(GPIO_FN_VIO_D10, NULL);
468	gpio_request(GPIO_FN_VIO_D9, NULL);
469	gpio_request(GPIO_FN_VIO_D8, NULL);
470
471	gpio_request(GPIO_PTZ7, NULL);
472	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
473	gpio_request(GPIO_PTZ6, NULL);
474	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
475	gpio_request(GPIO_PTZ5, NULL);
476	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
477	gpio_request(GPIO_PTZ4, NULL);
478	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
479
480	__raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
481
482	/* FLCTL */
483	gpio_request(GPIO_FN_FCE, NULL);
484	gpio_request(GPIO_FN_NAF7, NULL);
485	gpio_request(GPIO_FN_NAF6, NULL);
486	gpio_request(GPIO_FN_NAF5, NULL);
487	gpio_request(GPIO_FN_NAF4, NULL);
488	gpio_request(GPIO_FN_NAF3, NULL);
489	gpio_request(GPIO_FN_NAF2, NULL);
490	gpio_request(GPIO_FN_NAF1, NULL);
491	gpio_request(GPIO_FN_NAF0, NULL);
492	gpio_request(GPIO_FN_FCDE, NULL);
493	gpio_request(GPIO_FN_FOE, NULL);
494	gpio_request(GPIO_FN_FSC, NULL);
495	gpio_request(GPIO_FN_FWE, NULL);
496	gpio_request(GPIO_FN_FRB, NULL);
497
498	__raw_writew(0, PORT_HIZCRC);
499	__raw_writew(0xFFFF, PORT_DRVCRA);
500	__raw_writew(0xFFFF, PORT_DRVCRB);
501
 
 
502	/* SDHI0 - CN3 - SD CARD */
503	gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
504	gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
505	gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
506	gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
507	gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
508	gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
509	gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
510	gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
511
512	/* SDHI1 - CN7 - MICRO SD CARD */
513	gpio_request(GPIO_FN_SDHI1CD, NULL);
514	gpio_request(GPIO_FN_SDHI1D3, NULL);
515	gpio_request(GPIO_FN_SDHI1D2, NULL);
516	gpio_request(GPIO_FN_SDHI1D1, NULL);
517	gpio_request(GPIO_FN_SDHI1D0, NULL);
518	gpio_request(GPIO_FN_SDHI1CMD, NULL);
519	gpio_request(GPIO_FN_SDHI1CLK, NULL);
520
521	/* Add a clock alias for ov7725 xclk source. */
522	clk_add_alias(NULL, "0-0021", "video_clk", NULL);
523
524	/* Register RSTB gpio for ov7725 camera sensor. */
525	gpiod_add_lookup_table(&ov7725_gpios);
526
527	i2c_register_board_info(0, ap325rxa_i2c_devices,
528				ARRAY_SIZE(ap325rxa_i2c_devices));
529
530	/* Initialize CEU platform device separately to map memory first */
531	device_initialize(&ap325rxa_ceu_device.dev);
532	dma_declare_coherent_memory(&ap325rxa_ceu_device.dev,
533			ceu_dma_membase, ceu_dma_membase,
534			CEU_BUFFER_MEMORY_SIZE);
535
536	platform_device_add(&ap325rxa_ceu_device);
537
538	return platform_add_devices(ap325rxa_devices,
539				ARRAY_SIZE(ap325rxa_devices));
540}
541arch_initcall(ap325rxa_devices_setup);
542
543/* Return the board specific boot mode pin configuration */
544static int ap325rxa_mode_pins(void)
545{
546	/* MD0=0, MD1=0, MD2=0: Clock Mode 0
547	 * MD3=0: 16-bit Area0 Bus Width
548	 * MD5=1: Little Endian
549	 * TSTMD=1, MD8=1: Test Mode Disabled
550	 */
551	return MODE_PIN5 | MODE_PIN8;
552}
553
554/* Reserve a portion of memory for CEU buffers */
555static void __init ap325rxa_mv_mem_reserve(void)
556{
557	phys_addr_t phys;
558	phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
559
560	phys = memblock_phys_alloc(size, PAGE_SIZE);
561	if (!phys)
562		panic("Failed to allocate CEU memory\n");
563
564	memblock_phys_free(phys, size);
565	memblock_remove(phys, size);
566
567	ceu_dma_membase = phys;
568}
569
570static struct sh_machine_vector mv_ap325rxa __initmv = {
571	.mv_name = "AP-325RXA",
572	.mv_mode_pins = ap325rxa_mode_pins,
573	.mv_mem_reserve	= ap325rxa_mv_mem_reserve,
574};