1/*
2 * linux/arch/arm/mach-omap1/board-ams-delta.c
3 *
4 * Modified from board-generic.c
5 *
6 * Board specific inits for the Amstrad E3 (codename Delta) videophone
7 *
8 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/basic_mmio_gpio.h>
15#include <linux/gpio.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/input.h>
19#include <linux/interrupt.h>
20#include <linux/leds.h>
21#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h>
23#include <linux/regulator/fixed.h>
24#include <linux/regulator/machine.h>
25#include <linux/serial_8250.h>
26#include <linux/export.h>
27#include <linux/omapfb.h>
28#include <linux/io.h>
29#include <linux/platform_data/gpio-omap.h>
30
31#include <media/soc_camera.h>
32
33#include <asm/serial.h>
34#include <asm/mach-types.h>
35#include <asm/mach/arch.h>
36#include <asm/mach/map.h>
37
38#include <mach/board-ams-delta.h>
39#include <linux/platform_data/keypad-omap.h>
40#include <mach/mux.h>
41
42#include <mach/hardware.h>
43#include <mach/ams-delta-fiq.h>
44#include <mach/camera.h>
45#include <mach/usb.h>
46
47#include "iomap.h"
48#include "common.h"
49
50static const unsigned int ams_delta_keymap[] = {
51	KEY(0, 0, KEY_F1),		/* Advert    */
52
53	KEY(0, 3, KEY_COFFEE),		/* Games     */
54	KEY(0, 2, KEY_QUESTION),	/* Directory */
55	KEY(2, 3, KEY_CONNECT),		/* Internet  */
56	KEY(1, 2, KEY_SHOP),		/* Services  */
57	KEY(1, 1, KEY_PHONE),		/* VoiceMail */
58
59	KEY(0, 1, KEY_DELETE),		/* Delete    */
60	KEY(2, 2, KEY_PLAY),		/* Play      */
61	KEY(1, 0, KEY_PAGEUP),		/* Up        */
62	KEY(1, 3, KEY_PAGEDOWN),	/* Down      */
63	KEY(2, 0, KEY_EMAIL),		/* ReadEmail */
64	KEY(2, 1, KEY_STOP),		/* Stop      */
65
66	/* Numeric keypad portion */
67	KEY(0, 7, KEY_KP1),
68	KEY(0, 6, KEY_KP2),
69	KEY(0, 5, KEY_KP3),
70	KEY(1, 7, KEY_KP4),
71	KEY(1, 6, KEY_KP5),
72	KEY(1, 5, KEY_KP6),
73	KEY(2, 7, KEY_KP7),
74	KEY(2, 6, KEY_KP8),
75	KEY(2, 5, KEY_KP9),
76	KEY(3, 6, KEY_KP0),
77	KEY(3, 7, KEY_KPASTERISK),
78	KEY(3, 5, KEY_KPDOT),		/* # key     */
79	KEY(7, 2, KEY_NUMLOCK),		/* Mute      */
80	KEY(7, 1, KEY_KPMINUS),		/* Recall    */
81	KEY(6, 1, KEY_KPPLUS),		/* Redial    */
82	KEY(7, 6, KEY_KPSLASH),		/* Handsfree */
83	KEY(6, 0, KEY_ENTER),		/* Video     */
84
85	KEY(7, 4, KEY_CAMERA),		/* Photo     */
86
87	KEY(0, 4, KEY_F2),		/* Home      */
88	KEY(1, 4, KEY_F3),		/* Office    */
89	KEY(2, 4, KEY_F4),		/* Mobile    */
90	KEY(7, 7, KEY_F5),		/* SMS       */
91	KEY(7, 5, KEY_F6),		/* Email     */
92
93	/* QWERTY portion of keypad */
94	KEY(3, 4, KEY_Q),
95	KEY(3, 3, KEY_W),
96	KEY(3, 2, KEY_E),
97	KEY(3, 1, KEY_R),
98	KEY(3, 0, KEY_T),
99	KEY(4, 7, KEY_Y),
100	KEY(4, 6, KEY_U),
101	KEY(4, 5, KEY_I),
102	KEY(4, 4, KEY_O),
103	KEY(4, 3, KEY_P),
104
105	KEY(4, 2, KEY_A),
106	KEY(4, 1, KEY_S),
107	KEY(4, 0, KEY_D),
108	KEY(5, 7, KEY_F),
109	KEY(5, 6, KEY_G),
110	KEY(5, 5, KEY_H),
111	KEY(5, 4, KEY_J),
112	KEY(5, 3, KEY_K),
113	KEY(5, 2, KEY_L),
114
115	KEY(5, 1, KEY_Z),
116	KEY(5, 0, KEY_X),
117	KEY(6, 7, KEY_C),
118	KEY(6, 6, KEY_V),
119	KEY(6, 5, KEY_B),
120	KEY(6, 4, KEY_N),
121	KEY(6, 3, KEY_M),
122	KEY(6, 2, KEY_SPACE),
123
124	KEY(7, 0, KEY_LEFTSHIFT),	/* Vol up    */
125	KEY(7, 3, KEY_LEFTCTRL),	/* Vol down  */
126};
127
128#define LATCH1_PHYS	0x01000000
129#define LATCH1_VIRT	0xEA000000
130#define MODEM_PHYS	0x04000000
131#define MODEM_VIRT	0xEB000000
132#define LATCH2_PHYS	0x08000000
133#define LATCH2_VIRT	0xEC000000
134
135static struct map_desc ams_delta_io_desc[] __initdata = {
136	/* AMS_DELTA_LATCH1 */
137	{
138		.virtual	= LATCH1_VIRT,
139		.pfn		= __phys_to_pfn(LATCH1_PHYS),
140		.length		= 0x01000000,
141		.type		= MT_DEVICE
142	},
143	/* AMS_DELTA_LATCH2 */
144	{
145		.virtual	= LATCH2_VIRT,
146		.pfn		= __phys_to_pfn(LATCH2_PHYS),
147		.length		= 0x01000000,
148		.type		= MT_DEVICE
149	},
150	/* AMS_DELTA_MODEM */
151	{
152		.virtual	= MODEM_VIRT,
153		.pfn		= __phys_to_pfn(MODEM_PHYS),
154		.length		= 0x01000000,
155		.type		= MT_DEVICE
156	}
157};
158
159static struct omap_lcd_config ams_delta_lcd_config __initdata = {
160	.ctrl_name	= "internal",
161};
162
163static struct omap_usb_config ams_delta_usb_config __initdata = {
164	.register_host	= 1,
165	.hmc_mode	= 16,
166	.pins[0]	= 2,
167};
168
169#define LATCH1_GPIO_BASE	232
170#define LATCH1_NGPIO		8
171
172static struct resource latch1_resources[] = {
173	[0] = {
174		.name	= "dat",
175		.start	= LATCH1_PHYS,
176		.end	= LATCH1_PHYS + (LATCH1_NGPIO - 1) / 8,
177		.flags	= IORESOURCE_MEM,
178	},
179};
180
181static struct bgpio_pdata latch1_pdata = {
182	.base	= LATCH1_GPIO_BASE,
183	.ngpio	= LATCH1_NGPIO,
184};
185
186static struct platform_device latch1_gpio_device = {
187	.name		= "basic-mmio-gpio",
188	.id		= 0,
189	.resource	= latch1_resources,
190	.num_resources	= ARRAY_SIZE(latch1_resources),
191	.dev		= {
192		.platform_data	= &latch1_pdata,
193	},
194};
195
196static struct resource latch2_resources[] = {
197	[0] = {
198		.name	= "dat",
199		.start	= LATCH2_PHYS,
200		.end	= LATCH2_PHYS + (AMS_DELTA_LATCH2_NGPIO - 1) / 8,
201		.flags	= IORESOURCE_MEM,
202	},
203};
204
205static struct bgpio_pdata latch2_pdata = {
206	.base	= AMS_DELTA_LATCH2_GPIO_BASE,
207	.ngpio	= AMS_DELTA_LATCH2_NGPIO,
208};
209
210static struct platform_device latch2_gpio_device = {
211	.name		= "basic-mmio-gpio",
212	.id		= 1,
213	.resource	= latch2_resources,
214	.num_resources	= ARRAY_SIZE(latch2_resources),
215	.dev		= {
216		.platform_data	= &latch2_pdata,
217	},
218};
219
220static const struct gpio latch_gpios[] __initconst = {
221	{
222		.gpio	= LATCH1_GPIO_BASE + 6,
223		.flags	= GPIOF_OUT_INIT_LOW,
224		.label	= "dockit1",
225	},
226	{
227		.gpio	= LATCH1_GPIO_BASE + 7,
228		.flags	= GPIOF_OUT_INIT_LOW,
229		.label	= "dockit2",
230	},
231	{
232		.gpio	= AMS_DELTA_GPIO_PIN_SCARD_RSTIN,
233		.flags	= GPIOF_OUT_INIT_LOW,
234		.label	= "scard_rstin",
235	},
236	{
237		.gpio	= AMS_DELTA_GPIO_PIN_SCARD_CMDVCC,
238		.flags	= GPIOF_OUT_INIT_LOW,
239		.label	= "scard_cmdvcc",
240	},
241	{
242		.gpio	= AMS_DELTA_GPIO_PIN_MODEM_CODEC,
243		.flags	= GPIOF_OUT_INIT_LOW,
244		.label	= "modem_codec",
245	},
246	{
247		.gpio	= AMS_DELTA_LATCH2_GPIO_BASE + 14,
248		.flags	= GPIOF_OUT_INIT_LOW,
249		.label	= "hookflash1",
250	},
251	{
252		.gpio	= AMS_DELTA_LATCH2_GPIO_BASE + 15,
253		.flags	= GPIOF_OUT_INIT_LOW,
254		.label	= "hookflash2",
255	},
256};
257
258static struct regulator_consumer_supply modem_nreset_consumers[] = {
259	REGULATOR_SUPPLY("RESET#", "serial8250.1"),
260	REGULATOR_SUPPLY("POR", "cx20442-codec"),
261};
262
263static struct regulator_init_data modem_nreset_data = {
264	.constraints		= {
265		.valid_ops_mask		= REGULATOR_CHANGE_STATUS,
266		.boot_on		= 1,
267	},
268	.num_consumer_supplies	= ARRAY_SIZE(modem_nreset_consumers),
269	.consumer_supplies	= modem_nreset_consumers,
270};
271
272static struct fixed_voltage_config modem_nreset_config = {
273	.supply_name		= "modem_nreset",
274	.microvolts		= 3300000,
275	.gpio			= AMS_DELTA_GPIO_PIN_MODEM_NRESET,
276	.startup_delay		= 25000,
277	.enable_high		= 1,
278	.enabled_at_boot	= 1,
279	.init_data		= &modem_nreset_data,
280};
281
282static struct platform_device modem_nreset_device = {
283	.name	= "reg-fixed-voltage",
284	.id	= -1,
285	.dev	= {
286		.platform_data	= &modem_nreset_config,
287	},
288};
289
290struct modem_private_data {
291	struct regulator *regulator;
292};
293
294static struct modem_private_data modem_priv;
295
296void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value)
297{
298	int bit = 0;
299	u16 bitpos = 1 << bit;
300
301	for (; bit < ngpio; bit++, bitpos = bitpos << 1) {
302		if (!(mask & bitpos))
303			continue;
304		else
305			gpio_set_value(base + bit, (value & bitpos) != 0);
306	}
307}
308EXPORT_SYMBOL(ams_delta_latch_write);
309
310static struct resource ams_delta_nand_resources[] = {
311	[0] = {
312		.start	= OMAP1_MPUIO_BASE,
313		.end	= OMAP1_MPUIO_BASE +
314				OMAP_MPUIO_IO_CNTL + sizeof(u32) - 1,
315		.flags	= IORESOURCE_MEM,
316	},
317};
318
319static struct platform_device ams_delta_nand_device = {
320	.name	= "ams-delta-nand",
321	.id	= -1,
322	.num_resources	= ARRAY_SIZE(ams_delta_nand_resources),
323	.resource	= ams_delta_nand_resources,
324};
325
326static struct resource ams_delta_kp_resources[] = {
327	[0] = {
328		.start	= INT_KEYBOARD,
329		.end	= INT_KEYBOARD,
330		.flags	= IORESOURCE_IRQ,
331	},
332};
333
334static const struct matrix_keymap_data ams_delta_keymap_data = {
335	.keymap		= ams_delta_keymap,
336	.keymap_size	= ARRAY_SIZE(ams_delta_keymap),
337};
338
339static struct omap_kp_platform_data ams_delta_kp_data = {
340	.rows		= 8,
341	.cols		= 8,
342	.keymap_data	= &ams_delta_keymap_data,
343	.delay		= 9,
344};
345
346static struct platform_device ams_delta_kp_device = {
347	.name		= "omap-keypad",
348	.id		= -1,
349	.dev		= {
350		.platform_data = &ams_delta_kp_data,
351	},
352	.num_resources	= ARRAY_SIZE(ams_delta_kp_resources),
353	.resource	= ams_delta_kp_resources,
354};
355
356static struct platform_device ams_delta_lcd_device = {
357	.name	= "lcd_ams_delta",
358	.id	= -1,
359};
360
361static const struct gpio_led gpio_leds[] __initconst = {
362	{
363		.name		 = "camera",
364		.gpio		 = LATCH1_GPIO_BASE + 0,
365		.default_state	 = LEDS_GPIO_DEFSTATE_OFF,
366#ifdef CONFIG_LEDS_TRIGGERS
367		.default_trigger = "ams_delta_camera",
368#endif
369	},
370	{
371		.name		 = "advert",
372		.gpio		 = LATCH1_GPIO_BASE + 1,
373		.default_state	 = LEDS_GPIO_DEFSTATE_OFF,
374	},
375	{
376		.name		 = "email",
377		.gpio		 = LATCH1_GPIO_BASE + 2,
378		.default_state	 = LEDS_GPIO_DEFSTATE_OFF,
379	},
380	{
381		.name		 = "handsfree",
382		.gpio		 = LATCH1_GPIO_BASE + 3,
383		.default_state	 = LEDS_GPIO_DEFSTATE_OFF,
384	},
385	{
386		.name		 = "voicemail",
387		.gpio		 = LATCH1_GPIO_BASE + 4,
388		.default_state	 = LEDS_GPIO_DEFSTATE_OFF,
389	},
390	{
391		.name		 = "voice",
392		.gpio		 = LATCH1_GPIO_BASE + 5,
393		.default_state	 = LEDS_GPIO_DEFSTATE_OFF,
394	},
395};
396
397static const struct gpio_led_platform_data leds_pdata __initconst = {
398	.leds		= gpio_leds,
399	.num_leds	= ARRAY_SIZE(gpio_leds),
400};
401
402static struct i2c_board_info ams_delta_camera_board_info[] = {
403	{
404		I2C_BOARD_INFO("ov6650", 0x60),
405	},
406};
407
408#ifdef CONFIG_LEDS_TRIGGERS
409DEFINE_LED_TRIGGER(ams_delta_camera_led_trigger);
410
411static int ams_delta_camera_power(struct device *dev, int power)
412{
413	/*
414	 * turn on camera LED
415	 */
416	if (power)
417		led_trigger_event(ams_delta_camera_led_trigger, LED_FULL);
418	else
419		led_trigger_event(ams_delta_camera_led_trigger, LED_OFF);
420	return 0;
421}
422#else
423#define ams_delta_camera_power	NULL
424#endif
425
426static struct soc_camera_link ams_delta_iclink = {
427	.bus_id         = 0,	/* OMAP1 SoC camera bus */
428	.i2c_adapter_id = 1,
429	.board_info     = &ams_delta_camera_board_info[0],
430	.module_name    = "ov6650",
431	.power		= ams_delta_camera_power,
432};
433
434static struct platform_device ams_delta_camera_device = {
435	.name   = "soc-camera-pdrv",
436	.id     = 0,
437	.dev    = {
438		.platform_data = &ams_delta_iclink,
439	},
440};
441
442static struct omap1_cam_platform_data ams_delta_camera_platform_data = {
443	.camexclk_khz	= 12000,	/* default 12MHz clock, no extra DPLL */
444	.lclk_khz_max	= 1334,		/* results in 5fps CIF, 10fps QCIF */
445};
446
447static struct platform_device ams_delta_audio_device = {
448	.name   = "ams-delta-audio",
449	.id     = -1,
450};
451
452static struct platform_device cx20442_codec_device = {
453	.name   = "cx20442-codec",
454	.id     = -1,
455};
456
457static struct platform_device *ams_delta_devices[] __initdata = {
458	&latch1_gpio_device,
459	&latch2_gpio_device,
460	&ams_delta_kp_device,
461	&ams_delta_camera_device,
462	&ams_delta_audio_device,
463};
464
465static struct platform_device *late_devices[] __initdata = {
466	&ams_delta_nand_device,
467	&ams_delta_lcd_device,
468	&cx20442_codec_device,
469};
470
471static void __init ams_delta_init(void)
472{
473	/* mux pins for uarts */
474	omap_cfg_reg(UART1_TX);
475	omap_cfg_reg(UART1_RTS);
476
477	/* parallel camera interface */
478	omap_cfg_reg(H19_1610_CAM_EXCLK);
479	omap_cfg_reg(J15_1610_CAM_LCLK);
480	omap_cfg_reg(L18_1610_CAM_VS);
481	omap_cfg_reg(L15_1610_CAM_HS);
482	omap_cfg_reg(L19_1610_CAM_D0);
483	omap_cfg_reg(K14_1610_CAM_D1);
484	omap_cfg_reg(K15_1610_CAM_D2);
485	omap_cfg_reg(K19_1610_CAM_D3);
486	omap_cfg_reg(K18_1610_CAM_D4);
487	omap_cfg_reg(J14_1610_CAM_D5);
488	omap_cfg_reg(J19_1610_CAM_D6);
489	omap_cfg_reg(J18_1610_CAM_D7);
490
491	omap_serial_init();
492	omap_register_i2c_bus(1, 100, NULL, 0);
493
494	omap1_usb_init(&ams_delta_usb_config);
495	omap1_set_camera_info(&ams_delta_camera_platform_data);
496#ifdef CONFIG_LEDS_TRIGGERS
497	led_trigger_register_simple("ams_delta_camera",
498			&ams_delta_camera_led_trigger);
499#endif
500	gpio_led_register_device(-1, &leds_pdata);
501	platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
502
503	ams_delta_init_fiq();
504
505	omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
506
507	omapfb_set_lcd_config(&ams_delta_lcd_config);
508}
509
510static void modem_pm(struct uart_port *port, unsigned int state, unsigned old)
511{
512	struct modem_private_data *priv = port->private_data;
513
514	if (IS_ERR(priv->regulator))
515		return;
516
517	if (state == old)
518		return;
519
520	if (state == 0)
521		regulator_enable(priv->regulator);
522	else if (old == 0)
523		regulator_disable(priv->regulator);
524}
525
526static struct plat_serial8250_port ams_delta_modem_ports[] = {
527	{
528		.membase	= IOMEM(MODEM_VIRT),
529		.mapbase	= MODEM_PHYS,
530		.irq		= -EINVAL, /* changed later */
531		.flags		= UPF_BOOT_AUTOCONF,
532		.irqflags	= IRQF_TRIGGER_RISING,
533		.iotype		= UPIO_MEM,
534		.regshift	= 1,
535		.uartclk	= BASE_BAUD * 16,
536		.pm		= modem_pm,
537		.private_data	= &modem_priv,
538	},
539	{ },
540};
541
542static struct platform_device ams_delta_modem_device = {
543	.name	= "serial8250",
544	.id	= PLAT8250_DEV_PLATFORM1,
545	.dev		= {
546		.platform_data = ams_delta_modem_ports,
547	},
548};
549
550static int __init late_init(void)
551{
552	int err;
553
554	if (!machine_is_ams_delta())
555		return -ENODEV;
556
557	err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios));
558	if (err) {
559		pr_err("Couldn't take over latch1/latch2 GPIO pins\n");
560		return err;
561	}
562
563	platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
564
565	err = platform_device_register(&modem_nreset_device);
566	if (err) {
567		pr_err("Couldn't register the modem regulator device\n");
568		return err;
569	}
570
571	omap_cfg_reg(M14_1510_GPIO2);
572	ams_delta_modem_ports[0].irq =
573			gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
574
575	err = gpio_request(AMS_DELTA_GPIO_PIN_MODEM_IRQ, "modem");
576	if (err) {
577		pr_err("Couldn't request gpio pin for modem\n");
578		return err;
579	}
580	gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
581
582	/* Initialize the modem_nreset regulator consumer before use */
583	modem_priv.regulator = ERR_PTR(-ENODEV);
584
585	ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
586			AMS_DELTA_LATCH2_MODEM_CODEC);
587
588	err = platform_device_register(&ams_delta_modem_device);
589	if (err)
590		goto gpio_free;
591
592	/*
593	 * Once the modem device is registered, the modem_nreset
594	 * regulator can be requested on behalf of that device.
595	 */
596	modem_priv.regulator = regulator_get(&ams_delta_modem_device.dev,
597			"RESET#");
598	if (IS_ERR(modem_priv.regulator)) {
599		err = PTR_ERR(modem_priv.regulator);
600		goto unregister;
601	}
602	return 0;
603
604unregister:
605	platform_device_unregister(&ams_delta_modem_device);
606gpio_free:
607	gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
608	return err;
609}
610
611static void __init ams_delta_init_late(void)
612{
613	omap1_init_late();
614	late_init();
615}
616
617static void __init ams_delta_map_io(void)
618{
619	omap15xx_map_io();
620	iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
621}
622
623MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
624	/* Maintainer: Jonathan McDowell <noodles@earth.li> */
625	.atag_offset	= 0x100,
626	.map_io		= ams_delta_map_io,
627	.init_early	= omap1_init_early,
628	.init_irq	= omap1_init_irq,
629	.init_machine	= ams_delta_init,
630	.init_late	= ams_delta_init_late,
631	.init_time	= omap1_timer_init,
632	.restart	= omap1_restart,
633MACHINE_END
634