]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef _I8042_SPARCIO_H |
2 | #define _I8042_SPARCIO_H | |
3 | ||
1da177e4 | 4 | #include <asm/io.h> |
1da177e4 | 5 | #include <asm/oplib.h> |
f57caaef DM |
6 | #include <asm/prom.h> |
7 | #include <asm/of_device.h> | |
1da177e4 LT |
8 | |
9 | static int i8042_kbd_irq = -1; | |
10 | static int i8042_aux_irq = -1; | |
11 | #define I8042_KBD_IRQ i8042_kbd_irq | |
12 | #define I8042_AUX_IRQ i8042_aux_irq | |
13 | ||
14 | #define I8042_KBD_PHYS_DESC "sparcps2/serio0" | |
15 | #define I8042_AUX_PHYS_DESC "sparcps2/serio1" | |
16 | #define I8042_MUX_PHYS_DESC "sparcps2/serio%d" | |
17 | ||
18 | static void __iomem *kbd_iobase; | |
19 | ||
20 | #define I8042_COMMAND_REG (kbd_iobase + 0x64UL) | |
21 | #define I8042_DATA_REG (kbd_iobase + 0x60UL) | |
22 | ||
23 | static inline int i8042_read_data(void) | |
24 | { | |
25 | return readb(kbd_iobase + 0x60UL); | |
26 | } | |
27 | ||
28 | static inline int i8042_read_status(void) | |
29 | { | |
30 | return readb(kbd_iobase + 0x64UL); | |
31 | } | |
32 | ||
33 | static inline void i8042_write_data(int val) | |
34 | { | |
35 | writeb(val, kbd_iobase + 0x60UL); | |
36 | } | |
37 | ||
38 | static inline void i8042_write_command(int val) | |
39 | { | |
40 | writeb(val, kbd_iobase + 0x64UL); | |
41 | } | |
42 | ||
43 | #define OBP_PS2KBD_NAME1 "kb_ps2" | |
44 | #define OBP_PS2KBD_NAME2 "keyboard" | |
45 | #define OBP_PS2MS_NAME1 "kdmouse" | |
46 | #define OBP_PS2MS_NAME2 "mouse" | |
47 | ||
f57caaef DM |
48 | static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_device_id *match) |
49 | { | |
50 | struct device_node *dp = op->node; | |
51 | ||
52 | dp = dp->child; | |
53 | while (dp) { | |
54 | if (!strcmp(dp->name, OBP_PS2KBD_NAME1) || | |
55 | !strcmp(dp->name, OBP_PS2KBD_NAME2)) { | |
56 | struct of_device *kbd = of_find_device_by_node(dp); | |
57 | unsigned int irq = kbd->irqs[0]; | |
58 | if (irq == 0xffffffff) | |
59 | irq = op->irqs[0]; | |
60 | i8042_kbd_irq = irq; | |
61 | kbd_iobase = of_ioremap(&kbd->resource[0], | |
62 | 0, 8, "kbd"); | |
63 | } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) || | |
64 | !strcmp(dp->name, OBP_PS2MS_NAME2)) { | |
65 | struct of_device *ms = of_find_device_by_node(dp); | |
66 | unsigned int irq = ms->irqs[0]; | |
67 | if (irq == 0xffffffff) | |
68 | irq = op->irqs[0]; | |
69 | i8042_aux_irq = irq; | |
70 | } | |
71 | ||
72 | dp = dp->sibling; | |
73 | } | |
74 | ||
75 | return 0; | |
76 | } | |
77 | ||
78 | static int __devexit sparc_i8042_remove(struct of_device *op) | |
79 | { | |
80 | of_iounmap(kbd_iobase, 8); | |
81 | ||
82 | return 0; | |
83 | } | |
84 | ||
85 | static struct of_device_id sparc_i8042_match[] = { | |
86 | { | |
87 | .name = "8042", | |
88 | }, | |
89 | {}, | |
90 | }; | |
91 | MODULE_DEVICE_TABLE(of, i8042_match); | |
92 | ||
93 | static struct of_platform_driver sparc_i8042_driver = { | |
94 | .name = "i8042", | |
95 | .match_table = sparc_i8042_match, | |
96 | .probe = sparc_i8042_probe, | |
97 | .remove = __devexit_p(sparc_i8042_remove), | |
98 | }; | |
99 | ||
8d5987a6 | 100 | static int __init i8042_platform_init(void) |
1da177e4 LT |
101 | { |
102 | #ifndef CONFIG_PCI | |
8d5987a6 | 103 | return -ENODEV; |
1da177e4 | 104 | #else |
f57caaef | 105 | struct device_node *root = of_find_node_by_path("/"); |
1da177e4 | 106 | |
f57caaef | 107 | if (!strcmp(root->name, "SUNW,JavaStation-1")) { |
1da177e4 LT |
108 | /* Hardcoded values for MrCoffee. */ |
109 | i8042_kbd_irq = i8042_aux_irq = 13 | 0x20; | |
110 | kbd_iobase = ioremap(0x71300060, 8); | |
111 | if (!kbd_iobase) | |
8d5987a6 | 112 | return -ENODEV; |
1da177e4 | 113 | } else { |
f57caaef DM |
114 | int err = of_register_driver(&sparc_i8042_driver, |
115 | &of_bus_type); | |
116 | if (err) | |
117 | return err; | |
118 | ||
1da177e4 LT |
119 | if (i8042_kbd_irq == -1 || |
120 | i8042_aux_irq == -1) { | |
f57caaef DM |
121 | if (kbd_iobase) { |
122 | of_iounmap(kbd_iobase, 8); | |
123 | kbd_iobase = (void __iomem *) NULL; | |
124 | } | |
8d5987a6 | 125 | return -ENODEV; |
1da177e4 LT |
126 | } |
127 | } | |
128 | ||
129 | i8042_reset = 1; | |
130 | ||
131 | return 0; | |
132 | #endif /* CONFIG_PCI */ | |
133 | } | |
134 | ||
135 | static inline void i8042_platform_exit(void) | |
136 | { | |
137 | #ifdef CONFIG_PCI | |
f57caaef DM |
138 | struct device_node *root = of_find_node_by_path("/"); |
139 | ||
140 | if (strcmp(root->name, "SUNW,JavaStation-1")) | |
141 | of_unregister_driver(&sparc_i8042_driver); | |
1da177e4 LT |
142 | #endif |
143 | } | |
144 | ||
145 | #endif /* _I8042_SPARCIO_H */ |