• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/arm/mach-pxa/
1/*
2 * Support for HTC Magician PDA phones:
3 * i-mate JAM, O2 Xda mini, Orange SPV M500, Qtek s100, Qtek s110
4 * and T-Mobile MDA Compact.
5 *
6 * Copyright (c) 2006-2007 Philipp Zabel
7 *
8 * Based on hx4700.c, spitz.c and others.
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 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/delay.h>
20#include <linux/gpio.h>
21#include <linux/gpio_keys.h>
22#include <linux/input.h>
23#include <linux/mfd/htc-egpio.h>
24#include <linux/mfd/htc-pasic3.h>
25#include <linux/mtd/physmap.h>
26#include <linux/pda_power.h>
27#include <linux/pwm_backlight.h>
28#include <linux/regulator/bq24022.h>
29#include <linux/regulator/machine.h>
30#include <linux/usb/gpio_vbus.h>
31
32#include <mach/hardware.h>
33#include <asm/mach-types.h>
34#include <asm/mach/arch.h>
35
36#include <mach/pxa27x.h>
37#include <mach/magician.h>
38#include <mach/pxafb.h>
39#include <plat/i2c.h>
40#include <mach/mmc.h>
41#include <mach/irda.h>
42#include <mach/ohci.h>
43
44#include "devices.h"
45#include "generic.h"
46
47static unsigned long magician_pin_config[] __initdata = {
48
49	/* SDRAM and Static Memory I/O Signals */
50	GPIO20_nSDCS_2,
51	GPIO21_nSDCS_3,
52	GPIO15_nCS_1,
53	GPIO78_nCS_2,   /* PASIC3 */
54	GPIO79_nCS_3,   /* EGPIO CPLD */
55	GPIO80_nCS_4,
56	GPIO33_nCS_5,
57
58	/* I2C */
59	GPIO117_I2C_SCL,
60	GPIO118_I2C_SDA,
61
62	/* PWM 0 */
63	GPIO16_PWM0_OUT,
64
65	/* I2S */
66	GPIO28_I2S_BITCLK_OUT,
67	GPIO29_I2S_SDATA_IN,
68	GPIO31_I2S_SYNC,
69	GPIO113_I2S_SYSCLK,
70
71	/* SSP 1 */
72	GPIO23_SSP1_SCLK,
73	GPIO24_SSP1_SFRM,
74	GPIO25_SSP1_TXD,
75
76	/* SSP 2 */
77	GPIO19_SSP2_SCLK,
78	GPIO14_SSP2_SFRM,
79	GPIO89_SSP2_TXD,
80	GPIO88_SSP2_RXD,
81
82	/* MMC */
83	GPIO32_MMC_CLK,
84	GPIO92_MMC_DAT_0,
85	GPIO109_MMC_DAT_1,
86	GPIO110_MMC_DAT_2,
87	GPIO111_MMC_DAT_3,
88	GPIO112_MMC_CMD,
89
90	/* LCD */
91	GPIOxx_LCD_TFT_16BPP,
92
93	/* QCI */
94	GPIO12_CIF_DD_7,
95	GPIO17_CIF_DD_6,
96	GPIO50_CIF_DD_3,
97	GPIO51_CIF_DD_2,
98	GPIO52_CIF_DD_4,
99	GPIO53_CIF_MCLK,
100	GPIO54_CIF_PCLK,
101	GPIO55_CIF_DD_1,
102	GPIO81_CIF_DD_0,
103	GPIO82_CIF_DD_5,
104	GPIO84_CIF_FV,
105	GPIO85_CIF_LV,
106
107	/* Magician specific input GPIOs */
108	GPIO9_GPIO,	/* unknown */
109	GPIO10_GPIO,	/* GSM_IRQ */
110	GPIO13_GPIO,	/* CPLD_IRQ */
111	GPIO107_GPIO,	/* DS1WM_IRQ */
112	GPIO108_GPIO,	/* GSM_READY */
113	GPIO115_GPIO,	/* nPEN_IRQ */
114
115	/* I2C */
116	GPIO117_I2C_SCL,
117	GPIO118_I2C_SDA,
118};
119
120/*
121 * IRDA
122 */
123
124static struct pxaficp_platform_data magician_ficp_info = {
125	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
126	.transceiver_cap	= IR_SIRMODE | IR_OFF,
127};
128
129/*
130 * GPIO Keys
131 */
132
133#define INIT_KEY(_code, _gpio, _desc)	\
134	{				\
135		.code   = KEY_##_code,	\
136		.gpio   = _gpio,	\
137		.desc   = _desc,	\
138		.type   = EV_KEY,	\
139		.wakeup = 1,		\
140	}
141
142static struct gpio_keys_button magician_button_table[] = {
143	INIT_KEY(POWER,      GPIO0_MAGICIAN_KEY_POWER,      "Power button"),
144	INIT_KEY(ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    "Hangup button"),
145	INIT_KEY(F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  "Contacts button"),
146	INIT_KEY(CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  "Calendar button"),
147	INIT_KEY(CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    "Camera button"),
148	INIT_KEY(UP,         GPIO93_MAGICIAN_KEY_UP,        "Up button"),
149	INIT_KEY(DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      "Down button"),
150	INIT_KEY(LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      "Left button"),
151	INIT_KEY(RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     "Right button"),
152	INIT_KEY(KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     "Action button"),
153	INIT_KEY(RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    "Record button"),
154	INIT_KEY(VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   "Volume up"),
155	INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
156	INIT_KEY(PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    "Phone button"),
157	INIT_KEY(PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  "Headset button"),
158};
159
160static struct gpio_keys_platform_data gpio_keys_data = {
161	.buttons  = magician_button_table,
162	.nbuttons = ARRAY_SIZE(magician_button_table),
163};
164
165static struct platform_device gpio_keys = {
166	.name = "gpio-keys",
167	.dev  = {
168		.platform_data = &gpio_keys_data,
169	},
170	.id   = -1,
171};
172
173
174/*
175 * EGPIO (Xilinx CPLD)
176 *
177 * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
178 */
179
180static struct resource egpio_resources[] = {
181	[0] = {
182		.start = PXA_CS3_PHYS,
183		.end   = PXA_CS3_PHYS + 0x20 - 1,
184		.flags = IORESOURCE_MEM,
185	},
186	[1] = {
187		.start = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ),
188		.end   = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ),
189		.flags = IORESOURCE_IRQ,
190	},
191};
192
193static struct htc_egpio_chip egpio_chips[] = {
194	[0] = {
195		.reg_start = 0,
196		.gpio_base = MAGICIAN_EGPIO(0, 0),
197		.num_gpios = 24,
198		.direction = HTC_EGPIO_OUTPUT,
199		.initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
200	},
201	[1] = {
202		.reg_start = 4,
203		.gpio_base = MAGICIAN_EGPIO(4, 0),
204		.num_gpios = 24,
205		.direction = HTC_EGPIO_INPUT,
206	},
207};
208
209static struct htc_egpio_platform_data egpio_info = {
210	.reg_width    = 8,
211	.bus_width    = 32,
212	.irq_base     = IRQ_BOARD_START,
213	.num_irqs     = 4,
214	.ack_register = 3,
215	.chip         = egpio_chips,
216	.num_chips    = ARRAY_SIZE(egpio_chips),
217};
218
219static struct platform_device egpio = {
220	.name          = "htc-egpio",
221	.id            = -1,
222	.resource      = egpio_resources,
223	.num_resources = ARRAY_SIZE(egpio_resources),
224	.dev = {
225		.platform_data = &egpio_info,
226	},
227};
228
229/*
230 * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
231 */
232
233static struct pxafb_mode_info toppoly_modes[] = {
234	{
235		.pixclock     = 96153,
236		.bpp          = 16,
237		.xres         = 240,
238		.yres         = 320,
239		.hsync_len    = 11,
240		.vsync_len    = 3,
241		.left_margin  = 19,
242		.upper_margin = 2,
243		.right_margin = 10,
244		.lower_margin = 2,
245		.sync         = 0,
246	},
247};
248
249static struct pxafb_mode_info samsung_modes[] = {
250	{
251		.pixclock     = 96153,
252		.bpp          = 16,
253		.xres         = 240,
254		.yres         = 320,
255		.hsync_len    = 8,
256		.vsync_len    = 4,
257		.left_margin  = 9,
258		.upper_margin = 4,
259		.right_margin = 9,
260		.lower_margin = 4,
261		.sync         = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
262	},
263};
264
265static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
266{
267	pr_debug("Toppoly LCD power\n");
268
269	if (on) {
270		pr_debug("on\n");
271		gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
272		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
273		udelay(2000);
274		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
275		udelay(2000);
276		udelay(2000);
277		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
278		udelay(2000);
279		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
280	} else {
281		pr_debug("off\n");
282		msleep(15);
283		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
284		udelay(500);
285		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
286		udelay(1000);
287		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
288		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
289	}
290}
291
292static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
293{
294	pr_debug("Samsung LCD power\n");
295
296	if (on) {
297		pr_debug("on\n");
298		if (system_rev < 3)
299			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
300		else
301			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
302		mdelay(10);
303		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
304		mdelay(10);
305		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
306		mdelay(30);
307		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
308		mdelay(10);
309	} else {
310		pr_debug("off\n");
311		mdelay(10);
312		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
313		mdelay(30);
314		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
315		mdelay(10);
316		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
317		mdelay(10);
318		if (system_rev < 3)
319			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
320		else
321			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
322	}
323}
324
325static struct pxafb_mach_info toppoly_info = {
326	.modes           = toppoly_modes,
327	.num_modes       = 1,
328	.fixed_modes     = 1,
329	.lcd_conn	= LCD_COLOR_TFT_16BPP,
330	.pxafb_lcd_power = toppoly_lcd_power,
331};
332
333static struct pxafb_mach_info samsung_info = {
334	.modes           = samsung_modes,
335	.num_modes       = 1,
336	.fixed_modes     = 1,
337	.lcd_conn	 = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\
338			   LCD_ALTERNATE_MAPPING,
339	.pxafb_lcd_power = samsung_lcd_power,
340};
341
342/*
343 * Backlight
344 */
345
346static int magician_backlight_init(struct device *dev)
347{
348	int ret;
349
350	ret = gpio_request(EGPIO_MAGICIAN_BL_POWER, "BL_POWER");
351	if (ret)
352		goto err;
353	ret = gpio_request(EGPIO_MAGICIAN_BL_POWER2, "BL_POWER2");
354	if (ret)
355		goto err2;
356	return 0;
357
358err2:
359	gpio_free(EGPIO_MAGICIAN_BL_POWER);
360err:
361	return ret;
362}
363
364static int magician_backlight_notify(struct device *dev, int brightness)
365{
366	gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
367	if (brightness >= 200) {
368		gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
369		return brightness - 72;
370	} else {
371		gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0);
372		return brightness;
373	}
374}
375
376static void magician_backlight_exit(struct device *dev)
377{
378	gpio_free(EGPIO_MAGICIAN_BL_POWER);
379	gpio_free(EGPIO_MAGICIAN_BL_POWER2);
380}
381
382static struct platform_pwm_backlight_data backlight_data = {
383	.pwm_id         = 0,
384	.max_brightness = 272,
385	.dft_brightness = 100,
386	.pwm_period_ns  = 30923,
387	.init           = magician_backlight_init,
388	.notify         = magician_backlight_notify,
389	.exit           = magician_backlight_exit,
390};
391
392static struct platform_device backlight = {
393	.name = "pwm-backlight",
394	.id   = -1,
395	.dev  = {
396		.parent        = &pxa27x_device_pwm0.dev,
397		.platform_data = &backlight_data,
398	},
399};
400
401/*
402 * LEDs
403 */
404
405static struct gpio_led gpio_leds[] = {
406	{
407		.name = "magician::vibra",
408		.default_trigger = "none",
409		.gpio = GPIO22_MAGICIAN_VIBRA_EN,
410	},
411	{
412		.name = "magician::phone_bl",
413		.default_trigger = "backlight",
414		.gpio = GPIO103_MAGICIAN_LED_KP,
415	},
416};
417
418static struct gpio_led_platform_data gpio_led_info = {
419	.leds = gpio_leds,
420	.num_leds = ARRAY_SIZE(gpio_leds),
421};
422
423static struct platform_device leds_gpio = {
424	.name = "leds-gpio",
425	.id   = -1,
426	.dev  = {
427		.platform_data = &gpio_led_info,
428	},
429};
430
431static struct pasic3_led pasic3_leds[] = {
432	{
433		.led = {
434			.name            = "magician:red",
435			.default_trigger = "ds2760-battery.0-charging",
436		},
437		.hw_num = 0,
438		.bit2   = PASIC3_BIT2_LED0,
439		.mask   = PASIC3_MASK_LED0,
440	},
441	{
442		.led = {
443			.name            = "magician:green",
444			.default_trigger = "ds2760-battery.0-charging-or-full",
445		},
446		.hw_num = 1,
447		.bit2   = PASIC3_BIT2_LED1,
448		.mask   = PASIC3_MASK_LED1,
449	},
450	{
451		.led = {
452			.name            = "magician:blue",
453			.default_trigger = "bluetooth",
454		},
455		.hw_num = 2,
456		.bit2   = PASIC3_BIT2_LED2,
457		.mask   = PASIC3_MASK_LED2,
458	},
459};
460
461static struct pasic3_leds_machinfo pasic3_leds_info = {
462	.num_leds   = ARRAY_SIZE(pasic3_leds),
463	.power_gpio = EGPIO_MAGICIAN_LED_POWER,
464	.leds       = pasic3_leds,
465};
466
467/*
468 * PASIC3 with DS1WM
469 */
470
471static struct resource pasic3_resources[] = {
472	[0] = {
473		.start  = PXA_CS2_PHYS,
474		.end	= PXA_CS2_PHYS + 0x1b,
475		.flags  = IORESOURCE_MEM,
476	},
477	/* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
478	[1] = {
479		.start  = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ),
480		.end    = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ),
481		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
482	}
483};
484
485static struct pasic3_platform_data pasic3_platform_data = {
486	.led_pdata  = &pasic3_leds_info,
487	.clock_rate = 4000000,
488};
489
490static struct platform_device pasic3 = {
491	.name		= "pasic3",
492	.id		= -1,
493	.num_resources	= ARRAY_SIZE(pasic3_resources),
494	.resource	= pasic3_resources,
495	.dev = {
496		.platform_data = &pasic3_platform_data,
497	},
498};
499
500/*
501 * USB "Transceiver"
502 */
503
504static struct resource gpio_vbus_resource = {
505	.flags = IORESOURCE_IRQ,
506	.start = IRQ_MAGICIAN_VBUS,
507	.end   = IRQ_MAGICIAN_VBUS,
508};
509
510static struct gpio_vbus_mach_info gpio_vbus_info = {
511	.gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
512	.gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
513};
514
515static struct platform_device gpio_vbus = {
516	.name          = "gpio-vbus",
517	.id            = -1,
518	.num_resources = 1,
519	.resource      = &gpio_vbus_resource,
520	.dev = {
521		.platform_data = &gpio_vbus_info,
522	},
523};
524
525/*
526 * External power
527 */
528
529static int power_supply_init(struct device *dev)
530{
531	return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
532}
533
534static int magician_is_ac_online(void)
535{
536	return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
537}
538
539static void power_supply_exit(struct device *dev)
540{
541	gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
542}
543
544static char *magician_supplicants[] = {
545	"ds2760-battery.0", "backup-battery"
546};
547
548static struct pda_power_pdata power_supply_info = {
549	.init            = power_supply_init,
550	.is_ac_online    = magician_is_ac_online,
551	.exit            = power_supply_exit,
552	.supplied_to     = magician_supplicants,
553	.num_supplicants = ARRAY_SIZE(magician_supplicants),
554};
555
556static struct resource power_supply_resources[] = {
557	[0] = {
558		.name  = "ac",
559		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
560		         IORESOURCE_IRQ_LOWEDGE,
561		.start = IRQ_MAGICIAN_VBUS,
562		.end   = IRQ_MAGICIAN_VBUS,
563	},
564	[1] = {
565		.name  = "usb",
566		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
567		         IORESOURCE_IRQ_LOWEDGE,
568		.start = IRQ_MAGICIAN_VBUS,
569		.end   = IRQ_MAGICIAN_VBUS,
570	},
571};
572
573static struct platform_device power_supply = {
574	.name = "pda-power",
575	.id   = -1,
576	.dev  = {
577		.platform_data = &power_supply_info,
578	},
579	.resource      = power_supply_resources,
580	.num_resources = ARRAY_SIZE(power_supply_resources),
581};
582
583/*
584 * Battery charger
585 */
586
587static struct regulator_consumer_supply bq24022_consumers[] = {
588	{
589		.dev = &gpio_vbus.dev,
590		.supply = "vbus_draw",
591	},
592	{
593		.dev = &power_supply.dev,
594		.supply = "ac_draw",
595	},
596};
597
598static struct regulator_init_data bq24022_init_data = {
599	.constraints = {
600		.max_uA         = 500000,
601		.valid_ops_mask = REGULATOR_CHANGE_CURRENT,
602	},
603	.num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
604	.consumer_supplies      = bq24022_consumers,
605};
606
607static struct bq24022_mach_info bq24022_info = {
608	.gpio_nce   = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
609	.gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2,
610	.init_data  = &bq24022_init_data,
611};
612
613static struct platform_device bq24022 = {
614	.name = "bq24022",
615	.id   = -1,
616	.dev  = {
617		.platform_data = &bq24022_info,
618	},
619};
620
621/*
622 * MMC/SD
623 */
624
625static int magician_mci_init(struct device *dev,
626				irq_handler_t detect_irq, void *data)
627{
628	return request_irq(IRQ_MAGICIAN_SD, detect_irq,
629				IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
630				"mmc card detect", data);
631}
632
633static void magician_mci_exit(struct device *dev, void *data)
634{
635	free_irq(IRQ_MAGICIAN_SD, data);
636}
637
638static struct pxamci_platform_data magician_mci_info = {
639	.ocr_mask 		= MMC_VDD_32_33|MMC_VDD_33_34,
640	.init     		= magician_mci_init,
641	.exit     		= magician_mci_exit,
642	.gpio_card_detect	= -1,
643	.gpio_card_ro		= EGPIO_MAGICIAN_nSD_READONLY,
644	.gpio_card_ro_invert	= 1,
645	.gpio_power		= EGPIO_MAGICIAN_SD_POWER,
646};
647
648
649/*
650 * USB OHCI
651 */
652
653static struct pxaohci_platform_data magician_ohci_info = {
654	.port_mode	= PMM_PERPORT_MODE,
655	.flags		= ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
656	.power_budget	= 0,
657};
658
659
660/*
661 * StrataFlash
662 */
663
664static void magician_set_vpp(struct map_info *map, int vpp)
665{
666	gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
667}
668
669static struct resource strataflash_resource = {
670	.start = PXA_CS0_PHYS,
671	.end   = PXA_CS0_PHYS + SZ_64M - 1,
672	.flags = IORESOURCE_MEM,
673};
674
675static struct physmap_flash_data strataflash_data = {
676	.width = 4,
677	.set_vpp = magician_set_vpp,
678};
679
680static struct platform_device strataflash = {
681	.name          = "physmap-flash",
682	.id            = -1,
683	.resource      = &strataflash_resource,
684	.num_resources = 1,
685	.dev = {
686		.platform_data = &strataflash_data,
687	},
688};
689
690/*
691 * I2C
692 */
693
694static struct i2c_pxa_platform_data i2c_info = {
695	.fast_mode = 1,
696};
697
698/*
699 * Platform devices
700 */
701
702static struct platform_device *devices[] __initdata = {
703	&gpio_keys,
704	&egpio,
705	&backlight,
706	&pasic3,
707	&bq24022,
708	&gpio_vbus,
709	&power_supply,
710	&strataflash,
711	&leds_gpio,
712};
713
714static void __init magician_init(void)
715{
716	void __iomem *cpld;
717	int lcd_select;
718	int err;
719
720	gpio_request(GPIO13_MAGICIAN_CPLD_IRQ, "CPLD_IRQ");
721	gpio_request(GPIO107_MAGICIAN_DS1WM_IRQ, "DS1WM_IRQ");
722
723	pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
724
725	pxa_set_ffuart_info(NULL);
726	pxa_set_btuart_info(NULL);
727	pxa_set_stuart_info(NULL);
728
729	platform_add_devices(ARRAY_AND_SIZE(devices));
730
731	err = gpio_request(GPIO83_MAGICIAN_nIR_EN, "nIR_EN");
732	if (!err) {
733		gpio_direction_output(GPIO83_MAGICIAN_nIR_EN, 1);
734		pxa_set_ficp_info(&magician_ficp_info);
735	}
736	pxa27x_set_i2c_power_info(NULL);
737	pxa_set_i2c_info(&i2c_info);
738	pxa_set_mci_info(&magician_mci_info);
739	pxa_set_ohci_info(&magician_ohci_info);
740
741	/* Check LCD type we have */
742	cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
743	if (cpld) {
744		u8 board_id = __raw_readb(cpld+0x14);
745		iounmap(cpld);
746		system_rev = board_id & 0x7;
747		lcd_select = board_id & 0x8;
748		pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
749		if (lcd_select && (system_rev < 3)) {
750			gpio_request(GPIO75_MAGICIAN_SAMSUNG_POWER, "SAMSUNG_POWER");
751			gpio_direction_output(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
752		}
753		gpio_request(GPIO104_MAGICIAN_LCD_POWER_1, "LCD_POWER_1");
754		gpio_request(GPIO105_MAGICIAN_LCD_POWER_2, "LCD_POWER_2");
755		gpio_request(GPIO106_MAGICIAN_LCD_POWER_3, "LCD_POWER_3");
756		gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0);
757		gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0);
758		gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0);
759		set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info);
760	} else
761		pr_err("LCD detection: CPLD mapping failed\n");
762}
763
764
765MACHINE_START(MAGICIAN, "HTC Magician")
766	.phys_io = 0x40000000,
767	.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
768	.boot_params = 0xa0000100,
769	.map_io = pxa_map_io,
770	.init_irq = pxa27x_init_irq,
771	.init_machine = magician_init,
772	.timer = &pxa_timer,
773MACHINE_END
774