• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Hardware definitions for Palm Treo smartphones
4  *
5  * currently supported:
6  *     Palm Treo 680 (GSM)
7  *     Palm Centro 685 (GSM)
8  *
9  * Author:     Tomas Cech <sleep_walker@suse.cz>
10  *
11  * (find more info at www.hackndev.com)
12  */
13 
14 #include <linux/platform_device.h>
15 #include <linux/delay.h>
16 #include <linux/irq.h>
17 #include <linux/gpio_keys.h>
18 #include <linux/input.h>
19 #include <linux/memblock.h>
20 #include <linux/pda_power.h>
21 #include <linux/pwm_backlight.h>
22 #include <linux/gpio.h>
23 #include <linux/power_supply.h>
24 #include <linux/w1-gpio.h>
25 
26 #include <asm/mach-types.h>
27 #include <asm/mach/arch.h>
28 #include <asm/mach/map.h>
29 
30 #include "pxa27x.h"
31 #include "pxa27x-udc.h"
32 #include <mach/audio.h>
33 #include "palmtreo.h"
34 #include <linux/platform_data/mmc-pxamci.h>
35 #include <linux/platform_data/video-pxafb.h>
36 #include <linux/platform_data/irda-pxaficp.h>
37 #include <linux/platform_data/keypad-pxa27x.h>
38 #include "udc.h"
39 #include <linux/platform_data/usb-ohci-pxa27x.h>
40 #include <mach/pxa2xx-regs.h>
41 #include <linux/platform_data/asoc-palm27x.h>
42 #include <linux/platform_data/media/camera-pxa.h>
43 #include "palm27x.h"
44 
45 #include <sound/pxa2xx-lib.h>
46 
47 #include "generic.h"
48 #include "devices.h"
49 
50 /******************************************************************************
51  * Pin configuration
52  ******************************************************************************/
53 static unsigned long treo_pin_config[] __initdata = {
54 	/* MMC */
55 	GPIO32_MMC_CLK,
56 	GPIO92_MMC_DAT_0,
57 	GPIO109_MMC_DAT_1,
58 	GPIO110_MMC_DAT_2,
59 	GPIO111_MMC_DAT_3,
60 	GPIO112_MMC_CMD,
61 	GPIO113_GPIO,				/* SD detect */
62 
63 	/* AC97 */
64 	GPIO28_AC97_BITCLK,
65 	GPIO29_AC97_SDATA_IN_0,
66 	GPIO30_AC97_SDATA_OUT,
67 	GPIO31_AC97_SYNC,
68 	GPIO89_AC97_SYSCLK,
69 	GPIO95_AC97_nRESET,
70 
71 	/* IrDA */
72 	GPIO46_FICP_RXD,
73 	GPIO47_FICP_TXD,
74 
75 	/* PWM */
76 	GPIO16_PWM0_OUT,
77 
78 	/* USB */
79 	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,	/* usb detect */
80 
81 	/* MATRIX KEYPAD */
82 	GPIO101_KP_MKIN_1,
83 	GPIO102_KP_MKIN_2,
84 	GPIO97_KP_MKIN_3,
85 	GPIO98_KP_MKIN_4,
86 	GPIO91_KP_MKIN_6,
87 	GPIO13_KP_MKIN_7,
88 	GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH,
89 	GPIO104_KP_MKOUT_1,
90 	GPIO105_KP_MKOUT_2,
91 	GPIO106_KP_MKOUT_3,
92 	GPIO107_KP_MKOUT_4,
93 	GPIO108_KP_MKOUT_5,
94 	GPIO96_KP_MKOUT_6,
95 	GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,	/* Hotsync button */
96 
97 	/* Quick Capture Interface */
98 	GPIO84_CIF_FV,
99 	GPIO85_CIF_LV,
100 	GPIO53_CIF_MCLK,
101 	GPIO54_CIF_PCLK,
102 	GPIO81_CIF_DD_0,
103 	GPIO55_CIF_DD_1,
104 	GPIO51_CIF_DD_2,
105 	GPIO50_CIF_DD_3,
106 	GPIO52_CIF_DD_4,
107 	GPIO48_CIF_DD_5,
108 	GPIO17_CIF_DD_6,
109 	GPIO12_CIF_DD_7,
110 
111 	/* I2C */
112 	GPIO117_I2C_SCL,
113 	GPIO118_I2C_SDA,
114 
115 	/* GSM */
116 	GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH,	/* GSM host wake up */
117 	GPIO34_FFUART_RXD,
118 	GPIO35_FFUART_CTS,
119 	GPIO39_FFUART_TXD,
120 	GPIO41_FFUART_RTS,
121 
122 	/* MISC. */
123 	GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,	/* external power detect */
124 	GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,	/* silent switch */
125 	GPIO116_GPIO,				/* headphone detect */
126 	GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,	/* bluetooth host wake up */
127 };
128 
129 #ifdef CONFIG_MACH_TREO680
130 static unsigned long treo680_pin_config[] __initdata = {
131 	GPIO33_GPIO,    /* SD read only */
132 
133 	/* MATRIX KEYPAD - different wake up source */
134 	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
135 	GPIO99_KP_MKIN_5,
136 
137 	/* LCD... L_BIAS alt fn not configured on Treo680; is GPIO instead */
138 	GPIOxx_LCD_16BPP,
139 	GPIO74_LCD_FCLK,
140 	GPIO75_LCD_LCLK,
141 	GPIO76_LCD_PCLK,
142 };
143 #endif /* CONFIG_MACH_TREO680 */
144 
145 #ifdef CONFIG_MACH_CENTRO
146 static unsigned long centro685_pin_config[] __initdata = {
147 	/* Bluetooth attached to BT UART*/
148 	MFP_CFG_OUT(GPIO80, AF0, DRIVE_LOW),    /* power: LOW = off */
149 	GPIO42_BTUART_RXD,
150 	GPIO43_BTUART_TXD,
151 	GPIO44_BTUART_CTS,
152 	GPIO45_BTUART_RTS,
153 
154 	/* MATRIX KEYPAD - different wake up source */
155 	GPIO100_KP_MKIN_0,
156 	GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
157 
158 	/* LCD */
159 	GPIOxx_LCD_TFT_16BPP,
160 };
161 #endif /* CONFIG_MACH_CENTRO */
162 
163 /******************************************************************************
164  * GPIO keyboard
165  ******************************************************************************/
166 #if IS_ENABLED(CONFIG_KEYBOARD_PXA27x)
167 static const unsigned int treo680_matrix_keys[] = {
168 	KEY(0, 0, KEY_F8),		/* Red/Off/Power */
169 	KEY(0, 1, KEY_LEFT),
170 	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
171 	KEY(0, 3, KEY_L),
172 	KEY(0, 4, KEY_A),
173 	KEY(0, 5, KEY_Q),
174 	KEY(0, 6, KEY_P),
175 
176 	KEY(1, 0, KEY_RIGHTCTRL),	/* Menu */
177 	KEY(1, 1, KEY_RIGHT),
178 	KEY(1, 2, KEY_LEFTSHIFT),	/* Left shift */
179 	KEY(1, 3, KEY_Z),
180 	KEY(1, 4, KEY_S),
181 	KEY(1, 5, KEY_W),
182 
183 	KEY(2, 0, KEY_F1),		/* Phone */
184 	KEY(2, 1, KEY_UP),
185 	KEY(2, 2, KEY_0),
186 	KEY(2, 3, KEY_X),
187 	KEY(2, 4, KEY_D),
188 	KEY(2, 5, KEY_E),
189 
190 	KEY(3, 0, KEY_F10),		/* Calendar */
191 	KEY(3, 1, KEY_DOWN),
192 	KEY(3, 2, KEY_SPACE),
193 	KEY(3, 3, KEY_C),
194 	KEY(3, 4, KEY_F),
195 	KEY(3, 5, KEY_R),
196 
197 	KEY(4, 0, KEY_F12),		/* Mail */
198 	KEY(4, 1, KEY_KPENTER),
199 	KEY(4, 2, KEY_RIGHTALT),	/* Alt */
200 	KEY(4, 3, KEY_V),
201 	KEY(4, 4, KEY_G),
202 	KEY(4, 5, KEY_T),
203 
204 	KEY(5, 0, KEY_F9),		/* Home */
205 	KEY(5, 1, KEY_PAGEUP),		/* Side up */
206 	KEY(5, 2, KEY_DOT),
207 	KEY(5, 3, KEY_B),
208 	KEY(5, 4, KEY_H),
209 	KEY(5, 5, KEY_Y),
210 
211 	KEY(6, 0, KEY_TAB),		/* Side Activate */
212 	KEY(6, 1, KEY_PAGEDOWN),	/* Side down */
213 	KEY(6, 2, KEY_ENTER),
214 	KEY(6, 3, KEY_N),
215 	KEY(6, 4, KEY_J),
216 	KEY(6, 5, KEY_U),
217 
218 	KEY(7, 0, KEY_F6),		/* Green/Call */
219 	KEY(7, 1, KEY_O),
220 	KEY(7, 2, KEY_BACKSPACE),
221 	KEY(7, 3, KEY_M),
222 	KEY(7, 4, KEY_K),
223 	KEY(7, 5, KEY_I),
224 };
225 
226 static const unsigned int centro_matrix_keys[] = {
227 	KEY(0, 0, KEY_F9),		/* Home */
228 	KEY(0, 1, KEY_LEFT),
229 	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
230 	KEY(0, 3, KEY_L),
231 	KEY(0, 4, KEY_A),
232 	KEY(0, 5, KEY_Q),
233 	KEY(0, 6, KEY_P),
234 
235 	KEY(1, 0, KEY_RIGHTCTRL),	/* Menu */
236 	KEY(1, 1, KEY_RIGHT),
237 	KEY(1, 2, KEY_LEFTSHIFT),	/* Left shift */
238 	KEY(1, 3, KEY_Z),
239 	KEY(1, 4, KEY_S),
240 	KEY(1, 5, KEY_W),
241 
242 	KEY(2, 0, KEY_F1),		/* Phone */
243 	KEY(2, 1, KEY_UP),
244 	KEY(2, 2, KEY_0),
245 	KEY(2, 3, KEY_X),
246 	KEY(2, 4, KEY_D),
247 	KEY(2, 5, KEY_E),
248 
249 	KEY(3, 0, KEY_F10),		/* Calendar */
250 	KEY(3, 1, KEY_DOWN),
251 	KEY(3, 2, KEY_SPACE),
252 	KEY(3, 3, KEY_C),
253 	KEY(3, 4, KEY_F),
254 	KEY(3, 5, KEY_R),
255 
256 	KEY(4, 0, KEY_F12),		/* Mail */
257 	KEY(4, 1, KEY_KPENTER),
258 	KEY(4, 2, KEY_RIGHTALT),	/* Alt */
259 	KEY(4, 3, KEY_V),
260 	KEY(4, 4, KEY_G),
261 	KEY(4, 5, KEY_T),
262 
263 	KEY(5, 0, KEY_F8),		/* Red/Off/Power */
264 	KEY(5, 1, KEY_PAGEUP),		/* Side up */
265 	KEY(5, 2, KEY_DOT),
266 	KEY(5, 3, KEY_B),
267 	KEY(5, 4, KEY_H),
268 	KEY(5, 5, KEY_Y),
269 
270 	KEY(6, 0, KEY_TAB),		/* Side Activate */
271 	KEY(6, 1, KEY_PAGEDOWN),	/* Side down */
272 	KEY(6, 2, KEY_ENTER),
273 	KEY(6, 3, KEY_N),
274 	KEY(6, 4, KEY_J),
275 	KEY(6, 5, KEY_U),
276 
277 	KEY(7, 0, KEY_F6),		/* Green/Call */
278 	KEY(7, 1, KEY_O),
279 	KEY(7, 2, KEY_BACKSPACE),
280 	KEY(7, 3, KEY_M),
281 	KEY(7, 4, KEY_K),
282 	KEY(7, 5, KEY_I),
283 };
284 
285 static struct matrix_keymap_data treo680_matrix_keymap_data = {
286 	.keymap			= treo680_matrix_keys,
287 	.keymap_size		= ARRAY_SIZE(treo680_matrix_keys),
288 };
289 
290 static struct matrix_keymap_data centro_matrix_keymap_data = {
291 	.keymap			= centro_matrix_keys,
292 	.keymap_size		= ARRAY_SIZE(centro_matrix_keys),
293 };
294 
295 static struct pxa27x_keypad_platform_data treo680_keypad_pdata = {
296 	.matrix_key_rows	= 8,
297 	.matrix_key_cols	= 7,
298 	.matrix_keymap_data	= &treo680_matrix_keymap_data,
299 	.direct_key_map		= { KEY_CONNECT },
300 	.direct_key_num		= 1,
301 
302 	.debounce_interval	= 30,
303 };
304 
palmtreo_kpc_init(void)305 static void __init palmtreo_kpc_init(void)
306 {
307 	static struct pxa27x_keypad_platform_data *data = &treo680_keypad_pdata;
308 
309 	if (machine_is_centro())
310 		data->matrix_keymap_data = &centro_matrix_keymap_data;
311 
312 	pxa_set_keypad_info(&treo680_keypad_pdata);
313 }
314 #else
palmtreo_kpc_init(void)315 static inline void palmtreo_kpc_init(void) {}
316 #endif
317 
318 /******************************************************************************
319  * USB host
320  ******************************************************************************/
321 #if IS_ENABLED(CONFIG_USB_OHCI_HCD)
322 static struct pxaohci_platform_data treo680_ohci_info = {
323 	.port_mode    = PMM_PERPORT_MODE,
324 	.flags        = ENABLE_PORT1 | ENABLE_PORT3,
325 	.power_budget = 0,
326 };
327 
palmtreo_uhc_init(void)328 static void __init palmtreo_uhc_init(void)
329 {
330 	if (machine_is_treo680())
331 		pxa_set_ohci_info(&treo680_ohci_info);
332 }
333 #else
palmtreo_uhc_init(void)334 static inline void palmtreo_uhc_init(void) {}
335 #endif
336 
337 /******************************************************************************
338  * Vibra and LEDs
339  ******************************************************************************/
340 static struct gpio_led treo680_gpio_leds[] = {
341 	{
342 		.name			= "treo680:vibra:vibra",
343 		.default_trigger	= "none",
344 		.gpio			= GPIO_NR_TREO680_VIBRATE_EN,
345 	},
346 	{
347 		.name			= "treo680:green:led",
348 		.default_trigger	= "mmc0",
349 		.gpio			= GPIO_NR_TREO_GREEN_LED,
350 	},
351 	{
352 		.name			= "treo680:white:keybbl",
353 		.default_trigger	= "none",
354 		.gpio			= GPIO_NR_TREO680_KEYB_BL,
355 	},
356 };
357 
358 static struct gpio_led_platform_data treo680_gpio_led_info = {
359 	.leds		= treo680_gpio_leds,
360 	.num_leds	= ARRAY_SIZE(treo680_gpio_leds),
361 };
362 
363 static struct gpio_led centro_gpio_leds[] = {
364 	{
365 		.name			= "centro:vibra:vibra",
366 		.default_trigger	= "none",
367 		.gpio			= GPIO_NR_CENTRO_VIBRATE_EN,
368 	},
369 	{
370 		.name			= "centro:green:led",
371 		.default_trigger	= "mmc0",
372 		.gpio			= GPIO_NR_TREO_GREEN_LED,
373 	},
374 	{
375 		.name			= "centro:white:keybbl",
376 		.default_trigger	= "none",
377 		.active_low		= 1,
378 		.gpio			= GPIO_NR_CENTRO_KEYB_BL,
379 	},
380 };
381 
382 static struct gpio_led_platform_data centro_gpio_led_info = {
383 	.leds		= centro_gpio_leds,
384 	.num_leds	= ARRAY_SIZE(centro_gpio_leds),
385 };
386 
387 static struct platform_device palmtreo_leds = {
388 	.name   = "leds-gpio",
389 	.id     = -1,
390 };
391 
palmtreo_leds_init(void)392 static void __init palmtreo_leds_init(void)
393 {
394 	if (machine_is_centro())
395 		palmtreo_leds.dev.platform_data = &centro_gpio_led_info;
396 	else if (machine_is_treo680())
397 		palmtreo_leds.dev.platform_data = &treo680_gpio_led_info;
398 
399 	platform_device_register(&palmtreo_leds);
400 }
401 
402 /******************************************************************************
403  * Machine init
404  ******************************************************************************/
treo_reserve(void)405 static void __init treo_reserve(void)
406 {
407 	memblock_reserve(0xa0000000, 0x1000);
408 	memblock_reserve(0xa2000000, 0x1000);
409 }
410 
palmphone_common_init(void)411 static void __init palmphone_common_init(void)
412 {
413 	pxa2xx_mfp_config(ARRAY_AND_SIZE(treo_pin_config));
414 	pxa_set_ffuart_info(NULL);
415 	pxa_set_btuart_info(NULL);
416 	pxa_set_stuart_info(NULL);
417 	palm27x_pm_init(TREO_STR_BASE);
418 	palm27x_lcd_init(GPIO_NR_TREO_BL_POWER, &palm_320x320_new_lcd_mode);
419 	palm27x_udc_init(GPIO_NR_TREO_USB_DETECT, GPIO_NR_TREO_USB_PULLUP, 1);
420 	palm27x_irda_init(GPIO_NR_TREO_IR_EN);
421 	palm27x_ac97_init(-1, -1, -1, 95);
422 	palm27x_pwm_init(GPIO_NR_TREO_BL_POWER, -1);
423 	palm27x_power_init(GPIO_NR_TREO_POWER_DETECT, -1);
424 	palm27x_pmic_init();
425 	palmtreo_kpc_init();
426 	palmtreo_uhc_init();
427 	palmtreo_leds_init();
428 }
429 
430 #ifdef CONFIG_MACH_TREO680
treo680_gpio_init(void)431 void __init treo680_gpio_init(void)
432 {
433 	unsigned int gpio;
434 
435 	/* drive all three lcd gpios high initially */
436 	const unsigned long lcd_flags = GPIOF_INIT_HIGH | GPIOF_DIR_OUT;
437 
438 	/*
439 	 * LCD GPIO initialization...
440 	 */
441 
442 	/*
443 	 * This is likely the power to the lcd.  Toggling it low/high appears to
444 	 * turn the lcd off/on.  Can be toggled after lcd is initialized without
445 	 * any apparent adverse effects to the lcd operation.  Note that this
446 	 * gpio line is used by the lcd controller as the L_BIAS signal, but
447 	 * treo680 configures it as gpio.
448 	 */
449 	gpio = GPIO_NR_TREO680_LCD_POWER;
450 	if (gpio_request_one(gpio, lcd_flags, "LCD power") < 0)
451 		goto fail;
452 
453 	/*
454 	 * These two are called "enables", for lack of a better understanding.
455 	 * If either of these are toggled after the lcd is initialized, the
456 	 * image becomes degraded.  N.B. The IPL shipped with the treo
457 	 * configures GPIO_NR_TREO680_LCD_EN_N as output and drives it high.  If
458 	 * the IPL is ever reprogrammed, this initialization may be need to be
459 	 * revisited.
460 	 */
461 	gpio = GPIO_NR_TREO680_LCD_EN;
462 	if (gpio_request_one(gpio, lcd_flags, "LCD enable") < 0)
463 		goto fail;
464 	gpio = GPIO_NR_TREO680_LCD_EN_N;
465 	if (gpio_request_one(gpio, lcd_flags, "LCD enable_n") < 0)
466 		goto fail;
467 
468 	/* driving this low turns LCD on */
469 	gpio_set_value(GPIO_NR_TREO680_LCD_EN_N, 0);
470 
471 	return;
472  fail:
473 	pr_err("gpio %d initialization failed\n", gpio);
474 	gpio_free(GPIO_NR_TREO680_LCD_POWER);
475 	gpio_free(GPIO_NR_TREO680_LCD_EN);
476 	gpio_free(GPIO_NR_TREO680_LCD_EN_N);
477 }
478 
479 static struct gpiod_lookup_table treo680_mci_gpio_table = {
480 	.dev_id = "pxa2xx-mci.0",
481 	.table = {
482 		GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO_SD_DETECT_N,
483 			    "cd", GPIO_ACTIVE_LOW),
484 		GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO680_SD_READONLY,
485 			    "wp", GPIO_ACTIVE_LOW),
486 		GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO680_SD_POWER,
487 			    "power", GPIO_ACTIVE_HIGH),
488 		{ },
489 	},
490 };
491 
treo680_init(void)492 static void __init treo680_init(void)
493 {
494 	pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
495 	palmphone_common_init();
496 	treo680_gpio_init();
497 	palm27x_mmc_init(&treo680_mci_gpio_table);
498 }
499 #endif
500 
501 #ifdef CONFIG_MACH_CENTRO
502 
503 static struct gpiod_lookup_table centro685_mci_gpio_table = {
504 	.dev_id = "pxa2xx-mci.0",
505 	.table = {
506 		GPIO_LOOKUP("gpio-pxa", GPIO_NR_TREO_SD_DETECT_N,
507 			    "cd", GPIO_ACTIVE_LOW),
508 		GPIO_LOOKUP("gpio-pxa", GPIO_NR_CENTRO_SD_POWER,
509 			    "power", GPIO_ACTIVE_LOW),
510 		{ },
511 	},
512 };
513 
centro_init(void)514 static void __init centro_init(void)
515 {
516 	pxa2xx_mfp_config(ARRAY_AND_SIZE(centro685_pin_config));
517 	palmphone_common_init();
518 	palm27x_mmc_init(&centro685_mci_gpio_table);
519 }
520 #endif
521 
522 #ifdef CONFIG_MACH_TREO680
523 MACHINE_START(TREO680, "Palm Treo 680")
524 	.atag_offset    = 0x100,
525 	.map_io         = pxa27x_map_io,
526 	.reserve	= treo_reserve,
527 	.nr_irqs	= PXA_NR_IRQS,
528 	.init_irq       = pxa27x_init_irq,
529 	.handle_irq       = pxa27x_handle_irq,
530 	.init_time	= pxa_timer_init,
531 	.init_machine   = treo680_init,
532 	.restart	= pxa_restart,
533 MACHINE_END
534 #endif
535 
536 #ifdef CONFIG_MACH_CENTRO
537 MACHINE_START(CENTRO, "Palm Centro 685")
538 	.atag_offset    = 0x100,
539 	.map_io         = pxa27x_map_io,
540 	.reserve	= treo_reserve,
541 	.nr_irqs	= PXA_NR_IRQS,
542 	.init_irq       = pxa27x_init_irq,
543 	.handle_irq       = pxa27x_handle_irq,
544 	.init_time	= pxa_timer_init,
545 	.init_machine	= centro_init,
546 	.restart	= pxa_restart,
547 MACHINE_END
548 #endif
549