[ARM] 4948/1: magician: use htc-egpio to drive the GPIO/IRQ expander CPLD
[linux-2.6] / arch / arm / mach-pxa / magician.c
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/gpio_keys.h>
20 #include <linux/input.h>
21 #include <linux/mfd/htc-egpio.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/map.h>
24 #include <linux/mtd/physmap.h>
25
26 #include <asm/gpio.h>
27 #include <asm/hardware.h>
28 #include <asm/mach-types.h>
29 #include <asm/mach/arch.h>
30 #include <asm/arch/magician.h>
31 #include <asm/arch/pxa-regs.h>
32 #include <asm/arch/pxafb.h>
33 #include <asm/arch/i2c.h>
34 #include <asm/arch/irda.h>
35 #include <asm/arch/ohci.h>
36
37 #include "generic.h"
38
39 /*
40  * IRDA
41  */
42
43 static void magician_irda_transceiver_mode(struct device *dev, int mode)
44 {
45         gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF);
46 }
47
48 static struct pxaficp_platform_data magician_ficp_info = {
49         .transceiver_cap  = IR_SIRMODE | IR_OFF,
50         .transceiver_mode = magician_irda_transceiver_mode,
51 };
52
53 /*
54  * GPIO Keys
55  */
56
57 static struct gpio_keys_button magician_button_table[] = {
58         {KEY_POWER,      GPIO0_MAGICIAN_KEY_POWER,      0, "Power button"},
59         {KEY_ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    0, "Hangup button"},
60         {KEY_F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  0, "Contacts button"},
61         {KEY_CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  0, "Calendar button"},
62         {KEY_CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    0, "Camera button"},
63         {KEY_UP,         GPIO93_MAGICIAN_KEY_UP,        0, "Up button"},
64         {KEY_DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      0, "Down button"},
65         {KEY_LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      0, "Left button"},
66         {KEY_RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     0, "Right button"},
67         {KEY_KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     0, "Action button"},
68         {KEY_RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    0, "Record button"},
69         {KEY_VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   0, "Volume up"},
70         {KEY_VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, 0, "Volume down"},
71         {KEY_PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    0, "Phone button"},
72         {KEY_PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  0, "Headset button"},
73 };
74
75 static struct gpio_keys_platform_data gpio_keys_data = {
76         .buttons  = magician_button_table,
77         .nbuttons = ARRAY_SIZE(magician_button_table),
78 };
79
80 static struct platform_device gpio_keys = {
81         .name = "gpio-keys",
82         .dev  = {
83                 .platform_data = &gpio_keys_data,
84         },
85         .id   = -1,
86 };
87
88
89 /*
90  * EGPIO (Xilinx CPLD)
91  *
92  * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
93  */
94
95 static struct resource egpio_resources[] = {
96         [0] = {
97                 .start = PXA_CS3_PHYS,
98                 .end   = PXA_CS3_PHYS + 0x20,
99                 .flags = IORESOURCE_MEM,
100         },
101         [1] = {
102                 .start = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ),
103                 .end   = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ),
104                 .flags = IORESOURCE_IRQ,
105         },
106 };
107
108 static struct htc_egpio_chip egpio_chips[] = {
109         [0] = {
110                 .reg_start = 0,
111                 .gpio_base = MAGICIAN_EGPIO(0, 0),
112                 .num_gpios = 24,
113                 .direction = HTC_EGPIO_OUTPUT,
114                 .initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
115         },
116         [1] = {
117                 .reg_start = 4,
118                 .gpio_base = MAGICIAN_EGPIO(4, 0),
119                 .num_gpios = 24,
120                 .direction = HTC_EGPIO_INPUT,
121         },
122 };
123
124 static struct htc_egpio_platform_data egpio_info = {
125         .reg_width    = 8,
126         .bus_width    = 32,
127         .irq_base     = IRQ_BOARD_START,
128         .num_irqs     = 4,
129         .ack_register = 3,
130         .chip         = egpio_chips,
131         .num_chips    = ARRAY_SIZE(egpio_chips),
132 };
133
134 static struct platform_device egpio = {
135         .name          = "htc-egpio",
136         .id            = -1,
137         .resource      = egpio_resources,
138         .num_resources = ARRAY_SIZE(egpio_resources),
139         .dev = {
140                 .platform_data = &egpio_info,
141         },
142 };
143
144 /*
145  * LCD - Toppoly TD028STEB1
146  */
147
148 static struct pxafb_mode_info toppoly_modes[] = {
149         {
150                 .pixclock     = 96153,
151                 .bpp          = 16,
152                 .xres         = 240,
153                 .yres         = 320,
154                 .hsync_len    = 11,
155                 .vsync_len    = 3,
156                 .left_margin  = 19,
157                 .upper_margin = 2,
158                 .right_margin = 10,
159                 .lower_margin = 2,
160                 .sync         = 0,
161         },
162 };
163
164 static struct pxafb_mach_info toppoly_info = {
165         .modes       = toppoly_modes,
166         .num_modes   = 1,
167         .fixed_modes = 1,
168         .lccr0       = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
169         .lccr3       = LCCR3_PixRsEdg,
170 };
171
172 /*
173  * Backlight
174  */
175
176 static void magician_set_bl_intensity(int intensity)
177 {
178         if (intensity) {
179                 PWM_CTRL0 = 1;
180                 PWM_PERVAL0 = 0xc8;
181                 PWM_PWDUTY0 = intensity;
182                 pxa_set_cken(CKEN_PWM0, 1);
183         } else {
184                 pxa_set_cken(CKEN_PWM0, 0);
185         }
186 }
187
188 static struct generic_bl_info backlight_info = {
189         .default_intensity = 0x64,
190         .limit_mask        = 0x0b,
191         .max_intensity     = 0xc7,
192         .set_bl_intensity  = magician_set_bl_intensity,
193 };
194
195 static struct platform_device backlight = {
196         .name = "generic-bl",
197         .dev  = {
198                 .platform_data = &backlight_info,
199         },
200         .id   = -1,
201 };
202
203
204 /*
205  * USB OHCI
206  */
207
208 static int magician_ohci_init(struct device *dev)
209 {
210         UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) &
211             ~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE);
212
213         return 0;
214 }
215
216 static struct pxaohci_platform_data magician_ohci_info = {
217         .port_mode    = PMM_PERPORT_MODE,
218         .init         = magician_ohci_init,
219         .power_budget = 0,
220 };
221
222
223 /*
224  * StrataFlash
225  */
226
227 #define PXA_CS_SIZE             0x04000000
228
229 static struct resource strataflash_resource = {
230         .start = PXA_CS0_PHYS,
231         .end   = PXA_CS0_PHYS + PXA_CS_SIZE - 1,
232         .flags = IORESOURCE_MEM,
233 };
234
235 static struct physmap_flash_data strataflash_data = {
236         .width = 4,
237 };
238
239 static struct platform_device strataflash = {
240         .name          = "physmap-flash",
241         .id            = -1,
242         .resource      = &strataflash_resource,
243         .num_resources = 1,
244         .dev = {
245                 .platform_data = &strataflash_data,
246         },
247 };
248
249 /*
250  * Platform devices
251  */
252
253 static struct platform_device *devices[] __initdata = {
254         &gpio_keys,
255         &egpio,
256         &backlight,
257         &strataflash,
258 };
259
260 static void __init magician_init(void)
261 {
262         platform_add_devices(devices, ARRAY_SIZE(devices));
263         pxa_set_i2c_info(NULL);
264         pxa_set_ohci_info(&magician_ohci_info);
265         pxa_set_ficp_info(&magician_ficp_info);
266         set_pxa_fb_info(&toppoly_info);
267 }
268
269
270 MACHINE_START(MAGICIAN, "HTC Magician")
271         .phys_io = 0x40000000,
272         .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
273         .boot_params = 0xa0000100,
274         .map_io = pxa_map_io,
275         .init_irq = pxa27x_init_irq,
276         .init_machine = magician_init,
277         .timer = &pxa_timer,
278 MACHINE_END