This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / input / serio / i8042-x86ia64io.h
1 #ifndef _I8042_X86IA64IO_H
2 #define _I8042_X86IA64IO_H
3
4 /*
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 as published by
7  * the Free Software Foundation.
8  */
9
10 /*
11  * Names.
12  */
13
14 #define I8042_KBD_PHYS_DESC "isa0060/serio0"
15 #define I8042_AUX_PHYS_DESC "isa0060/serio1"
16 #define I8042_MUX_PHYS_DESC "isa0060/serio%d"
17
18 /*
19  * IRQs.
20  */
21
22 #if defined(__ia64__)
23 # define I8042_MAP_IRQ(x)       isa_irq_to_vector((x))
24 #else
25 # define I8042_MAP_IRQ(x)       (x)
26 #endif
27
28 #define I8042_KBD_IRQ   i8042_kbd_irq
29 #define I8042_AUX_IRQ   i8042_aux_irq
30
31 static int i8042_kbd_irq;
32 static int i8042_aux_irq;
33
34 /*
35  * Register numbers.
36  */
37
38 #define I8042_COMMAND_REG       i8042_command_reg
39 #define I8042_STATUS_REG        i8042_command_reg
40 #define I8042_DATA_REG          i8042_data_reg
41
42 static int i8042_command_reg = 0x64;
43 static int i8042_data_reg = 0x60;
44
45
46 static inline int i8042_read_data(void)
47 {
48         return inb(I8042_DATA_REG);
49 }
50
51 static inline int i8042_read_status(void)
52 {
53         return inb(I8042_STATUS_REG);
54 }
55
56 static inline void i8042_write_data(int val)
57 {
58         outb(val, I8042_DATA_REG);
59 }
60
61 static inline void i8042_write_command(int val)
62 {
63         outb(val, I8042_COMMAND_REG);
64 }
65
66 #if defined(__i386__)
67
68 #include <linux/dmi.h>
69
70 static struct dmi_system_id __initdata i8042_dmi_table[] = {
71         {
72                 .ident = "Compaq Proliant 8500",
73                 .matches = {
74                         DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
75                         DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
76                         DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
77                 },
78         },
79         {
80                 .ident = "Compaq Proliant DL760",
81                 .matches = {
82                         DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
83                         DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
84                         DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
85                 },
86         },
87         { }
88 };
89 #endif
90
91 #if defined(__ia64__) && defined(CONFIG_ACPI)
92 #include <linux/acpi.h>
93 #include <acpi/acpi_bus.h>
94
95 struct i8042_acpi_resources {
96         unsigned int port1;
97         unsigned int port2;
98         unsigned int irq;
99 };
100
101 static int i8042_acpi_kbd_registered;
102 static int i8042_acpi_aux_registered;
103
104 static acpi_status i8042_acpi_parse_resource(struct acpi_resource *res, void *data)
105 {
106         struct i8042_acpi_resources *i8042_res = data;
107         struct acpi_resource_io *io;
108         struct acpi_resource_fixed_io *fixed_io;
109         struct acpi_resource_irq *irq;
110         struct acpi_resource_ext_irq *ext_irq;
111
112         switch (res->id) {
113                 case ACPI_RSTYPE_IO:
114                         io = &res->data.io;
115                         if (io->range_length) {
116                                 if (!i8042_res->port1)
117                                         i8042_res->port1 = io->min_base_address;
118                                 else
119                                         i8042_res->port2 = io->min_base_address;
120                         }
121                         break;
122
123                 case ACPI_RSTYPE_FIXED_IO:
124                         fixed_io = &res->data.fixed_io;
125                         if (fixed_io->range_length) {
126                                 if (!i8042_res->port1)
127                                         i8042_res->port1 = fixed_io->base_address;
128                                 else
129                                         i8042_res->port2 = fixed_io->base_address;
130                         }
131                         break;
132
133                 case ACPI_RSTYPE_IRQ:
134                         irq = &res->data.irq;
135                         if (irq->number_of_interrupts > 0)
136                                 i8042_res->irq =
137                                         acpi_register_gsi(irq->interrupts[0],
138                                                           irq->edge_level,
139                                                           irq->active_high_low);
140                         break;
141
142                 case ACPI_RSTYPE_EXT_IRQ:
143                         ext_irq = &res->data.extended_irq;
144                         if (ext_irq->number_of_interrupts > 0)
145                                 i8042_res->irq =
146                                         acpi_register_gsi(ext_irq->interrupts[0],
147                                                           ext_irq->edge_level,
148                                                           ext_irq->active_high_low);
149                         break;
150         }
151         return AE_OK;
152 }
153
154 static int i8042_acpi_kbd_add(struct acpi_device *device)
155 {
156         struct i8042_acpi_resources kbd_res;
157         acpi_status status;
158
159         memset(&kbd_res, 0, sizeof(kbd_res));
160         status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
161                                      i8042_acpi_parse_resource, &kbd_res);
162         if (ACPI_FAILURE(status))
163                 return -ENODEV;
164
165         if (kbd_res.port1)
166                 i8042_data_reg = kbd_res.port1;
167         else
168                 printk(KERN_WARNING "ACPI: [%s] has no data port; default is 0x%x\n",
169                         acpi_device_bid(device), i8042_data_reg);
170
171         if (kbd_res.port2)
172                 i8042_command_reg = kbd_res.port2;
173         else
174                 printk(KERN_WARNING "ACPI: [%s] has no command port; default is 0x%x\n",
175                         acpi_device_bid(device), i8042_command_reg);
176
177         if (kbd_res.irq)
178                 i8042_kbd_irq = kbd_res.irq;
179         else
180                 printk(KERN_WARNING "ACPI: [%s] has no IRQ; default is %d\n",
181                         acpi_device_bid(device), i8042_kbd_irq);
182
183         strncpy(acpi_device_name(device), "PS/2 Keyboard Controller",
184                 sizeof(acpi_device_name(device)));
185         printk("ACPI: %s [%s] at I/O 0x%x, 0x%x, irq %d\n",
186                 acpi_device_name(device), acpi_device_bid(device),
187                 i8042_data_reg, i8042_command_reg, i8042_kbd_irq);
188
189         return 0;
190 }
191
192 static int i8042_acpi_aux_add(struct acpi_device *device)
193 {
194         struct i8042_acpi_resources aux_res;
195         acpi_status status;
196
197         memset(&aux_res, 0, sizeof(aux_res));
198         status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
199                                      i8042_acpi_parse_resource, &aux_res);
200         if (ACPI_FAILURE(status))
201                 return -ENODEV;
202
203         if (aux_res.irq)
204                 i8042_aux_irq = aux_res.irq;
205         else
206                 printk(KERN_WARNING "ACPI: [%s] has no IRQ; default is %d\n",
207                         acpi_device_bid(device), i8042_aux_irq);
208
209         strncpy(acpi_device_name(device), "PS/2 Mouse Controller",
210                 sizeof(acpi_device_name(device)));
211         printk("ACPI: %s [%s] at irq %d\n",
212                 acpi_device_name(device), acpi_device_bid(device), i8042_aux_irq);
213
214         return 0;
215 }
216
217 static struct acpi_driver i8042_acpi_kbd_driver = {
218         .name           = "i8042",
219         .ids            = "PNP0303,PNP030B",
220         .ops            = {
221                 .add            = i8042_acpi_kbd_add,
222         },
223 };
224
225 static struct acpi_driver i8042_acpi_aux_driver = {
226         .name           = "i8042",
227         .ids            = "PNP0F03,PNP0F0B,PNP0F0E,PNP0F12,PNP0F13,SYN0801",
228         .ops            = {
229                 .add            = i8042_acpi_aux_add,
230         },
231 };
232
233 static int i8042_acpi_init(void)
234 {
235         int result;
236
237         if (acpi_disabled || i8042_noacpi) {
238                 printk("i8042: ACPI detection disabled\n");
239                 return 0;
240         }
241
242         result = acpi_bus_register_driver(&i8042_acpi_kbd_driver);
243         if (result < 0)
244                 return result;
245
246         if (result == 0) {
247                 acpi_bus_unregister_driver(&i8042_acpi_kbd_driver);
248                 return -ENODEV;
249         }
250         i8042_acpi_kbd_registered = 1;
251
252         result = acpi_bus_register_driver(&i8042_acpi_aux_driver);
253         if (result >= 0)
254                 i8042_acpi_aux_registered = 1;
255         if (result == 0)
256                 i8042_noaux = 1;
257
258         return 0;
259 }
260
261 static void i8042_acpi_exit(void)
262 {
263         if (i8042_acpi_kbd_registered)
264                 acpi_bus_unregister_driver(&i8042_acpi_kbd_driver);
265
266         if (i8042_acpi_aux_registered)
267                 acpi_bus_unregister_driver(&i8042_acpi_aux_driver);
268 }
269 #endif
270
271 static inline int i8042_platform_init(void)
272 {
273 /*
274  * On ix86 platforms touching the i8042 data register region can do really
275  * bad things. Because of this the region is always reserved on ix86 boxes.
276  *
277  *      if (!request_region(I8042_DATA_REG, 16, "i8042"))
278  *              return -1;
279  */
280
281         i8042_kbd_irq = I8042_MAP_IRQ(1);
282         i8042_aux_irq = I8042_MAP_IRQ(12);
283
284 #if defined(__ia64__) && defined(CONFIG_ACPI)
285         if (i8042_acpi_init())
286                 return -1;
287 #endif
288
289 #if defined(__ia64__)
290         i8042_reset = 1;
291 #endif
292
293 #if defined(__i386__)
294         if (dmi_check_system(i8042_dmi_table))
295                 i8042_noloop = 1;
296 #endif
297
298         return 0;
299 }
300
301 static inline void i8042_platform_exit(void)
302 {
303 #if defined(__ia64__) && defined(CONFIG_ACPI)
304         i8042_acpi_exit();
305 #endif
306 }
307
308 #endif /* _I8042_X86IA64IO_H */