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 */
309
|
This page was automatically generated by the
LXR engine.
|