3 * Hardware definitions for the HTC Magician
5 * Copyright 2006 Philipp Zabel
8 * Copyright 2005 SDG Systems, LLC
10 * Use consistent with the GNU GPL is permitted,
11 * provided that this copyright notice is
12 * preserved in its entirety in all copies and derived works.
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/ioport.h>
19 #include <linux/platform_device.h>
20 #include <linux/input.h>
21 #include <linux/interrupt.h>
22 #include <linux/delay.h>
24 #include <linux/spi/spi.h>
25 #include <linux/spi/ads7846.h>
27 #include <asm/mach-types.h>
28 #include <asm/hardware.h>
29 #include <asm/mach/arch.h>
30 #include <asm/mach/map.h>
32 #include <asm/arch/magician.h>
33 #include <asm/arch/pxa-regs.h>
34 #include <asm/arch/serial.h>
35 #include <asm/arch/pxa2xx_spi.h>
36 #include <asm/hardware/gpio_keys.h>
37 #include <asm/arch/mmc.h>
38 #include <asm/arch/udc.h>
39 #include <asm/arch/audio.h>
40 #include <asm/arch/irda.h>
41 #include <asm/arch/ohci.h>
43 #include <linux/corgi_bl.h>
45 #include "../generic.h"
51 static void magician_irda_transceiver_mode(struct device
*dev
, int mode
)
55 local_irq_save(flags
);
57 SET_MAGICIAN_GPIO_N(IR_ON
, 0);
59 SET_MAGICIAN_GPIO_N(IR_ON
, 1);
60 local_irq_restore(flags
);
63 static struct pxaficp_platform_data magician_ficp_platform_data
= {
64 .transceiver_cap
= IR_SIRMODE
| IR_OFF
,
65 .transceiver_mode
= magician_irda_transceiver_mode
,
72 struct magician_phone_funcs
{
73 void (*configure
) (int state
);
76 static struct magician_phone_funcs phone_funcs
;
78 static void magician_phone_configure (int state
, int suspend
)
80 if (phone_funcs
.configure
)
81 phone_funcs
.configure (state
);
84 static struct platform_pxa_serial_funcs magician_pxa_phone_funcs
= {
85 .configure
= magician_phone_configure
,
88 static struct platform_device magician_phone
= {
89 .name
= "magician-phone",
91 .platform_data
= &phone_funcs
,
101 static void __init
magician_map_io(void)
104 btuart_device
.dev
.platform_data
= &magician_pxa_phone_funcs
;
107 static void __init
magician_init_irq(void)
118 struct platform_device magician_pm
= {
119 .name
= "magician-pm",
122 .platform_data
= NULL
,
130 static struct resource magician_cpld_resources
[] = {
132 .start
= PXA_CS3_PHYS
,
133 .end
= PXA_CS3_PHYS
+ 0x1000,
134 .flags
= IORESOURCE_MEM
,
137 .start
= MAGICIAN_IRQ(CPLD_IRQ
),
138 .end
= MAGICIAN_IRQ(CPLD_IRQ
),
139 .flags
= IORESOURCE_IRQ
,
143 struct platform_device magician_cpld
= {
144 .name
= "magician-cpld",
146 .num_resources
= ARRAY_SIZE(magician_cpld_resources
),
147 .resource
= magician_cpld_resources
,
149 EXPORT_SYMBOL(magician_cpld
);
152 * USB Device Controller
155 static void magician_udc_command(int cmd
)
157 printk ("magician_udc_command(%d)\n", cmd
);
159 case PXA2XX_UDC_CMD_CONNECT
:
160 UP2OCR
= UP2OCR_HXOE
| UP2OCR_DMPUE
| UP2OCR_DMPUBE
;
161 SET_MAGICIAN_GPIO(USB_PUEN
, 1);
163 case PXA2XX_UDC_CMD_DISCONNECT
:
164 UP2OCR
= UP2OCR_HXOE
| UP2OCR_DMPUE
| UP2OCR_DMPUBE
;
165 SET_MAGICIAN_GPIO(USB_PUEN
, 0);
170 static struct pxa2xx_udc_mach_info magician_udc_mach_info __initdata
= {
171 /* .udc_is_connected = is not used by pxa27x_udc.c at all */
172 .udc_command
= magician_udc_command
,
179 static struct gpio_keys_button magician_button_table
[] = {
180 {KEY_POWER
, GPIO_NR_MAGICIAN_KEY_ON
, 0},
181 {KEY_F8
, GPIO_NR_MAGICIAN_KEY_PHONE_HANGUP
, 0},
182 {KEY_F5
, GPIO_NR_MAGICIAN_KEY_CONTACTS
, 0},
183 {KEY_F9
, GPIO_NR_MAGICIAN_KEY_CALENDAR
, 0},
184 {KEY_F10
, GPIO_NR_MAGICIAN_KEY_CAMERA
, 0},
185 {KEY_UP
, GPIO_NR_MAGICIAN_KEY_UP
, 0},
186 {KEY_DOWN
, GPIO_NR_MAGICIAN_KEY_DOWN
, 0},
187 {KEY_LEFT
, GPIO_NR_MAGICIAN_KEY_LEFT
, 0},
188 {KEY_RIGHT
, GPIO_NR_MAGICIAN_KEY_RIGHT
, 0},
189 {KEY_KPENTER
, GPIO_NR_MAGICIAN_KEY_ENTER
, 0},
190 {KEY_F9
, GPIO_NR_MAGICIAN_KEY_RECORD
, 0},
191 {KEY_VOLUMEUP
, GPIO_NR_MAGICIAN_KEY_VOLUMEUP
, 0},
192 {KEY_VOLUMEDOWN
, GPIO_NR_MAGICIAN_KEY_VOLUMEDOWN
, 0},
193 {KEY_F7
, GPIO_NR_MAGICIAN_KEY_PHONE_LIFT
, 0},
196 static struct gpio_keys_platform_data magician_gpio_keys_data
= {
197 .buttons
= magician_button_table
,
198 .nbuttons
= ARRAY_SIZE(magician_button_table
),
201 static struct platform_device magician_gpio_keys
= {
204 .platform_data
= &magician_gpio_keys_data
,
213 static struct platform_device magician_lcd
= {
214 .name
= "magician-lcd",
216 .platform_data
= NULL
,
225 static void magician_set_bl_intensity(int intensity
)
230 if (intensity
> 0xc7) {
231 PWM_PWDUTY0
= intensity
- 0x48;
232 magician_egpio_enable(&magician_cpld
, EGPIO_NR_MAGICIAN_BL_POWER2
);
234 PWM_PWDUTY0
= intensity
;
235 magician_egpio_disable(&magician_cpld
, EGPIO_NR_MAGICIAN_BL_POWER2
);
237 magician_egpio_enable(&magician_cpld
, EGPIO_NR_MAGICIAN_BL_POWER
);
238 pxa_set_cken(CKEN0_PWM0
, 1);
240 magician_egpio_disable(&magician_cpld
, EGPIO_NR_MAGICIAN_BL_POWER
);
241 pxa_set_cken(CKEN0_PWM0
, 0);
245 static struct corgibl_machinfo magician_bl_machinfo
= {
246 .default_intensity
= 0x64,
248 .max_intensity
= 0xc7+0x48,
249 .set_bl_intensity
= magician_set_bl_intensity
,
252 static struct platform_device magician_bl
= {
255 .platform_data
= &magician_bl_machinfo
,
260 /* Touchscreen, the TSC2046 chipset is pin-compatible to ADS7846 */
262 static struct platform_device magician_ts
= {
263 .name
= "magician-ts",
265 .platform_data
= NULL
,
270 int magician_get_pendown_state()
272 return GET_MAGICIAN_GPIO(TOUCHPANEL_IRQ_N
) ? 0 : 1;
275 EXPORT_SYMBOL(magician_get_pendown_state
);
277 static struct ads7846_platform_data magician_tsc2046_platform_data __initdata
= {
280 .x_plate_ohms
= 180, /* GUESS */
281 .y_plate_ohms
= 180, /* GUESS */
282 .vref_delay_usecs
= 100,
286 .get_pendown_state
= &magician_get_pendown_state
,
289 struct pxa2xx_spi_chip tsc2046_chip_info
= {
292 .timeout_microsecs
= 64,
295 static struct spi_board_info magician_spi_board_info
[] __initdata
= {
297 .modalias
= "ads7846",
299 .max_speed_hz
= 1857143,
300 .irq
= MAGICIAN_IRQ(TOUCHPANEL_IRQ_N
),
301 .platform_data
= &magician_tsc2046_platform_data
,
302 .controller_data
= &tsc2046_chip_info
,
306 static struct resource pxa_spi_ssp2_resources
[] = {
308 .start
= __PREG(SSCR0_P(2)),
309 .end
= __PREG(SSCR0_P(2)) + 0x2c,
310 .flags
= IORESOURCE_MEM
,
315 .flags
= IORESOURCE_IRQ
,
319 static struct pxa2xx_spi_master pxa_ssp2_master_info
= {
320 .ssp_type
= PXA27x_SSP
,
321 .clock_enable
= CKEN3_SSP2
,
322 // .num_chipselect = 1,
325 static struct platform_device pxa_spi_ssp2
= {
326 .name
= "pxa2xx-spi",
328 .resource
= pxa_spi_ssp2_resources
,
329 .num_resources
= ARRAY_SIZE(pxa_spi_ssp2_resources
),
331 .platform_data
= &pxa_ssp2_master_info
,
339 static struct platform_device magician_led
= {
340 .name
= "magician-led",
348 static struct pxamci_platform_data magician_mci_platform_data
;
350 static int magician_mci_init(struct device
*dev
, irq_handler_t magician_detect_int
, void *data
)
354 err
= request_irq(IRQ_MAGICIAN_SD
, magician_detect_int
,
355 IRQF_DISABLED
| IRQF_SAMPLE_RANDOM
,
356 "MMC card detect", data
);
358 printk(KERN_ERR
"magician_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
365 static void magician_mci_setpower(struct device
*dev
, unsigned int vdd
)
367 struct pxamci_platform_data
* p_d
= dev
->platform_data
;
369 if (( 1 << vdd
) & p_d
->ocr_mask
)
370 magician_egpio_enable(&magician_cpld
, EGPIO_NR_MAGICIAN_SD_POWER
);
372 magician_egpio_disable(&magician_cpld
, EGPIO_NR_MAGICIAN_SD_POWER
);
375 static int magician_mci_get_ro(struct device
*dev
)
377 /* FIXME return (cpld->mapping->cpld14 & 0x10) ? 1 : 0; */
381 static void magician_mci_exit(struct device
*dev
, void *data
)
383 free_irq(IRQ_MAGICIAN_SD
, data
);
386 static struct pxamci_platform_data magician_mci_platform_data
= {
387 .ocr_mask
= MMC_VDD_32_33
|MMC_VDD_33_34
,
388 .init
= magician_mci_init
,
389 .get_ro
= magician_mci_get_ro
,
390 .setpower
= magician_mci_setpower
,
391 .exit
= magician_mci_exit
,
397 static int magician_ohci_init(struct device
*dev
)
399 /* missing GPIO setup here */
401 /* no idea what this does, got the values from haret */
402 UHCHR
= (UHCHR
| UHCHR_SSEP2
| UHCHR_PCPL
| UHCHR_CGR
) &
403 ~(UHCHR_SSEP1
| UHCHR_SSEP3
| UHCHR_SSE
);
408 static struct pxaohci_platform_data magician_ohci_platform_data
= {
409 .port_mode
= PMM_PERPORT_MODE
,
410 .init
= magician_ohci_init
,
413 static struct platform_device
*devices
[] __initdata
= {
417 &magician_lcd
, // needs the cpld to power on/off the lcd
427 static void __init
magician_init(void)
432 #if 0 // GPIO/MSC setup from bootldr
433 /* 0x1350 0x41664 (resume) */
434 GPSR0
= 0x4034c000; // 0x0030c800 <-- set 11, clear 18, clear 30
435 GPSR1
= 0x0002321a; // GPSR1 = (PGSR1 & 0x01000100) | 0x0002420a <-- clear 36 44 45, set 46 and get 40 and 66 from PGSR1
436 GPSR2
= 0x0009c000; // 0x0009c000
437 GPSR3
= 0x01180000; // 0x00180000 <-- clear gpio24
441 GPDR0
= 0xfdfdc80c; // 0xfdfdc80c
442 GPDR1
= 0xff23990b; // 0xff23ab83
443 GPDR2
= 0x02c9ffff; // 0x02c9ffff
444 GPDR3
= 0x01b60780; // 0x01b60780
445 GAFR0_L
= 0xa2000000; // 0xa2000000
446 GAFR0_U
= 0x490a845a; // 0x490a854a <-- 2(1->0) 4(0->1)
447 GAFR1_L
= 0x6998815a; // 0x6918005a <-- 20(1->0) 23(2->0) 27(2->0)
448 GAFR1_U
= 0xaaa07958; // 0xaaa07958
449 GAFR2_L
= 0xaa0aaaaa; // 0xaa0aaaaa
450 GAFR2_U
= 0x010e0f3a; // 0x010e0f3a
451 GAFR3_L
= 0x54000000; // 0x54000000
452 GAFR3_U
= 0x00001405; // 0x00001405
453 MSC0
= 0x7ff001a0; // 0x7ff005a2 <-- ( RBUFF,RRR RDN, RDF, RBW,RT ) ( RBUFF,RRR RDN, RDF, RBW,RT )
454 MSC1
= 0x7ff01880; // 0x18801880 <--
455 MSC2
= 0x16607ff0; // 0x16607ff0
458 /* set USBC_PUEN - in wince it is turned off when the plug is pulled. */
459 GPSR(27) = GPIO_bit(27);
460 // should this be controlled by the USBC_DET irq from the cpld? (on gpio 13)
462 platform_add_devices(devices
, ARRAY_SIZE(devices
));
464 spi_register_board_info(magician_spi_board_info
,
465 ARRAY_SIZE(magician_spi_board_info
));
467 pxa_set_mci_info(&magician_mci_platform_data
);
468 pxa_set_ohci_info(&magician_ohci_platform_data
);
469 // pxa_set_btuart_info(&magician_pxa_phone_funcs);
470 pxa_set_udc_info(&magician_udc_mach_info
);
471 pxa_set_ficp_info(&magician_ficp_platform_data
);
475 MACHINE_START(MAGICIAN
, "HTC Magician")
476 .phys_io
= 0x40000000,.io_pg_offst
=
477 (io_p2v(0x40000000) >> 18) & 0xfffc,
478 .boot_params
= 0xa0000100,
479 .map_io
= magician_map_io
,
480 .init_irq
= magician_init_irq
,
482 .init_machine
= magician_init
,