PageRenderTime 73ms CodeModel.GetById 8ms app.highlight 59ms RepoModel.GetById 2ms app.codeStats 0ms

/arch/arm/mach-pxa/magician.c

https://github.com/AICP/kernel_asus_grouper
C | 763 lines | 590 code | 98 blank | 75 comment | 12 complexity | 75592efee3427b7c418b5d1de7d79b90 MD5 | raw file
  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#include <linux/i2c/pxa-i2c.h>
 32
 33#include <mach/hardware.h>
 34#include <asm/mach-types.h>
 35#include <asm/mach/arch.h>
 36
 37#include <mach/pxa27x.h>
 38#include <mach/magician.h>
 39#include <mach/pxafb.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		/* FIXME: enable LCDC here */
277		udelay(2000);
278		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
279		udelay(2000);
280		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
281	} else {
282		pr_debug("off\n");
283		msleep(15);
284		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
285		udelay(500);
286		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
287		udelay(1000);
288		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
289		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
290	}
291}
292
293static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
294{
295	pr_debug("Samsung LCD power\n");
296
297	if (on) {
298		pr_debug("on\n");
299		if (system_rev < 3)
300			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
301		else
302			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
303		mdelay(10);
304		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
305		mdelay(10);
306		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
307		mdelay(30);
308		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
309		mdelay(10);
310	} else {
311		pr_debug("off\n");
312		mdelay(10);
313		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
314		mdelay(30);
315		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
316		mdelay(10);
317		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
318		mdelay(10);
319		if (system_rev < 3)
320			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
321		else
322			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
323	}
324}
325
326static struct pxafb_mach_info toppoly_info = {
327	.modes           = toppoly_modes,
328	.num_modes       = 1,
329	.fixed_modes     = 1,
330	.lcd_conn	= LCD_COLOR_TFT_16BPP,
331	.pxafb_lcd_power = toppoly_lcd_power,
332};
333
334static struct pxafb_mach_info samsung_info = {
335	.modes           = samsung_modes,
336	.num_modes       = 1,
337	.fixed_modes     = 1,
338	.lcd_conn	 = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\
339			   LCD_ALTERNATE_MAPPING,
340	.pxafb_lcd_power = samsung_lcd_power,
341};
342
343/*
344 * Backlight
345 */
346
347static struct gpio magician_bl_gpios[] = {
348	{ EGPIO_MAGICIAN_BL_POWER,  GPIOF_DIR_OUT, "Backlight power" },
349	{ EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Backlight power 2" },
350};
351
352static int magician_backlight_init(struct device *dev)
353{
354	return gpio_request_array(ARRAY_AND_SIZE(magician_bl_gpios));
355}
356
357static int magician_backlight_notify(struct device *dev, int brightness)
358{
359	gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
360	if (brightness >= 200) {
361		gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
362		return brightness - 72;
363	} else {
364		gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0);
365		return brightness;
366	}
367}
368
369static void magician_backlight_exit(struct device *dev)
370{
371	gpio_free_array(ARRAY_AND_SIZE(magician_bl_gpios));
372}
373
374static struct platform_pwm_backlight_data backlight_data = {
375	.pwm_id         = 0,
376	.max_brightness = 272,
377	.dft_brightness = 100,
378	.pwm_period_ns  = 30923,
379	.init           = magician_backlight_init,
380	.notify         = magician_backlight_notify,
381	.exit           = magician_backlight_exit,
382};
383
384static struct platform_device backlight = {
385	.name = "pwm-backlight",
386	.id   = -1,
387	.dev  = {
388		.parent        = &pxa27x_device_pwm0.dev,
389		.platform_data = &backlight_data,
390	},
391};
392
393/*
394 * LEDs
395 */
396
397static struct gpio_led gpio_leds[] = {
398	{
399		.name = "magician::vibra",
400		.default_trigger = "none",
401		.gpio = GPIO22_MAGICIAN_VIBRA_EN,
402	},
403	{
404		.name = "magician::phone_bl",
405		.default_trigger = "backlight",
406		.gpio = GPIO103_MAGICIAN_LED_KP,
407	},
408};
409
410static struct gpio_led_platform_data gpio_led_info = {
411	.leds = gpio_leds,
412	.num_leds = ARRAY_SIZE(gpio_leds),
413};
414
415static struct platform_device leds_gpio = {
416	.name = "leds-gpio",
417	.id   = -1,
418	.dev  = {
419		.platform_data = &gpio_led_info,
420	},
421};
422
423static struct pasic3_led pasic3_leds[] = {
424	{
425		.led = {
426			.name            = "magician:red",
427			.default_trigger = "ds2760-battery.0-charging",
428		},
429		.hw_num = 0,
430		.bit2   = PASIC3_BIT2_LED0,
431		.mask   = PASIC3_MASK_LED0,
432	},
433	{
434		.led = {
435			.name            = "magician:green",
436			.default_trigger = "ds2760-battery.0-charging-or-full",
437		},
438		.hw_num = 1,
439		.bit2   = PASIC3_BIT2_LED1,
440		.mask   = PASIC3_MASK_LED1,
441	},
442	{
443		.led = {
444			.name            = "magician:blue",
445			.default_trigger = "bluetooth",
446		},
447		.hw_num = 2,
448		.bit2   = PASIC3_BIT2_LED2,
449		.mask   = PASIC3_MASK_LED2,
450	},
451};
452
453static struct pasic3_leds_machinfo pasic3_leds_info = {
454	.num_leds   = ARRAY_SIZE(pasic3_leds),
455	.power_gpio = EGPIO_MAGICIAN_LED_POWER,
456	.leds       = pasic3_leds,
457};
458
459/*
460 * PASIC3 with DS1WM
461 */
462
463static struct resource pasic3_resources[] = {
464	[0] = {
465		.start  = PXA_CS2_PHYS,
466		.end	= PXA_CS2_PHYS + 0x1b,
467		.flags  = IORESOURCE_MEM,
468	},
469	/* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
470	[1] = {
471		.start  = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ),
472		.end    = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ),
473		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
474	}
475};
476
477static struct pasic3_platform_data pasic3_platform_data = {
478	.led_pdata  = &pasic3_leds_info,
479	.clock_rate = 4000000,
480};
481
482static struct platform_device pasic3 = {
483	.name		= "pasic3",
484	.id		= -1,
485	.num_resources	= ARRAY_SIZE(pasic3_resources),
486	.resource	= pasic3_resources,
487	.dev = {
488		.platform_data = &pasic3_platform_data,
489	},
490};
491
492/*
493 * USB "Transceiver"
494 */
495
496static struct resource gpio_vbus_resource = {
497	.flags = IORESOURCE_IRQ,
498	.start = IRQ_MAGICIAN_VBUS,
499	.end   = IRQ_MAGICIAN_VBUS,
500};
501
502static struct gpio_vbus_mach_info gpio_vbus_info = {
503	.gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
504	.gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
505};
506
507static struct platform_device gpio_vbus = {
508	.name          = "gpio-vbus",
509	.id            = -1,
510	.num_resources = 1,
511	.resource      = &gpio_vbus_resource,
512	.dev = {
513		.platform_data = &gpio_vbus_info,
514	},
515};
516
517/*
518 * External power
519 */
520
521static int power_supply_init(struct device *dev)
522{
523	return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
524}
525
526static int magician_is_ac_online(void)
527{
528	return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
529}
530
531static void power_supply_exit(struct device *dev)
532{
533	gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
534}
535
536static char *magician_supplicants[] = {
537	"ds2760-battery.0", "backup-battery"
538};
539
540static struct pda_power_pdata power_supply_info = {
541	.init            = power_supply_init,
542	.is_ac_online    = magician_is_ac_online,
543	.exit            = power_supply_exit,
544	.supplied_to     = magician_supplicants,
545	.num_supplicants = ARRAY_SIZE(magician_supplicants),
546};
547
548static struct resource power_supply_resources[] = {
549	[0] = {
550		.name  = "ac",
551		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
552		         IORESOURCE_IRQ_LOWEDGE,
553		.start = IRQ_MAGICIAN_VBUS,
554		.end   = IRQ_MAGICIAN_VBUS,
555	},
556	[1] = {
557		.name  = "usb",
558		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
559		         IORESOURCE_IRQ_LOWEDGE,
560		.start = IRQ_MAGICIAN_VBUS,
561		.end   = IRQ_MAGICIAN_VBUS,
562	},
563};
564
565static struct platform_device power_supply = {
566	.name = "pda-power",
567	.id   = -1,
568	.dev  = {
569		.platform_data = &power_supply_info,
570	},
571	.resource      = power_supply_resources,
572	.num_resources = ARRAY_SIZE(power_supply_resources),
573};
574
575/*
576 * Battery charger
577 */
578
579static struct regulator_consumer_supply bq24022_consumers[] = {
580	{
581		.dev = &gpio_vbus.dev,
582		.supply = "vbus_draw",
583	},
584	{
585		.dev = &power_supply.dev,
586		.supply = "ac_draw",
587	},
588};
589
590static struct regulator_init_data bq24022_init_data = {
591	.constraints = {
592		.max_uA         = 500000,
593		.valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
594	},
595	.num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
596	.consumer_supplies      = bq24022_consumers,
597};
598
599static struct bq24022_mach_info bq24022_info = {
600	.gpio_nce   = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
601	.gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2,
602	.init_data  = &bq24022_init_data,
603};
604
605static struct platform_device bq24022 = {
606	.name = "bq24022",
607	.id   = -1,
608	.dev  = {
609		.platform_data = &bq24022_info,
610	},
611};
612
613/*
614 * MMC/SD
615 */
616
617static int magician_mci_init(struct device *dev,
618				irq_handler_t detect_irq, void *data)
619{
620	return request_irq(IRQ_MAGICIAN_SD, detect_irq,
621				IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
622				"mmc card detect", data);
623}
624
625static void magician_mci_exit(struct device *dev, void *data)
626{
627	free_irq(IRQ_MAGICIAN_SD, data);
628}
629
630static struct pxamci_platform_data magician_mci_info = {
631	.ocr_mask 		= MMC_VDD_32_33|MMC_VDD_33_34,
632	.init     		= magician_mci_init,
633	.exit     		= magician_mci_exit,
634	.gpio_card_detect	= -1,
635	.gpio_card_ro		= EGPIO_MAGICIAN_nSD_READONLY,
636	.gpio_card_ro_invert	= 1,
637	.gpio_power		= EGPIO_MAGICIAN_SD_POWER,
638};
639
640
641/*
642 * USB OHCI
643 */
644
645static struct pxaohci_platform_data magician_ohci_info = {
646	.port_mode	= PMM_PERPORT_MODE,
647	.flags		= ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
648	.power_budget	= 0,
649};
650
651
652/*
653 * StrataFlash
654 */
655
656static void magician_set_vpp(struct platform_device *pdev, int vpp)
657{
658	gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
659}
660
661static struct resource strataflash_resource = {
662	.start = PXA_CS0_PHYS,
663	.end   = PXA_CS0_PHYS + SZ_64M - 1,
664	.flags = IORESOURCE_MEM,
665};
666
667static struct physmap_flash_data strataflash_data = {
668	.width = 4,
669	.set_vpp = magician_set_vpp,
670};
671
672static struct platform_device strataflash = {
673	.name          = "physmap-flash",
674	.id            = -1,
675	.resource      = &strataflash_resource,
676	.num_resources = 1,
677	.dev = {
678		.platform_data = &strataflash_data,
679	},
680};
681
682/*
683 * I2C
684 */
685
686static struct i2c_pxa_platform_data i2c_info = {
687	.fast_mode = 1,
688};
689
690/*
691 * Platform devices
692 */
693
694static struct platform_device *devices[] __initdata = {
695	&gpio_keys,
696	&egpio,
697	&backlight,
698	&pasic3,
699	&bq24022,
700	&gpio_vbus,
701	&power_supply,
702	&strataflash,
703	&leds_gpio,
704};
705
706static struct gpio magician_global_gpios[] = {
707	{ GPIO13_MAGICIAN_CPLD_IRQ,   GPIOF_IN, "CPLD_IRQ" },
708	{ GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
709	{ GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
710	{ GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
711	{ GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
712	{ GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" },
713};
714
715static void __init magician_init(void)
716{
717	void __iomem *cpld;
718	int lcd_select;
719	int err;
720
721	pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
722	err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
723	if (err)
724		pr_err("magician: Failed to request GPIOs: %d\n", err);
725
726	pxa_set_ffuart_info(NULL);
727	pxa_set_btuart_info(NULL);
728	pxa_set_stuart_info(NULL);
729
730	platform_add_devices(ARRAY_AND_SIZE(devices));
731
732	pxa_set_ficp_info(&magician_ficp_info);
733	pxa27x_set_i2c_power_info(NULL);
734	pxa_set_i2c_info(&i2c_info);
735	pxa_set_mci_info(&magician_mci_info);
736	pxa_set_ohci_info(&magician_ohci_info);
737
738	/* Check LCD type we have */
739	cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
740	if (cpld) {
741		u8 board_id = __raw_readb(cpld+0x14);
742		iounmap(cpld);
743		system_rev = board_id & 0x7;
744		lcd_select = board_id & 0x8;
745		pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
746		if (lcd_select && (system_rev < 3))
747			gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
748			                 GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
749		pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
750	} else
751		pr_err("LCD detection: CPLD mapping failed\n");
752}
753
754
755MACHINE_START(MAGICIAN, "HTC Magician")
756	.boot_params = 0xa0000100,
757	.map_io = pxa27x_map_io,
758	.nr_irqs = MAGICIAN_NR_IRQS,
759	.init_irq = pxa27x_init_irq,
760	.handle_irq = pxa27x_handle_irq,
761	.init_machine = magician_init,
762	.timer = &pxa_timer,
763MACHINE_END