ARM: mach-shmobile: mackerel: Add FSI-AK4643 support
[linux-2.6-block.git] / arch / arm / mach-shmobile / board-mackerel.c
CommitLineData
920adc75
KM
1/*
2 * mackerel board support
3 *
4 * Copyright (C) 2010 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * based on ap4evb
8 * Copyright (C) 2010 Magnus Damm
9 * Copyright (C) 2008 Yoshihiro Shimoda
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/irq.h>
28#include <linux/platform_device.h>
29#include <linux/gpio.h>
30#include <linux/input.h>
31#include <linux/io.h>
1a44d72a 32#include <linux/i2c.h>
d44deb35 33#include <linux/leds.h>
920adc75
KM
34#include <linux/mtd/mtd.h>
35#include <linux/mtd/partitions.h>
36#include <linux/mtd/physmap.h>
2264c151 37#include <linux/smsc911x.h>
1a44d72a 38#include <linux/sh_intc.h>
25338f2e 39#include <linux/usb/r8a66597.h>
920adc75 40
11fee467
KM
41#include <video/sh_mobile_lcdc.h>
42
1a44d72a
KM
43#include <sound/sh_fsi.h>
44
920adc75
KM
45#include <mach/common.h>
46#include <mach/sh7372.h>
47
48#include <asm/mach/arch.h>
49#include <asm/mach/time.h>
50#include <asm/mach/map.h>
51#include <asm/mach-types.h>
52
53/*
54 * Address Interface BusWidth note
55 * ------------------------------------------------------------------
56 * 0x0000_0000 NOR Flash ROM (MCP) 16bit SW7 : bit1 = ON
57 * 0x0800_0000 user area -
58 * 0x1000_0000 NOR Flash ROM (MCP) 16bit SW7 : bit1 = OFF
59 * 0x1400_0000 Ether (LAN9220) 16bit
60 * 0x1600_0000 user area - cannot use with NAND
61 * 0x1800_0000 user area -
62 * 0x1A00_0000 -
63 * 0x4000_0000 LPDDR2-SDRAM (POP) 32bit
64 */
65
4b82b689
KM
66/*
67 * CPU mode
68 *
69 * SW4 | Boot Area| Master | Remarks
70 * 1 | 2 | 3 | 4 | 5 | 6 | 8 | | Processor|
71 * ----+-----+-----+-----+-----+-----+-----+----------+----------+--------------
72 * ON | ON | OFF | ON | ON | OFF | OFF | External | System | External ROM
73 * ON | ON | ON | ON | ON | OFF | OFF | External | System | ROM Debug
74 * ON | ON | X | ON | OFF | OFF | OFF | Built-in | System | ROM Debug
75 * X | OFF | X | X | X | X | OFF | Built-in | System | MaskROM
76 * OFF | X | X | X | X | X | OFF | Built-in | System | MaskROM
77 * X | X | X | OFF | X | X | OFF | Built-in | System | MaskROM
78 * OFF | ON | OFF | X | X | OFF | ON | External | System | Standalone
79 * ON | OFF | OFF | X | X | OFF | ON | External | Realtime | Standalone
80*/
81
82/*
83 * NOR Flash ROM
84 *
85 * SW1 | SW2 | SW7 | NOR Flash ROM
86 * bit1 | bit1 bit2 | bit1 | Memory allocation
87 * ------+------------+------+------------------
88 * OFF | ON OFF | ON | Area 0
89 * OFF | ON OFF | OFF | Area 4
90 */
91
92/*
93 * SMSC 9220
94 *
95 * SW1 SMSC 9220
96 * -----------------------
97 * ON access disable
98 * OFF access enable
99 */
100
101/*
102 * NAND Flash ROM
103 *
104 * SW1 | SW2 | SW7 | NAND Flash ROM
105 * bit1 | bit1 bit2 | bit2 | Memory allocation
106 * ------+------------+------+------------------
107 * OFF | ON OFF | ON | FCE 0
108 * OFF | ON OFF | OFF | FCE 1
109 */
110
111/*
112 * External interrupt pin settings
113 *
114 * IRQX | pin setting | device | level
115 * ------+--------------------+--------------------+-------
116 * IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low
117 * IRQ6 | ICR1A.IRQ6SA=0011 | Ether(LAN9220) | High
118 * IRQ7 | ICR1A.IRQ7SA=0010 | LCD Tuch Panel | Low
119 * IRQ8 | ICR2A.IRQ8SA=0010 | MMC/SD card detect | Low
120 * IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low
121 * IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High
122 * IRQ22 | ICR4A.IRQ22SA=0011 | Sensor(AK8975) | High
25338f2e 123 */
4b82b689 124
25338f2e
KM
125/*
126 * USB
127 *
128 * USB0 : CN22 : Function
129 * USB1 : CN31 : Function/Host *1
130 *
131 * J30 (for CN31) *1
132 * ----------+---------------+-------------
133 * 1-2 short | VBUS 5V | Host
134 * open | external VBUS | Function
135 *
136 * *1
137 * CN31 is used as Host in Linux.
138 */
4b82b689 139
1a44d72a
KM
140/*
141 * FIXME !!
142 *
143 * gpio_no_direction
144 * are quick_hack.
145 *
146 * current gpio frame work doesn't have
147 * the method to control only pull up/down/free.
148 * this function should be replaced by correct gpio function
149 */
150static void __init gpio_no_direction(u32 addr)
151{
152 __raw_writeb(0x00, addr);
153}
154
920adc75
KM
155/* MTD */
156static struct mtd_partition nor_flash_partitions[] = {
157 {
158 .name = "loader",
159 .offset = 0x00000000,
160 .size = 512 * 1024,
161 .mask_flags = MTD_WRITEABLE,
162 },
163 {
164 .name = "bootenv",
165 .offset = MTDPART_OFS_APPEND,
166 .size = 512 * 1024,
167 .mask_flags = MTD_WRITEABLE,
168 },
169 {
170 .name = "kernel_ro",
171 .offset = MTDPART_OFS_APPEND,
172 .size = 8 * 1024 * 1024,
173 .mask_flags = MTD_WRITEABLE,
174 },
175 {
176 .name = "kernel",
177 .offset = MTDPART_OFS_APPEND,
178 .size = 8 * 1024 * 1024,
179 },
180 {
181 .name = "data",
182 .offset = MTDPART_OFS_APPEND,
183 .size = MTDPART_SIZ_FULL,
184 },
185};
186
187static struct physmap_flash_data nor_flash_data = {
188 .width = 2,
189 .parts = nor_flash_partitions,
190 .nr_parts = ARRAY_SIZE(nor_flash_partitions),
191};
192
193static struct resource nor_flash_resources[] = {
194 [0] = {
195 .start = 0x00000000,
196 .end = 0x08000000 - 1,
197 .flags = IORESOURCE_MEM,
198 }
199};
200
201static struct platform_device nor_flash_device = {
202 .name = "physmap-flash",
203 .dev = {
204 .platform_data = &nor_flash_data,
205 },
206 .num_resources = ARRAY_SIZE(nor_flash_resources),
207 .resource = nor_flash_resources,
208};
209
2264c151
KM
210/* SMSC */
211static struct resource smc911x_resources[] = {
212 {
213 .start = 0x14000000,
214 .end = 0x16000000 - 1,
215 .flags = IORESOURCE_MEM,
216 }, {
217 .start = evt2irq(0x02c0) /* IRQ6A */,
218 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
219 },
220};
221
222static struct smsc911x_platform_config smsc911x_info = {
223 .flags = SMSC911X_USE_16BIT | SMSC911X_SAVE_MAC_ADDRESS,
224 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
225 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
226};
227
228static struct platform_device smc911x_device = {
229 .name = "smsc911x",
230 .id = -1,
231 .num_resources = ARRAY_SIZE(smc911x_resources),
232 .resource = smc911x_resources,
233 .dev = {
234 .platform_data = &smsc911x_info,
235 },
236};
237
11fee467
KM
238/* LCDC */
239static struct fb_videomode mackerel_lcdc_modes[] = {
240 {
241 .name = "WVGA Panel",
242 .xres = 800,
243 .yres = 480,
244 .left_margin = 220,
245 .right_margin = 110,
246 .hsync_len = 70,
247 .upper_margin = 20,
248 .lower_margin = 5,
249 .vsync_len = 5,
250 .sync = 0,
251 },
252};
253
254static struct sh_mobile_lcdc_info lcdc_info = {
255 .clock_source = LCDC_CLK_BUS,
256 .ch[0] = {
257 .chan = LCDC_CHAN_MAINLCD,
258 .bpp = 16,
259 .lcd_cfg = mackerel_lcdc_modes,
260 .num_cfg = ARRAY_SIZE(mackerel_lcdc_modes),
261 .interface_type = RGB24,
262 .clock_divider = 2,
263 .flags = 0,
264 .lcd_size_cfg.width = 152,
265 .lcd_size_cfg.height = 91,
266 }
267};
268
269static struct resource lcdc_resources[] = {
270 [0] = {
271 .name = "LCDC",
272 .start = 0xfe940000,
273 .end = 0xfe943fff,
274 .flags = IORESOURCE_MEM,
275 },
276 [1] = {
277 .start = intcs_evt2irq(0x580),
278 .flags = IORESOURCE_IRQ,
279 },
280};
281
282static struct platform_device lcdc_device = {
283 .name = "sh_mobile_lcdc_fb",
284 .num_resources = ARRAY_SIZE(lcdc_resources),
285 .resource = lcdc_resources,
286 .dev = {
287 .platform_data = &lcdc_info,
288 .coherent_dma_mask = ~0,
289 },
290};
291
25338f2e
KM
292/* USB1 (Host) */
293static void usb1_host_port_power(int port, int power)
294{
295 if (!power) /* only power-on is supported for now */
296 return;
297
298 /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
299 __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
300}
301
302static struct r8a66597_platdata usb1_host_data = {
303 .on_chip = 1,
304 .port_power = usb1_host_port_power,
305};
306
307static struct resource usb1_host_resources[] = {
308 [0] = {
309 .name = "USBHS",
310 .start = 0xE68B0000,
311 .end = 0xE68B00E6 - 1,
312 .flags = IORESOURCE_MEM,
313 },
314 [1] = {
315 .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
316 .flags = IORESOURCE_IRQ,
317 },
318};
319
320static struct platform_device usb1_host_device = {
321 .name = "r8a66597_hcd",
322 .id = 1,
323 .dev = {
324 .dma_mask = NULL, /* not use dma */
325 .coherent_dma_mask = 0xffffffff,
326 .platform_data = &usb1_host_data,
327 },
328 .num_resources = ARRAY_SIZE(usb1_host_resources),
329 .resource = usb1_host_resources,
330};
331
d44deb35
KM
332/* LED */
333static struct gpio_led mackerel_leds[] = {
334 {
335 .name = "led0",
336 .gpio = GPIO_PORT0,
337 .default_state = LEDS_GPIO_DEFSTATE_ON,
338 },
339 {
340 .name = "led1",
341 .gpio = GPIO_PORT1,
342 .default_state = LEDS_GPIO_DEFSTATE_ON,
343 },
344 {
345 .name = "led2",
346 .gpio = GPIO_PORT2,
347 .default_state = LEDS_GPIO_DEFSTATE_ON,
348 },
349 {
350 .name = "led3",
351 .gpio = GPIO_PORT159,
352 .default_state = LEDS_GPIO_DEFSTATE_ON,
353 }
354};
355
356static struct gpio_led_platform_data mackerel_leds_pdata = {
357 .leds = mackerel_leds,
358 .num_leds = ARRAY_SIZE(mackerel_leds),
359};
360
361static struct platform_device leds_device = {
362 .name = "leds-gpio",
363 .id = 0,
364 .dev = {
365 .platform_data = &mackerel_leds_pdata,
366 },
367};
368
1a44d72a
KM
369/* FSI */
370#define IRQ_FSI evt2irq(0x1840)
371static struct sh_fsi_platform_info fsi_info = {
372 .porta_flags = SH_FSI_BRS_INV |
373 SH_FSI_OUT_SLAVE_MODE |
374 SH_FSI_IN_SLAVE_MODE |
375 SH_FSI_OFMT(PCM) |
376 SH_FSI_IFMT(PCM),
377};
378
379static struct resource fsi_resources[] = {
380 [0] = {
381 .name = "FSI",
382 .start = 0xFE3C0000,
383 .end = 0xFE3C0400 - 1,
384 .flags = IORESOURCE_MEM,
385 },
386 [1] = {
387 .start = IRQ_FSI,
388 .flags = IORESOURCE_IRQ,
389 },
390};
391
392static struct platform_device fsi_device = {
393 .name = "sh_fsi2",
394 .id = -1,
395 .num_resources = ARRAY_SIZE(fsi_resources),
396 .resource = fsi_resources,
397 .dev = {
398 .platform_data = &fsi_info,
399 },
400};
401
402static struct platform_device fsi_ak4643_device = {
403 .name = "sh_fsi2_a_ak4643",
404};
d44deb35 405
920adc75
KM
406static struct platform_device *mackerel_devices[] __initdata = {
407 &nor_flash_device,
2264c151 408 &smc911x_device,
11fee467 409 &lcdc_device,
25338f2e 410 &usb1_host_device,
d44deb35 411 &leds_device,
1a44d72a
KM
412 &fsi_device,
413 &fsi_ak4643_device,
414};
415
416/* I2C */
417static struct i2c_board_info i2c0_devices[] = {
418 {
419 I2C_BOARD_INFO("ak4643", 0x13),
420 },
920adc75
KM
421};
422
423static struct map_desc mackerel_io_desc[] __initdata = {
424 /* create a 1:1 entity map for 0xe6xxxxxx
425 * used by CPGA, INTC and PFC.
426 */
427 {
428 .virtual = 0xe6000000,
429 .pfn = __phys_to_pfn(0xe6000000),
430 .length = 256 << 20,
431 .type = MT_DEVICE_NONSHARED
432 },
433};
434
435static void __init mackerel_map_io(void)
436{
437 iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc));
438
439 /* setup early devices and console here as well */
440 sh7372_add_early_devices();
441 shmobile_setup_console();
442}
443
1a44d72a
KM
444#define GPIO_PORT9CR 0xE6051009
445#define GPIO_PORT10CR 0xE605100A
920adc75
KM
446static void __init mackerel_init(void)
447{
448 sh7372_pinmux_init();
449
450 /* enable SCIFA0 */
451 gpio_request(GPIO_FN_SCIFA0_TXD, NULL);
452 gpio_request(GPIO_FN_SCIFA0_RXD, NULL);
453
2264c151
KM
454 /* enable SMSC911X */
455 gpio_request(GPIO_FN_CS5A, NULL);
456 gpio_request(GPIO_FN_IRQ6_39, NULL);
457
11fee467 458 /* LCDC */
eb87e677
KM
459 gpio_request(GPIO_FN_LCDD23, NULL);
460 gpio_request(GPIO_FN_LCDD22, NULL);
461 gpio_request(GPIO_FN_LCDD21, NULL);
462 gpio_request(GPIO_FN_LCDD20, NULL);
463 gpio_request(GPIO_FN_LCDD19, NULL);
464 gpio_request(GPIO_FN_LCDD18, NULL);
11fee467
KM
465 gpio_request(GPIO_FN_LCDD17, NULL);
466 gpio_request(GPIO_FN_LCDD16, NULL);
467 gpio_request(GPIO_FN_LCDD15, NULL);
468 gpio_request(GPIO_FN_LCDD14, NULL);
469 gpio_request(GPIO_FN_LCDD13, NULL);
470 gpio_request(GPIO_FN_LCDD12, NULL);
471 gpio_request(GPIO_FN_LCDD11, NULL);
472 gpio_request(GPIO_FN_LCDD10, NULL);
473 gpio_request(GPIO_FN_LCDD9, NULL);
474 gpio_request(GPIO_FN_LCDD8, NULL);
475 gpio_request(GPIO_FN_LCDD7, NULL);
476 gpio_request(GPIO_FN_LCDD6, NULL);
477 gpio_request(GPIO_FN_LCDD5, NULL);
478 gpio_request(GPIO_FN_LCDD4, NULL);
479 gpio_request(GPIO_FN_LCDD3, NULL);
480 gpio_request(GPIO_FN_LCDD2, NULL);
481 gpio_request(GPIO_FN_LCDD1, NULL);
482 gpio_request(GPIO_FN_LCDD0, NULL);
483 gpio_request(GPIO_FN_LCDDISP, NULL);
484 gpio_request(GPIO_FN_LCDDCK, NULL);
485
486 gpio_request(GPIO_PORT31, NULL); /* backlight */
487 gpio_direction_output(GPIO_PORT31, 1);
488
489 gpio_request(GPIO_PORT151, NULL); /* LCDDON */
490 gpio_direction_output(GPIO_PORT151, 1);
491
25338f2e
KM
492 /* USB enable */
493 gpio_request(GPIO_FN_VBUS0_1, NULL);
494 gpio_request(GPIO_FN_IDIN_1_18, NULL);
495 gpio_request(GPIO_FN_PWEN_1_115, NULL);
496 gpio_request(GPIO_FN_OVCN_1_114, NULL);
497 gpio_request(GPIO_FN_EXTLP_1, NULL);
498 gpio_request(GPIO_FN_OVCN2_1, NULL);
499
500 /* setup USB phy */
501 __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */
502
1a44d72a
KM
503 /* enable FSI2 port A (ak4643) */
504 gpio_request(GPIO_FN_FSIAIBT, NULL);
505 gpio_request(GPIO_FN_FSIAILR, NULL);
506 gpio_request(GPIO_FN_FSIAISLD, NULL);
507 gpio_request(GPIO_FN_FSIAOSLD, NULL);
508 gpio_request(GPIO_PORT161, NULL);
509 gpio_direction_output(GPIO_PORT161, 0); /* slave */
510
511 gpio_request(GPIO_PORT9, NULL);
512 gpio_request(GPIO_PORT10, NULL);
513 gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
514 gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
515
516 intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */
517
518
519 i2c_register_board_info(0, i2c0_devices,
520 ARRAY_SIZE(i2c0_devices));
11fee467 521
920adc75
KM
522 sh7372_add_standard_devices();
523
524 platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
525}
526
527static void __init mackerel_timer_init(void)
528{
529 sh7372_clock_init();
530 shmobile_timer.init();
531}
532
533static struct sys_timer mackerel_timer = {
534 .init = mackerel_timer_init,
535};
536
537MACHINE_START(MACKEREL, "mackerel")
538 .map_io = mackerel_map_io,
539 .init_irq = sh7372_init_irq,
540 .init_machine = mackerel_init,
541 .timer = &mackerel_timer,
542MACHINE_END