hh.org updates
[hh.org.git] / arch / arm / mach-pxa / magician / magician.c
blob47ae88c83fc4156ead8b104c32f29542f814c92f
1 /*
3 * Hardware definitions for the HTC Magician
5 * Copyright 2006 Philipp Zabel
7 * Based on hx4700.c
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"
48 * IRDA
51 static void magician_irda_transceiver_mode(struct device *dev, int mode)
53 unsigned long flags;
55 local_irq_save(flags);
56 if (mode & IR_OFF)
57 SET_MAGICIAN_GPIO_N(IR_ON, 0);
58 else
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,
69 * Phone
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",
90 .dev = {
91 .platform_data = &phone_funcs,
93 .id = -1,
98 * Initialization code
101 static void __init magician_map_io(void)
103 pxa_map_io();
104 btuart_device.dev.platform_data = &magician_pxa_phone_funcs;
107 static void __init magician_init_irq(void)
109 /* int irq; */
111 pxa_init_irq();
115 * Power Management
118 struct platform_device magician_pm = {
119 .name = "magician-pm",
120 .id = -1,
121 .dev = {
122 .platform_data = NULL,
127 * CPLD
130 static struct resource magician_cpld_resources[] = {
131 [0] = {
132 .start = PXA_CS3_PHYS,
133 .end = PXA_CS3_PHYS + 0x1000,
134 .flags = IORESOURCE_MEM,
136 [1] = {
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",
145 .id = 0,
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);
158 switch(cmd) {
159 case PXA2XX_UDC_CMD_CONNECT:
160 UP2OCR = UP2OCR_HXOE | UP2OCR_DMPUE | UP2OCR_DMPUBE;
161 SET_MAGICIAN_GPIO(USB_PUEN, 1);
162 break;
163 case PXA2XX_UDC_CMD_DISCONNECT:
164 UP2OCR = UP2OCR_HXOE | UP2OCR_DMPUE | UP2OCR_DMPUBE;
165 SET_MAGICIAN_GPIO(USB_PUEN, 0);
166 break;
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,
176 * GPIO Keys
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 = {
202 .name = "gpio-keys",
203 .dev = {
204 .platform_data = &magician_gpio_keys_data,
206 .id = -1,
210 * LCD
213 static struct platform_device magician_lcd = {
214 .name = "magician-lcd",
215 .dev = {
216 .platform_data = NULL,
218 .id = -1,
222 * Backlight
225 static void magician_set_bl_intensity(int intensity)
227 if (intensity) {
228 PWM_CTRL0 = 1;
229 PWM_PERVAL0 = 0xc8;
230 if (intensity > 0xc7) {
231 PWM_PWDUTY0 = intensity - 0x48;
232 magician_egpio_enable(&magician_cpld, EGPIO_NR_MAGICIAN_BL_POWER2);
233 } else {
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);
239 } else {
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,
247 .limit_mask = 0x0b,
248 .max_intensity = 0xc7+0x48,
249 .set_bl_intensity = magician_set_bl_intensity,
252 static struct platform_device magician_bl = {
253 .name = "corgi-bl",
254 .dev = {
255 .platform_data = &magician_bl_machinfo,
257 .id = -1,
260 /* Touchscreen, the TSC2046 chipset is pin-compatible to ADS7846 */
262 static struct platform_device magician_ts = {
263 .name = "magician-ts",
264 .dev = {
265 .platform_data = NULL,
269 #if 0
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 = {
278 .x_max = 0xffff,
279 .y_max = 0xffff,
280 .x_plate_ohms = 180, /* GUESS */
281 .y_plate_ohms = 180, /* GUESS */
282 .vref_delay_usecs = 100,
283 .pressure_max = 255,
284 .debounce_max = 10,
285 .debounce_tol = 3,
286 .get_pendown_state = &magician_get_pendown_state,
289 struct pxa2xx_spi_chip tsc2046_chip_info = {
290 .tx_threshold = 1,
291 .rx_threshold = 2,
292 .timeout_microsecs = 64,
295 static struct spi_board_info magician_spi_board_info[] __initdata = {
296 [0] = {
297 .modalias = "ads7846",
298 .bus_num = 2,
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[] = {
307 [0] = {
308 .start = __PREG(SSCR0_P(2)),
309 .end = __PREG(SSCR0_P(2)) + 0x2c,
310 .flags = IORESOURCE_MEM,
312 [1] = {
313 .start = IRQ_SSP2,
314 .end = IRQ_SSP2,
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",
327 .id = 2,
328 .resource = pxa_spi_ssp2_resources,
329 .num_resources = ARRAY_SIZE(pxa_spi_ssp2_resources),
330 .dev = {stp
331 .platform_data = &pxa_ssp2_master_info,
334 #endif
337 * Magician LEDs
339 static struct platform_device magician_led = {
340 .name = "magician-led",
341 .id = -1,
345 * MMC/SD
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)
352 int err;
354 err = request_irq(IRQ_MAGICIAN_SD, magician_detect_int,
355 IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
356 "MMC card detect", data);
357 if (err) {
358 printk(KERN_ERR "magician_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
359 return -1;
362 return 0;
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);
371 else
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; */
378 return 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,
395 /* USB OHCI */
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);
405 return 0;
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 = {
414 &magician_pm,
415 &magician_gpio_keys,
416 &magician_cpld,
417 &magician_lcd, // needs the cpld to power on/off the lcd
418 &magician_bl,
419 &magician_ts,
420 &magician_led,
421 &magician_phone,
422 #if 0
423 &pxa_spi_ssp2,
424 #endif
427 static void __init magician_init(void)
430 /* BIG TODO */
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
439 // GPCR only here
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
456 #endif
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));
463 #if 0
464 spi_register_board_info(magician_spi_board_info,
465 ARRAY_SIZE(magician_spi_board_info));
466 #endif
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,
481 .timer = &pxa_timer,
482 .init_machine = magician_init,
483 MACHINE_END