diff options
author | Marek VaĊĦut <marek.vasut@gmail.com> | 2008-07-07 12:25:46 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-07-10 07:15:31 -0400 |
commit | b5e4ad57eeffef0ac274413f83be4ef903719ea4 (patch) | |
tree | 46f39439864a273809f8f603466c24d9095d3d65 /arch/arm | |
parent | f974a8ec96571535ee07880a023bcce0e3f2c76b (diff) |
[ARM] 5153/1: Add support for PalmTX handheld computer
PalmTX is PXA27x based device with wifi, bluetooth,
touchscreen, sdio slot, irda, keypad, nand flash,
pxa framebuffer, serial and usb gadget interface.
Supported by this patch is pxafb, touchscreen, irda,
keypad and sdio slot.
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-pxa/Kconfig | 14 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/palmtx.c | 342 |
3 files changed, 357 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index faa2c3f6c1af..2793076bd33a 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -199,6 +199,20 @@ config MACH_PCM027 | |||
199 | select IWMMXT | 199 | select IWMMXT |
200 | select PXA_SSP | 200 | select PXA_SSP |
201 | 201 | ||
202 | config ARCH_PXA_PALM | ||
203 | bool "PXA based Palm PDAs" | ||
204 | select HAVE_PWM | ||
205 | |||
206 | config MACH_PALMTX | ||
207 | bool "Palm T|X" | ||
208 | default y | ||
209 | depends on ARCH_PXA_PALM | ||
210 | select PXA27x | ||
211 | select IWMMXT | ||
212 | help | ||
213 | Say Y here if you intend to run this kernel on a Palm T|X | ||
214 | handheld computer. | ||
215 | |||
202 | config MACH_PCM990_BASEBOARD | 216 | config MACH_PCM990_BASEBOARD |
203 | bool "PHYTEC PCM-990 development board" | 217 | bool "PHYTEC PCM-990 development board" |
204 | select HAVE_PWM | 218 | select HAVE_PWM |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c4dfbe87fc4e..d7dc3a76e33c 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -37,6 +37,7 @@ obj-$(CONFIG_MACH_TOSA) += tosa.o | |||
37 | obj-$(CONFIG_MACH_EM_X270) += em-x270.o | 37 | obj-$(CONFIG_MACH_EM_X270) += em-x270.o |
38 | obj-$(CONFIG_MACH_MAGICIAN) += magician.o | 38 | obj-$(CONFIG_MACH_MAGICIAN) += magician.o |
39 | obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o | 39 | obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o |
40 | obj-$(CONFIG_MACH_PALMTX)+= palmtx.o | ||
40 | 41 | ||
41 | ifeq ($(CONFIG_MACH_ZYLONITE),y) | 42 | ifeq ($(CONFIG_MACH_ZYLONITE),y) |
42 | obj-y += zylonite.o | 43 | obj-y += zylonite.o |
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c new file mode 100644 index 000000000000..ae8973279c20 --- /dev/null +++ b/arch/arm/mach-pxa/palmtx.c | |||
@@ -0,0 +1,342 @@ | |||
1 | /* | ||
2 | * Hardware definitions for PalmTX | ||
3 | * | ||
4 | * Author: Marek Vasut <marek.vasut@gmail.com> | ||
5 | * | ||
6 | * Based on work of: | ||
7 | * Alex Osborne <ato@meshy.org> | ||
8 | * Cristiano P. <cristianop@users.sourceforge.net> | ||
9 | * Jan Herman <2hp@seznam.cz> | ||
10 | * Michal Hrusecky | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | * (find more info at www.hackndev.com) | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/irq.h> | ||
23 | #include <linux/gpio_keys.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/pwm_backlight.h> | ||
26 | #include <linux/gpio.h> | ||
27 | |||
28 | #include <asm/mach-types.h> | ||
29 | #include <asm/mach/arch.h> | ||
30 | #include <asm/mach/map.h> | ||
31 | |||
32 | #include <asm/arch/audio.h> | ||
33 | #include <asm/arch/palmtx.h> | ||
34 | #include <asm/arch/mmc.h> | ||
35 | #include <asm/arch/pxafb.h> | ||
36 | #include <asm/arch/pxa-regs.h> | ||
37 | #include <asm/arch/mfp-pxa27x.h> | ||
38 | #include <asm/arch/irda.h> | ||
39 | #include <asm/arch/pxa27x_keypad.h> | ||
40 | #include <asm/arch/udc.h> | ||
41 | |||
42 | #include "generic.h" | ||
43 | #include "devices.h" | ||
44 | |||
45 | /****************************************************************************** | ||
46 | * Pin configuration | ||
47 | ******************************************************************************/ | ||
48 | static unsigned long palmtx_pin_config[] __initdata = { | ||
49 | /* MMC */ | ||
50 | GPIO32_MMC_CLK, | ||
51 | GPIO92_MMC_DAT_0, | ||
52 | GPIO109_MMC_DAT_1, | ||
53 | GPIO110_MMC_DAT_2, | ||
54 | GPIO111_MMC_DAT_3, | ||
55 | GPIO112_MMC_CMD, | ||
56 | |||
57 | /* AC97 */ | ||
58 | GPIO28_AC97_BITCLK, | ||
59 | GPIO29_AC97_SDATA_IN_0, | ||
60 | GPIO30_AC97_SDATA_OUT, | ||
61 | GPIO31_AC97_SYNC, | ||
62 | |||
63 | /* IrDA */ | ||
64 | GPIO46_FICP_RXD, | ||
65 | GPIO47_FICP_TXD, | ||
66 | |||
67 | /* PWM */ | ||
68 | GPIO16_PWM0_OUT, | ||
69 | |||
70 | /* USB */ | ||
71 | GPIO13_GPIO, | ||
72 | }; | ||
73 | |||
74 | /****************************************************************************** | ||
75 | * SD/MMC card controller | ||
76 | ******************************************************************************/ | ||
77 | static int palmtx_mci_init(struct device *dev, irq_handler_t palmtx_detect_int, | ||
78 | void *data) | ||
79 | { | ||
80 | int err = 0; | ||
81 | |||
82 | /* Setup an interrupt for detecting card insert/remove events */ | ||
83 | err = request_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, palmtx_detect_int, | ||
84 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM | | ||
85 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | ||
86 | "SD/MMC card detect", data); | ||
87 | if (err) { | ||
88 | printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n", | ||
89 | __func__); | ||
90 | return err; | ||
91 | } | ||
92 | |||
93 | err = gpio_request(GPIO_NR_PALMTX_SD_POWER, "SD_POWER"); | ||
94 | if (err) | ||
95 | goto pwr_err; | ||
96 | |||
97 | err = gpio_request(GPIO_NR_PALMTX_SD_READONLY, "SD_READONLY"); | ||
98 | if (err) | ||
99 | goto ro_err; | ||
100 | |||
101 | printk(KERN_DEBUG "%s: irq registered\n", __func__); | ||
102 | |||
103 | return 0; | ||
104 | |||
105 | ro_err: | ||
106 | gpio_free(GPIO_NR_PALMTX_SD_POWER); | ||
107 | pwr_err: | ||
108 | free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data); | ||
109 | return err; | ||
110 | } | ||
111 | |||
112 | static void palmtx_mci_exit(struct device *dev, void *data) | ||
113 | { | ||
114 | gpio_free(GPIO_NR_PALMTX_SD_READONLY); | ||
115 | gpio_free(GPIO_NR_PALMTX_SD_POWER); | ||
116 | free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data); | ||
117 | } | ||
118 | |||
119 | static void palmtx_mci_power(struct device *dev, unsigned int vdd) | ||
120 | { | ||
121 | struct pxamci_platform_data *p_d = dev->platform_data; | ||
122 | gpio_set_value(GPIO_NR_PALMTX_SD_POWER, p_d->ocr_mask & (1 << vdd)); | ||
123 | } | ||
124 | |||
125 | static int palmtx_mci_get_ro(struct device *dev) | ||
126 | { | ||
127 | return gpio_get_value(GPIO_NR_PALMTX_SD_READONLY); | ||
128 | } | ||
129 | |||
130 | static struct pxamci_platform_data palmtx_mci_platform_data = { | ||
131 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | ||
132 | .setpower = palmtx_mci_power, | ||
133 | .get_ro = palmtx_mci_get_ro, | ||
134 | .init = palmtx_mci_init, | ||
135 | .exit = palmtx_mci_exit, | ||
136 | }; | ||
137 | |||
138 | /****************************************************************************** | ||
139 | * GPIO keyboard | ||
140 | ******************************************************************************/ | ||
141 | static unsigned int palmtx_matrix_keys[] = { | ||
142 | KEY(0, 0, KEY_POWER), | ||
143 | KEY(0, 1, KEY_F1), | ||
144 | KEY(0, 2, KEY_ENTER), | ||
145 | |||
146 | KEY(1, 0, KEY_F2), | ||
147 | KEY(1, 1, KEY_F3), | ||
148 | KEY(1, 2, KEY_F4), | ||
149 | |||
150 | KEY(2, 0, KEY_UP), | ||
151 | KEY(2, 2, KEY_DOWN), | ||
152 | |||
153 | KEY(3, 0, KEY_RIGHT), | ||
154 | KEY(3, 2, KEY_LEFT), | ||
155 | |||
156 | }; | ||
157 | |||
158 | static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = { | ||
159 | .matrix_key_rows = 4, | ||
160 | .matrix_key_cols = 3, | ||
161 | .matrix_key_map = palmtx_matrix_keys, | ||
162 | .matrix_key_map_size = ARRAY_SIZE(palmtx_matrix_keys), | ||
163 | |||
164 | .debounce_interval = 30, | ||
165 | }; | ||
166 | |||
167 | /****************************************************************************** | ||
168 | * GPIO keys | ||
169 | ******************************************************************************/ | ||
170 | static struct gpio_keys_button palmtx_pxa_buttons[] = { | ||
171 | {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" }, | ||
172 | }; | ||
173 | |||
174 | static struct gpio_keys_platform_data palmtx_pxa_keys_data = { | ||
175 | .buttons = palmtx_pxa_buttons, | ||
176 | .nbuttons = ARRAY_SIZE(palmtx_pxa_buttons), | ||
177 | }; | ||
178 | |||
179 | static struct platform_device palmtx_pxa_keys = { | ||
180 | .name = "gpio-keys", | ||
181 | .id = -1, | ||
182 | .dev = { | ||
183 | .platform_data = &palmtx_pxa_keys_data, | ||
184 | }, | ||
185 | }; | ||
186 | |||
187 | /****************************************************************************** | ||
188 | * Backlight | ||
189 | ******************************************************************************/ | ||
190 | static int palmtx_backlight_init(struct device *dev) | ||
191 | { | ||
192 | int ret; | ||
193 | |||
194 | ret = gpio_request(GPIO_NR_PALMTX_BL_POWER, "BL POWER"); | ||
195 | if (ret) | ||
196 | goto err; | ||
197 | ret = gpio_request(GPIO_NR_PALMTX_LCD_POWER, "LCD POWER"); | ||
198 | if (ret) | ||
199 | goto err2; | ||
200 | |||
201 | return 0; | ||
202 | err2: | ||
203 | gpio_free(GPIO_NR_PALMTX_BL_POWER); | ||
204 | err: | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int palmtx_backlight_notify(int brightness) | ||
209 | { | ||
210 | gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness); | ||
211 | gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness); | ||
212 | return brightness; | ||
213 | } | ||
214 | |||
215 | static void palmtx_backlight_exit(struct device *dev) | ||
216 | { | ||
217 | gpio_free(GPIO_NR_PALMTX_BL_POWER); | ||
218 | gpio_free(GPIO_NR_PALMTX_LCD_POWER); | ||
219 | } | ||
220 | |||
221 | static struct platform_pwm_backlight_data palmtx_backlight_data = { | ||
222 | .pwm_id = 0, | ||
223 | .max_brightness = PALMTX_MAX_INTENSITY, | ||
224 | .dft_brightness = PALMTX_MAX_INTENSITY, | ||
225 | .pwm_period_ns = PALMTX_PERIOD_NS, | ||
226 | .init = palmtx_backlight_init, | ||
227 | .notify = palmtx_backlight_notify, | ||
228 | .exit = palmtx_backlight_exit, | ||
229 | }; | ||
230 | |||
231 | static struct platform_device palmtx_backlight = { | ||
232 | .name = "pwm-backlight", | ||
233 | .dev = { | ||
234 | .parent = &pxa27x_device_pwm0.dev, | ||
235 | .platform_data = &palmtx_backlight_data, | ||
236 | }, | ||
237 | }; | ||
238 | |||
239 | /****************************************************************************** | ||
240 | * IrDA | ||
241 | ******************************************************************************/ | ||
242 | static void palmtx_irda_transceiver_mode(struct device *dev, int mode) | ||
243 | { | ||
244 | gpio_set_value(GPIO_NR_PALMTX_IR_DISABLE, mode & IR_OFF); | ||
245 | pxa2xx_transceiver_mode(dev, mode); | ||
246 | } | ||
247 | |||
248 | static struct pxaficp_platform_data palmtx_ficp_platform_data = { | ||
249 | .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, | ||
250 | .transceiver_mode = palmtx_irda_transceiver_mode, | ||
251 | }; | ||
252 | |||
253 | /****************************************************************************** | ||
254 | * UDC | ||
255 | ******************************************************************************/ | ||
256 | static void palmtx_udc_command(int cmd) | ||
257 | { | ||
258 | gpio_set_value(GPIO_NR_PALMTX_USB_POWER, !cmd); | ||
259 | udelay(50); | ||
260 | gpio_set_value(GPIO_NR_PALMTX_USB_PULLUP, !cmd); | ||
261 | } | ||
262 | |||
263 | static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = { | ||
264 | .gpio_vbus = GPIO_NR_PALMTX_USB_DETECT_N, | ||
265 | .gpio_vbus_inverted = 1, | ||
266 | .udc_command = palmtx_udc_command, | ||
267 | }; | ||
268 | |||
269 | /****************************************************************************** | ||
270 | * Framebuffer | ||
271 | ******************************************************************************/ | ||
272 | static struct pxafb_mode_info palmtx_lcd_modes[] = { | ||
273 | { | ||
274 | .pixclock = 57692, | ||
275 | .xres = 320, | ||
276 | .yres = 480, | ||
277 | .bpp = 16, | ||
278 | |||
279 | .left_margin = 32, | ||
280 | .right_margin = 1, | ||
281 | .upper_margin = 7, | ||
282 | .lower_margin = 1, | ||
283 | |||
284 | .hsync_len = 4, | ||
285 | .vsync_len = 1, | ||
286 | }, | ||
287 | }; | ||
288 | |||
289 | static struct pxafb_mach_info palmtx_lcd_screen = { | ||
290 | .modes = palmtx_lcd_modes, | ||
291 | .num_modes = ARRAY_SIZE(palmtx_lcd_modes), | ||
292 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, | ||
293 | }; | ||
294 | |||
295 | /****************************************************************************** | ||
296 | * Machine init | ||
297 | ******************************************************************************/ | ||
298 | static struct platform_device *devices[] __initdata = { | ||
299 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
300 | &palmtx_pxa_keys, | ||
301 | #endif | ||
302 | &palmtx_backlight, | ||
303 | }; | ||
304 | |||
305 | static struct map_desc palmtx_io_desc[] __initdata = { | ||
306 | { | ||
307 | .virtual = PALMTX_PCMCIA_VIRT, | ||
308 | .pfn = __phys_to_pfn(PALMTX_PCMCIA_PHYS), | ||
309 | .length = PALMTX_PCMCIA_SIZE, | ||
310 | .type = MT_DEVICE | ||
311 | }, | ||
312 | }; | ||
313 | |||
314 | static void __init palmtx_map_io(void) | ||
315 | { | ||
316 | pxa_map_io(); | ||
317 | iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc)); | ||
318 | } | ||
319 | |||
320 | static void __init palmtx_init(void) | ||
321 | { | ||
322 | pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config)); | ||
323 | |||
324 | set_pxa_fb_info(&palmtx_lcd_screen); | ||
325 | pxa_set_mci_info(&palmtx_mci_platform_data); | ||
326 | pxa_set_udc_info(&palmtx_udc_info); | ||
327 | pxa_set_ac97_info(NULL); | ||
328 | pxa_set_ficp_info(&palmtx_ficp_platform_data); | ||
329 | pxa_set_keypad_info(&palmtx_keypad_platform_data); | ||
330 | |||
331 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
332 | } | ||
333 | |||
334 | MACHINE_START(PALMTX, "Palm T|X") | ||
335 | .phys_io = PALMTX_PHYS_IO_START, | ||
336 | .io_pg_offst = io_p2v(0x40000000), | ||
337 | .boot_params = 0xa0000100, | ||
338 | .map_io = palmtx_map_io, | ||
339 | .init_irq = pxa27x_init_irq, | ||
340 | .timer = &pxa_timer, | ||
341 | .init_machine = palmtx_init | ||
342 | MACHINE_END | ||