blob: f33ebf447073d7800ed420e6456f28ebee043722 [file] [log] [blame]
Yusuke Goda04e917b2008-06-06 17:03:23 +09001/*
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>
Magnus Damm4875ea22008-07-28 19:11:07 +090015#include <linux/interrupt.h>
Yusuke Goda04e917b2008-06-06 17:03:23 +090016#include <linux/platform_device.h>
Arnd Hannemann365e1082010-12-28 22:22:36 +000017#include <linux/mmc/host.h>
Guennadi Liakhovetski960b9e72011-03-09 11:29:48 +010018#include <linux/mmc/sh_mobile_sdhi.h>
Yusuke Goda04e917b2008-06-06 17:03:23 +090019#include <linux/mtd/physmap.h>
Yoshihiro Shimoda908978a2008-09-09 17:17:42 +090020#include <linux/mtd/sh_flctl.h>
Yusuke Goda04e917b2008-06-06 17:03:23 +090021#include <linux/delay.h>
Magnus Damm026953d2008-07-05 12:32:44 +090022#include <linux/i2c.h>
Steve Glendinning90b76492009-01-07 17:20:07 +090023#include <linux/smsc911x.h>
Magnus Damm16587c42008-10-08 20:42:20 +090024#include <linux/gpio.h>
Guennadi Liakhovetskia1ad8032012-01-25 22:07:05 +010025#include <linux/videodev2.h>
Paul Mundt9c23c512012-05-18 15:45:09 +090026#include <linux/sh_intc.h>
Kuninori Morimoto47131252009-01-22 00:38:31 +000027#include <media/ov772x.h>
Nobuhiro Iwamatsuba087e62009-03-06 02:51:14 +000028#include <media/soc_camera.h>
Magnus Damm8b2224d2008-07-28 19:14:35 +090029#include <media/soc_camera_platform.h>
30#include <media/sh_mobile_ceu.h>
Paul Mundt225c9a82008-10-01 16:24:32 +090031#include <video/sh_mobile_lcdc.h>
Yusuke Goda04e917b2008-06-06 17:03:23 +090032#include <asm/io.h>
Magnus Damm6968980a2008-07-28 19:07:04 +090033#include <asm/clock.h>
Magnus Damm86c7d032009-10-30 04:23:51 +000034#include <asm/suspend.h>
Paul Mundtf7275652008-10-20 12:04:53 +090035#include <cpu/sh7723.h>
Yusuke Goda04e917b2008-06-06 17:03:23 +090036
Steve Glendinning90b76492009-01-07 17:20:07 +090037static struct smsc911x_platform_config smsc911x_config = {
38 .phy_interface = PHY_INTERFACE_MODE_MII,
39 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
40 .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
41 .flags = SMSC911X_USE_32BIT,
Magnus Damm4875ea22008-07-28 19:11:07 +090042};
43
Steve Glendinning90b76492009-01-07 17:20:07 +090044static struct resource smsc9118_resources[] = {
Yusuke Goda04e917b2008-06-06 17:03:23 +090045 [0] = {
46 .start = 0xb6080000,
47 .end = 0xb60fffff,
48 .flags = IORESOURCE_MEM,
49 },
50 [1] = {
Paul Mundt9c23c512012-05-18 15:45:09 +090051 .start = evt2irq(0x660),
52 .end = evt2irq(0x660),
Yusuke Goda04e917b2008-06-06 17:03:23 +090053 .flags = IORESOURCE_IRQ,
54 }
55};
56
Steve Glendinning90b76492009-01-07 17:20:07 +090057static struct platform_device smsc9118_device = {
58 .name = "smsc911x",
Yusuke Goda04e917b2008-06-06 17:03:23 +090059 .id = -1,
Steve Glendinning90b76492009-01-07 17:20:07 +090060 .num_resources = ARRAY_SIZE(smsc9118_resources),
61 .resource = smsc9118_resources,
Magnus Damm4875ea22008-07-28 19:11:07 +090062 .dev = {
Steve Glendinning90b76492009-01-07 17:20:07 +090063 .platform_data = &smsc911x_config,
Magnus Damm4875ea22008-07-28 19:11:07 +090064 },
Yusuke Goda04e917b2008-06-06 17:03:23 +090065};
66
Nobuhiro Iwamatsuaa88f162008-09-24 11:46:48 +090067/*
68 * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
69 * If this area erased, this board can not boot.
70 */
Yusuke Goda04e917b2008-06-06 17:03:23 +090071static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
72 {
Nobuhiro Iwamatsuaa88f162008-09-24 11:46:48 +090073 .name = "uboot",
74 .offset = 0,
75 .size = (1 * 1024 * 1024),
76 .mask_flags = MTD_WRITEABLE, /* Read-only */
Yusuke Goda04e917b2008-06-06 17:03:23 +090077 }, {
Nobuhiro Iwamatsuaa88f162008-09-24 11:46:48 +090078 .name = "kernel",
79 .offset = MTDPART_OFS_APPEND,
80 .size = (2 * 1024 * 1024),
Yusuke Goda04e917b2008-06-06 17:03:23 +090081 }, {
Nobuhiro Iwamatsuaa88f162008-09-24 11:46:48 +090082 .name = "free-area0",
83 .offset = MTDPART_OFS_APPEND,
84 .size = ((7 * 1024 * 1024) + (512 * 1024)),
85 }, {
86 .name = "CPLD-Data",
87 .offset = MTDPART_OFS_APPEND,
88 .mask_flags = MTD_WRITEABLE, /* Read-only */
89 .size = (1024 * 128 * 2),
90 }, {
91 .name = "free-area1",
92 .offset = MTDPART_OFS_APPEND,
93 .size = MTDPART_SIZ_FULL,
Yusuke Goda04e917b2008-06-06 17:03:23 +090094 },
95};
96
97static struct physmap_flash_data ap325rxa_nor_flash_data = {
98 .width = 2,
99 .parts = ap325rxa_nor_flash_partitions,
100 .nr_parts = ARRAY_SIZE(ap325rxa_nor_flash_partitions),
101};
102
103static struct resource ap325rxa_nor_flash_resources[] = {
104 [0] = {
105 .name = "NOR Flash",
106 .start = 0x00000000,
107 .end = 0x00ffffff,
108 .flags = IORESOURCE_MEM,
109 }
110};
111
112static struct platform_device ap325rxa_nor_flash_device = {
113 .name = "physmap-flash",
114 .resource = ap325rxa_nor_flash_resources,
115 .num_resources = ARRAY_SIZE(ap325rxa_nor_flash_resources),
116 .dev = {
117 .platform_data = &ap325rxa_nor_flash_data,
118 },
119};
120
Yoshihiro Shimoda908978a2008-09-09 17:17:42 +0900121static struct mtd_partition nand_partition_info[] = {
122 {
123 .name = "nand_data",
124 .offset = 0,
125 .size = MTDPART_SIZ_FULL,
126 },
127};
128
129static struct resource nand_flash_resources[] = {
130 [0] = {
131 .start = 0xa4530000,
132 .end = 0xa45300ff,
133 .flags = IORESOURCE_MEM,
134 }
135};
136
137static struct sh_flctl_platform_data nand_flash_data = {
138 .parts = nand_partition_info,
139 .nr_parts = ARRAY_SIZE(nand_partition_info),
140 .flcmncr_val = FCKSEL_E | TYPESEL_SET | NANWF_E,
141 .has_hwecc = 1,
142};
143
144static struct platform_device nand_flash_device = {
145 .name = "sh_flctl",
146 .resource = nand_flash_resources,
147 .num_resources = ARRAY_SIZE(nand_flash_resources),
148 .dev = {
149 .platform_data = &nand_flash_data,
150 },
151};
152
Magnus Damm6968980a2008-07-28 19:07:04 +0900153#define FPGA_LCDREG 0xB4100180
154#define FPGA_BKLREG 0xB4100212
155#define FPGA_LCDREG_VAL 0x0018
Magnus Damm8b2224d2008-07-28 19:14:35 +0900156#define PORT_MSELCRB 0xA4050182
Yoshihiro Shimoda908978a2008-09-09 17:17:42 +0900157#define PORT_HIZCRC 0xA405015C
158#define PORT_DRVCRA 0xA405018A
159#define PORT_DRVCRB 0xA405018C
Magnus Damm6968980a2008-07-28 19:07:04 +0900160
Laurent Pinchart018882a2011-09-11 22:59:04 +0200161static int ap320_wvga_set_brightness(int brightness)
Alexandre Courbotbacbe552011-02-16 03:49:03 +0000162{
163 if (brightness) {
164 gpio_set_value(GPIO_PTS3, 0);
165 __raw_writew(0x100, FPGA_BKLREG);
166 } else {
167 __raw_writew(0, FPGA_BKLREG);
168 gpio_set_value(GPIO_PTS3, 1);
169 }
Paul Mundt9c23c512012-05-18 15:45:09 +0900170
Alexandre Courbotbacbe552011-02-16 03:49:03 +0000171 return 0;
172}
173
Laurent Pinchart018882a2011-09-11 22:59:04 +0200174static int ap320_wvga_get_brightness(void)
Alexandre Courbotbacbe552011-02-16 03:49:03 +0000175{
176 return gpio_get_value(GPIO_PTS3);
177}
178
Laurent Pinchart018882a2011-09-11 22:59:04 +0200179static void ap320_wvga_power_on(void)
Magnus Damm6968980a2008-07-28 19:07:04 +0900180{
181 msleep(100);
182
183 /* ASD AP-320/325 LCD ON */
Paul Mundt9d56dd32010-01-26 12:58:40 +0900184 __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
Magnus Damm6968980a2008-07-28 19:07:04 +0900185}
186
Laurent Pinchart018882a2011-09-11 22:59:04 +0200187static void ap320_wvga_power_off(void)
Magnus Damm93356d02009-03-13 15:27:14 +0000188{
Magnus Damm93356d02009-03-13 15:27:14 +0000189 /* ASD AP-320/325 LCD OFF */
Paul Mundt9d56dd32010-01-26 12:58:40 +0900190 __raw_writew(0, FPGA_LCDREG);
Magnus Damm93356d02009-03-13 15:27:14 +0000191}
192
Jesper Juhle04008e2011-07-09 23:16:22 +0200193static const struct fb_videomode ap325rxa_lcdc_modes[] = {
Guennadi Liakhovetski44432402010-09-03 07:20:04 +0000194 {
195 .name = "LB070WV1",
196 .xres = 800,
197 .yres = 480,
198 .left_margin = 32,
199 .right_margin = 160,
200 .hsync_len = 8,
201 .upper_margin = 63,
202 .lower_margin = 80,
203 .vsync_len = 1,
204 .sync = 0, /* hsync and vsync are active low */
205 },
206};
207
Magnus Damm6968980a2008-07-28 19:07:04 +0900208static struct sh_mobile_lcdc_info lcdc_info = {
209 .clock_source = LCDC_CLK_EXTERNAL,
210 .ch[0] = {
211 .chan = LCDC_CHAN_MAINLCD,
Laurent Pinchartedd153a2011-12-13 14:02:28 +0100212 .fourcc = V4L2_PIX_FMT_RGB565,
Magnus Damm6968980a2008-07-28 19:07:04 +0900213 .interface_type = RGB18,
214 .clock_divider = 1,
Laurent Pinchart93ff2592011-11-29 14:33:41 +0100215 .lcd_modes = ap325rxa_lcdc_modes,
216 .num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes),
Laurent Pinchartafaad832011-09-11 22:59:04 +0200217 .panel_cfg = {
218 .width = 152, /* 7.0 inch */
Magnus Dammce9c0082008-08-11 15:26:00 +0900219 .height = 91,
Magnus Damm6968980a2008-07-28 19:07:04 +0900220 .display_on = ap320_wvga_power_on,
Magnus Damm93356d02009-03-13 15:27:14 +0000221 .display_off = ap320_wvga_power_off,
Alexandre Courbotbacbe552011-02-16 03:49:03 +0000222 },
223 .bl_info = {
224 .name = "sh_mobile_lcdc_bl",
225 .max_brightness = 1,
Laurent Pinchart43059b02011-09-11 22:59:04 +0200226 .set_brightness = ap320_wvga_set_brightness,
227 .get_brightness = ap320_wvga_get_brightness,
Magnus Damm6968980a2008-07-28 19:07:04 +0900228 },
229 }
230};
231
232static struct resource lcdc_resources[] = {
233 [0] = {
234 .name = "LCDC",
235 .start = 0xfe940000, /* P4-only space */
Phil Edworthya6f15ad2009-09-15 12:00:30 +0000236 .end = 0xfe942fff,
Magnus Damm6968980a2008-07-28 19:07:04 +0900237 .flags = IORESOURCE_MEM,
238 },
Magnus Damm07905552008-12-19 12:02:16 +0900239 [1] = {
Paul Mundt9c23c512012-05-18 15:45:09 +0900240 .start = evt2irq(0x580),
Magnus Damm07905552008-12-19 12:02:16 +0900241 .flags = IORESOURCE_IRQ,
242 },
Magnus Damm6968980a2008-07-28 19:07:04 +0900243};
244
245static struct platform_device lcdc_device = {
246 .name = "sh_mobile_lcdc_fb",
247 .num_resources = ARRAY_SIZE(lcdc_resources),
248 .resource = lcdc_resources,
249 .dev = {
250 .platform_data = &lcdc_info,
251 },
252};
253
Kuninori Morimoto86746282009-01-22 00:33:21 +0000254static void camera_power(int val)
255{
256 gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
257 mdelay(10);
258}
259
Magnus Damme565b512008-07-29 20:57:38 +0900260#ifdef CONFIG_I2C
Kuninori Morimoto47131252009-01-22 00:38:31 +0000261/* support for the old ncm03j camera */
Magnus Damm8b2224d2008-07-28 19:14:35 +0900262static unsigned char camera_ncm03j_magic[] =
263{
264 0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
265 0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,
266 0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,
267 0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,
268 0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,
269 0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,
270 0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,
271 0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,
272 0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,
273 0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,
274 0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,
275 0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,
276 0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,
277 0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,
278 0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,
279 0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
280};
281
Kuninori Morimoto47131252009-01-22 00:38:31 +0000282static int camera_probe(void)
283{
284 struct i2c_adapter *a = i2c_get_adapter(0);
285 struct i2c_msg msg;
286 int ret;
287
Magnus Damm37869fa2009-05-20 14:30:06 +0000288 if (!a)
289 return -ENODEV;
290
Kuninori Morimoto47131252009-01-22 00:38:31 +0000291 camera_power(1);
292 msg.addr = 0x6e;
293 msg.buf = camera_ncm03j_magic;
294 msg.len = 2;
295 msg.flags = 0;
296 ret = i2c_transfer(a, &msg, 1);
297 camera_power(0);
298
299 return ret;
300}
301
Magnus Damm8b2224d2008-07-28 19:14:35 +0900302static int camera_set_capture(struct soc_camera_platform_info *info,
303 int enable)
304{
305 struct i2c_adapter *a = i2c_get_adapter(0);
306 struct i2c_msg msg;
307 int ret = 0;
308 int i;
309
Kuninori Morimoto86746282009-01-22 00:33:21 +0000310 camera_power(0);
Magnus Damm8b2224d2008-07-28 19:14:35 +0900311 if (!enable)
312 return 0; /* no disable for now */
313
Kuninori Morimoto86746282009-01-22 00:33:21 +0000314 camera_power(1);
Magnus Damm8b2224d2008-07-28 19:14:35 +0900315 for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
316 u_int8_t buf[8];
317
318 msg.addr = 0x6e;
319 msg.buf = buf;
320 msg.len = 2;
321 msg.flags = 0;
322
323 buf[0] = camera_ncm03j_magic[i];
324 buf[1] = camera_ncm03j_magic[i + 1];
325
326 ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);
327 }
328
329 return ret;
330}
331
Guennadi Liakhovetski7dfff952011-07-15 20:03:38 -0300332static int ap325rxa_camera_add(struct soc_camera_device *icd);
333static void ap325rxa_camera_del(struct soc_camera_device *icd);
Guennadi Liakhovetskic41deba2009-08-25 11:06:21 -0300334
Magnus Damm8b2224d2008-07-28 19:14:35 +0900335static struct soc_camera_platform_info camera_info = {
Magnus Damm8b2224d2008-07-28 19:14:35 +0900336 .format_name = "UYVY",
337 .format_depth = 16,
338 .format = {
Guennadi Liakhovetskiace6e972010-07-22 16:52:51 -0300339 .code = V4L2_MBUS_FMT_UYVY8_2X8,
Magnus Damm8b2224d2008-07-28 19:14:35 +0900340 .colorspace = V4L2_COLORSPACE_SMPTE170M,
Guennadi Liakhovetski760697b2009-12-11 11:46:49 -0300341 .field = V4L2_FIELD_NONE,
Magnus Damm8b2224d2008-07-28 19:14:35 +0900342 .width = 640,
343 .height = 480,
344 },
Guennadi Liakhovetski7e5cf0a2011-07-27 10:52:36 -0300345 .mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
346 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
347 V4L2_MBUS_DATA_ACTIVE_HIGH,
348 .mbus_type = V4L2_MBUS_PARALLEL,
Magnus Damm8b2224d2008-07-28 19:14:35 +0900349 .set_capture = camera_set_capture,
Guennadi Liakhovetski0f448292009-12-11 11:31:35 -0300350};
351
Kuninori Morimotof4cdd752010-06-02 00:27:26 +0000352static struct soc_camera_link camera_link = {
Guennadi Liakhovetski0f448292009-12-11 11:31:35 -0300353 .bus_id = 0,
354 .add_device = ap325rxa_camera_add,
355 .del_device = ap325rxa_camera_del,
356 .module_name = "soc_camera_platform",
357 .priv = &camera_info,
Magnus Damm8b2224d2008-07-28 19:14:35 +0900358};
359
Guennadi Liakhovetskia3793a02011-02-22 09:57:44 +0000360static struct platform_device *camera_device;
Guennadi Liakhovetski0bab8292009-08-25 11:34:18 -0300361
Guennadi Liakhovetskia3793a02011-02-22 09:57:44 +0000362static void ap325rxa_camera_release(struct device *dev)
363{
364 soc_camera_platform_release(&camera_device);
365}
Kuninori Morimoto47131252009-01-22 00:38:31 +0000366
Guennadi Liakhovetski7dfff952011-07-15 20:03:38 -0300367static int ap325rxa_camera_add(struct soc_camera_device *icd)
Kuninori Morimoto47131252009-01-22 00:38:31 +0000368{
Guennadi Liakhovetski7dfff952011-07-15 20:03:38 -0300369 int ret = soc_camera_platform_add(icd, &camera_device, &camera_link,
Guennadi Liakhovetskia3793a02011-02-22 09:57:44 +0000370 ap325rxa_camera_release, 0);
371 if (ret < 0)
372 return ret;
Kuninori Morimoto47131252009-01-22 00:38:31 +0000373
Guennadi Liakhovetskia3793a02011-02-22 09:57:44 +0000374 ret = camera_probe();
375 if (ret < 0)
Guennadi Liakhovetski7dfff952011-07-15 20:03:38 -0300376 soc_camera_platform_del(icd, camera_device, &camera_link);
Guennadi Liakhovetskibc1937b2009-08-25 11:06:22 -0300377
Guennadi Liakhovetskia3793a02011-02-22 09:57:44 +0000378 return ret;
Kuninori Morimoto47131252009-01-22 00:38:31 +0000379}
Kuninori Morimoto47131252009-01-22 00:38:31 +0000380
Guennadi Liakhovetski7dfff952011-07-15 20:03:38 -0300381static void ap325rxa_camera_del(struct soc_camera_device *icd)
Guennadi Liakhovetskic41deba2009-08-25 11:06:21 -0300382{
Guennadi Liakhovetski7dfff952011-07-15 20:03:38 -0300383 soc_camera_platform_del(icd, camera_device, &camera_link);
Guennadi Liakhovetskic41deba2009-08-25 11:06:21 -0300384}
Magnus Damme565b512008-07-29 20:57:38 +0900385#endif /* CONFIG_I2C */
Magnus Damm8b2224d2008-07-28 19:14:35 +0900386
Kuninori Morimoto47131252009-01-22 00:38:31 +0000387static int ov7725_power(struct device *dev, int mode)
388{
389 camera_power(0);
390 if (mode)
391 camera_power(1);
392
393 return 0;
394}
395
Magnus Damm8b2224d2008-07-28 19:14:35 +0900396static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
Kuninori Morimoto46368fa2009-03-11 07:20:32 +0000397 .flags = SH_CEU_FLAG_USE_8BIT_BUS,
Magnus Damm8b2224d2008-07-28 19:14:35 +0900398};
399
400static struct resource ceu_resources[] = {
401 [0] = {
402 .name = "CEU",
403 .start = 0xfe910000,
404 .end = 0xfe91009f,
405 .flags = IORESOURCE_MEM,
406 },
407 [1] = {
Paul Mundt9c23c512012-05-18 15:45:09 +0900408 .start = evt2irq(0x880),
Magnus Damm8b2224d2008-07-28 19:14:35 +0900409 .flags = IORESOURCE_IRQ,
410 },
411 [2] = {
412 /* place holder for contiguous memory */
413 },
414};
415
416static struct platform_device ceu_device = {
417 .name = "sh_mobile_ceu",
Magnus Damma42b6dd2008-10-31 20:21:44 +0900418 .id = 0, /* "ceu0" clock */
Magnus Damm8b2224d2008-07-28 19:14:35 +0900419 .num_resources = ARRAY_SIZE(ceu_resources),
420 .resource = ceu_resources,
421 .dev = {
422 .platform_data = &sh_mobile_ceu_info,
423 },
424};
425
Magnus Damm17f81472009-10-02 02:22:56 +0000426static struct resource sdhi0_cn3_resources[] = {
427 [0] = {
428 .name = "SDHI0",
429 .start = 0x04ce0000,
Guennadi Liakhovetskid80e9222011-03-09 13:42:42 +0100430 .end = 0x04ce00ff,
Magnus Damm17f81472009-10-02 02:22:56 +0000431 .flags = IORESOURCE_MEM,
432 },
433 [1] = {
Paul Mundt9c23c512012-05-18 15:45:09 +0900434 .start = evt2irq(0xe80),
Magnus Damm17f81472009-10-02 02:22:56 +0000435 .flags = IORESOURCE_IRQ,
436 },
Magnus Dammfbdd9a72009-01-07 20:35:21 +0900437};
438
Arnd Hannemann365e1082010-12-28 22:22:36 +0000439static struct sh_mobile_sdhi_info sdhi0_cn3_data = {
440 .tmio_caps = MMC_CAP_SDIO_IRQ,
441};
442
Magnus Damm17f81472009-10-02 02:22:56 +0000443static struct platform_device sdhi0_cn3_device = {
444 .name = "sh_mobile_sdhi",
Magnus Damm8b431a72009-10-30 06:22:03 +0000445 .id = 0, /* "sdhi0" clock */
Magnus Damm17f81472009-10-02 02:22:56 +0000446 .num_resources = ARRAY_SIZE(sdhi0_cn3_resources),
447 .resource = sdhi0_cn3_resources,
Arnd Hannemann365e1082010-12-28 22:22:36 +0000448 .dev = {
449 .platform_data = &sdhi0_cn3_data,
450 },
Magnus Dammfbdd9a72009-01-07 20:35:21 +0900451};
452
Magnus Damm8b431a72009-10-30 06:22:03 +0000453static struct resource sdhi1_cn7_resources[] = {
454 [0] = {
455 .name = "SDHI1",
456 .start = 0x04cf0000,
Guennadi Liakhovetskid80e9222011-03-09 13:42:42 +0100457 .end = 0x04cf00ff,
Magnus Damm8b431a72009-10-30 06:22:03 +0000458 .flags = IORESOURCE_MEM,
459 },
460 [1] = {
Paul Mundt9c23c512012-05-18 15:45:09 +0900461 .start = evt2irq(0x4e0),
Magnus Damm8b431a72009-10-30 06:22:03 +0000462 .flags = IORESOURCE_IRQ,
463 },
464};
465
Arnd Hannemann365e1082010-12-28 22:22:36 +0000466static struct sh_mobile_sdhi_info sdhi1_cn7_data = {
467 .tmio_caps = MMC_CAP_SDIO_IRQ,
468};
469
Magnus Damm8b431a72009-10-30 06:22:03 +0000470static struct platform_device sdhi1_cn7_device = {
471 .name = "sh_mobile_sdhi",
472 .id = 1, /* "sdhi1" clock */
473 .num_resources = ARRAY_SIZE(sdhi1_cn7_resources),
474 .resource = sdhi1_cn7_resources,
Arnd Hannemann365e1082010-12-28 22:22:36 +0000475 .dev = {
476 .platform_data = &sdhi1_cn7_data,
477 },
Magnus Damm8b431a72009-10-30 06:22:03 +0000478};
479
Guennadi Liakhovetski194a1732009-05-12 15:13:36 +0000480static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
481 {
482 I2C_BOARD_INFO("pcf8563", 0x51),
483 },
484};
485
486static struct i2c_board_info ap325rxa_i2c_camera[] = {
487 {
488 I2C_BOARD_INFO("ov772x", 0x21),
489 },
490};
491
492static struct ov772x_camera_info ov7725_info = {
Guennadi Liakhovetski284f28e2011-07-28 18:24:25 -0300493 .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
Guennadi Liakhovetski194a1732009-05-12 15:13:36 +0000494 .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
Guennadi Liakhovetski0f448292009-12-11 11:31:35 -0300495};
496
497static struct soc_camera_link ov7725_link = {
498 .bus_id = 0,
499 .power = ov7725_power,
500 .board_info = &ap325rxa_i2c_camera[0],
501 .i2c_adapter_id = 0,
Guennadi Liakhovetski0f448292009-12-11 11:31:35 -0300502 .priv = &ov7725_info,
Guennadi Liakhovetski194a1732009-05-12 15:13:36 +0000503};
504
Guennadi Liakhovetskic41deba2009-08-25 11:06:21 -0300505static struct platform_device ap325rxa_camera[] = {
506 {
507 .name = "soc-camera-pdrv",
508 .id = 0,
509 .dev = {
Guennadi Liakhovetski0f448292009-12-11 11:31:35 -0300510 .platform_data = &ov7725_link,
Guennadi Liakhovetskic41deba2009-08-25 11:06:21 -0300511 },
512 }, {
513 .name = "soc-camera-pdrv",
514 .id = 1,
515 .dev = {
Guennadi Liakhovetski0f448292009-12-11 11:31:35 -0300516 .platform_data = &camera_link,
Guennadi Liakhovetskic41deba2009-08-25 11:06:21 -0300517 },
Guennadi Liakhovetski194a1732009-05-12 15:13:36 +0000518 },
519};
520
Yusuke Goda04e917b2008-06-06 17:03:23 +0900521static struct platform_device *ap325rxa_devices[] __initdata = {
Steve Glendinning90b76492009-01-07 17:20:07 +0900522 &smsc9118_device,
Magnus Damm6968980a2008-07-28 19:07:04 +0900523 &ap325rxa_nor_flash_device,
524 &lcdc_device,
Magnus Damm8b2224d2008-07-28 19:14:35 +0900525 &ceu_device,
Yoshihiro Shimoda908978a2008-09-09 17:17:42 +0900526 &nand_flash_device,
Magnus Damm17f81472009-10-02 02:22:56 +0000527 &sdhi0_cn3_device,
Magnus Damm8b431a72009-10-30 06:22:03 +0000528 &sdhi1_cn7_device,
Guennadi Liakhovetskic41deba2009-08-25 11:06:21 -0300529 &ap325rxa_camera[0],
530 &ap325rxa_camera[1],
Magnus Damm026953d2008-07-05 12:32:44 +0900531};
532
Magnus Damm86c7d032009-10-30 04:23:51 +0000533extern char ap325rxa_sdram_enter_start;
534extern char ap325rxa_sdram_enter_end;
535extern char ap325rxa_sdram_leave_start;
536extern char ap325rxa_sdram_leave_end;
537
Yusuke Goda04e917b2008-06-06 17:03:23 +0900538static int __init ap325rxa_devices_setup(void)
539{
Magnus Damm86c7d032009-10-30 04:23:51 +0000540 /* register board specific self-refresh code */
541 sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
542 &ap325rxa_sdram_enter_start,
543 &ap325rxa_sdram_enter_end,
544 &ap325rxa_sdram_leave_start,
545 &ap325rxa_sdram_leave_end);
546
Magnus Damm16587c42008-10-08 20:42:20 +0900547 /* LD3 and LD4 LEDs */
548 gpio_request(GPIO_PTX5, NULL); /* RUN */
549 gpio_direction_output(GPIO_PTX5, 1);
550 gpio_export(GPIO_PTX5, 0);
551
552 gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
553 gpio_direction_output(GPIO_PTX4, 0);
554 gpio_export(GPIO_PTX4, 0);
555
556 /* SW1 input */
557 gpio_request(GPIO_PTF7, NULL); /* MODE */
558 gpio_direction_input(GPIO_PTF7);
559 gpio_export(GPIO_PTF7, 0);
560
561 /* LCDC */
Magnus Damm16587c42008-10-08 20:42:20 +0900562 gpio_request(GPIO_FN_LCDD15, NULL);
563 gpio_request(GPIO_FN_LCDD14, NULL);
564 gpio_request(GPIO_FN_LCDD13, NULL);
565 gpio_request(GPIO_FN_LCDD12, NULL);
566 gpio_request(GPIO_FN_LCDD11, NULL);
567 gpio_request(GPIO_FN_LCDD10, NULL);
568 gpio_request(GPIO_FN_LCDD9, NULL);
569 gpio_request(GPIO_FN_LCDD8, NULL);
570 gpio_request(GPIO_FN_LCDD7, NULL);
571 gpio_request(GPIO_FN_LCDD6, NULL);
572 gpio_request(GPIO_FN_LCDD5, NULL);
573 gpio_request(GPIO_FN_LCDD4, NULL);
574 gpio_request(GPIO_FN_LCDD3, NULL);
575 gpio_request(GPIO_FN_LCDD2, NULL);
576 gpio_request(GPIO_FN_LCDD1, NULL);
577 gpio_request(GPIO_FN_LCDD0, NULL);
578 gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
579 gpio_request(GPIO_FN_LCDDCK, NULL);
580 gpio_request(GPIO_FN_LCDVEPWC, NULL);
581 gpio_request(GPIO_FN_LCDVCPWC, NULL);
582 gpio_request(GPIO_FN_LCDVSYN, NULL);
583 gpio_request(GPIO_FN_LCDHSYN, NULL);
584 gpio_request(GPIO_FN_LCDDISP, NULL);
585 gpio_request(GPIO_FN_LCDDON, NULL);
586
587 /* LCD backlight */
588 gpio_request(GPIO_PTS3, NULL);
589 gpio_direction_output(GPIO_PTS3, 1);
590
591 /* CEU */
Magnus Damm16587c42008-10-08 20:42:20 +0900592 gpio_request(GPIO_FN_VIO_CLK2, NULL);
593 gpio_request(GPIO_FN_VIO_VD2, NULL);
594 gpio_request(GPIO_FN_VIO_HD2, NULL);
595 gpio_request(GPIO_FN_VIO_FLD, NULL);
596 gpio_request(GPIO_FN_VIO_CKO, NULL);
597 gpio_request(GPIO_FN_VIO_D15, NULL);
598 gpio_request(GPIO_FN_VIO_D14, NULL);
599 gpio_request(GPIO_FN_VIO_D13, NULL);
600 gpio_request(GPIO_FN_VIO_D12, NULL);
601 gpio_request(GPIO_FN_VIO_D11, NULL);
602 gpio_request(GPIO_FN_VIO_D10, NULL);
603 gpio_request(GPIO_FN_VIO_D9, NULL);
604 gpio_request(GPIO_FN_VIO_D8, NULL);
605
606 gpio_request(GPIO_PTZ7, NULL);
607 gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
608 gpio_request(GPIO_PTZ6, NULL);
609 gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
610 gpio_request(GPIO_PTZ5, NULL);
Kuninori Morimoto86746282009-01-22 00:33:21 +0000611 gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
Magnus Damm16587c42008-10-08 20:42:20 +0900612 gpio_request(GPIO_PTZ4, NULL);
613 gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
614
Paul Mundt9d56dd32010-01-26 12:58:40 +0900615 __raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
Magnus Damm8b2224d2008-07-28 19:14:35 +0900616
Yoshihiro Shimoda908978a2008-09-09 17:17:42 +0900617 /* FLCTL */
Paul Mundtdd0e20e2008-10-21 18:08:10 +0900618 gpio_request(GPIO_FN_FCE, NULL);
619 gpio_request(GPIO_FN_NAF7, NULL);
620 gpio_request(GPIO_FN_NAF6, NULL);
621 gpio_request(GPIO_FN_NAF5, NULL);
622 gpio_request(GPIO_FN_NAF4, NULL);
623 gpio_request(GPIO_FN_NAF3, NULL);
624 gpio_request(GPIO_FN_NAF2, NULL);
625 gpio_request(GPIO_FN_NAF1, NULL);
626 gpio_request(GPIO_FN_NAF0, NULL);
627 gpio_request(GPIO_FN_FCDE, NULL);
628 gpio_request(GPIO_FN_FOE, NULL);
629 gpio_request(GPIO_FN_FSC, NULL);
630 gpio_request(GPIO_FN_FWE, NULL);
631 gpio_request(GPIO_FN_FRB, NULL);
Yoshihiro Shimoda908978a2008-09-09 17:17:42 +0900632
Paul Mundt9d56dd32010-01-26 12:58:40 +0900633 __raw_writew(0, PORT_HIZCRC);
634 __raw_writew(0xFFFF, PORT_DRVCRA);
635 __raw_writew(0xFFFF, PORT_DRVCRB);
Yoshihiro Shimoda908978a2008-09-09 17:17:42 +0900636
Magnus Damm8b2224d2008-07-28 19:14:35 +0900637 platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
Magnus Damm6968980a2008-07-28 19:07:04 +0900638
Magnus Damm8b431a72009-10-30 06:22:03 +0000639 /* SDHI0 - CN3 - SD CARD */
Magnus Damm17f81472009-10-02 02:22:56 +0000640 gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
641 gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
642 gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
643 gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
644 gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
645 gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
646 gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
647 gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
648
Magnus Damm8b431a72009-10-30 06:22:03 +0000649 /* SDHI1 - CN7 - MICRO SD CARD */
650 gpio_request(GPIO_FN_SDHI1CD, NULL);
651 gpio_request(GPIO_FN_SDHI1D3, NULL);
652 gpio_request(GPIO_FN_SDHI1D2, NULL);
653 gpio_request(GPIO_FN_SDHI1D1, NULL);
654 gpio_request(GPIO_FN_SDHI1D0, NULL);
655 gpio_request(GPIO_FN_SDHI1CMD, NULL);
656 gpio_request(GPIO_FN_SDHI1CLK, NULL);
657
Magnus Damm026953d2008-07-05 12:32:44 +0900658 i2c_register_board_info(0, ap325rxa_i2c_devices,
659 ARRAY_SIZE(ap325rxa_i2c_devices));
Yoshihiro Shimoda908978a2008-09-09 17:17:42 +0900660
Yusuke Goda04e917b2008-06-06 17:03:23 +0900661 return platform_add_devices(ap325rxa_devices,
662 ARRAY_SIZE(ap325rxa_devices));
663}
Magnus Dammdbefd602009-08-07 03:52:18 +0000664arch_initcall(ap325rxa_devices_setup);
Yusuke Goda04e917b2008-06-06 17:03:23 +0900665
Magnus Dammc01641b2009-06-03 08:26:40 +0000666/* Return the board specific boot mode pin configuration */
667static int ap325rxa_mode_pins(void)
668{
669 /* MD0=0, MD1=0, MD2=0: Clock Mode 0
670 * MD3=0: 16-bit Area0 Bus Width
671 * MD5=1: Little Endian
672 * TSTMD=1, MD8=1: Test Mode Disabled
673 */
674 return MODE_PIN5 | MODE_PIN8;
675}
676
Yusuke Goda04e917b2008-06-06 17:03:23 +0900677static struct sh_machine_vector mv_ap325rxa __initmv = {
678 .mv_name = "AP-325RXA",
Magnus Dammc01641b2009-06-03 08:26:40 +0000679 .mv_mode_pins = ap325rxa_mode_pins,
Yusuke Goda04e917b2008-06-06 17:03:23 +0900680};