aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/input/serio
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/Kconfig183
-rw-r--r--drivers/input/serio/Makefile23
-rw-r--r--drivers/input/serio/ambakmi.c231
-rw-r--r--drivers/input/serio/ct82c710.c225
-rw-r--r--drivers/input/serio/gscps2.c467
-rw-r--r--drivers/input/serio/hil_mlc.c949
-rw-r--r--drivers/input/serio/hp_sdc.c1054
-rw-r--r--drivers/input/serio/hp_sdc_mlc.c358
-rw-r--r--drivers/input/serio/i8042-io.h93
-rw-r--r--drivers/input/serio/i8042-ip22io.h76
-rw-r--r--drivers/input/serio/i8042-jazzio.h69
-rw-r--r--drivers/input/serio/i8042-ppcio.h136
-rw-r--r--drivers/input/serio/i8042-sparcio.h116
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h333
-rw-r--r--drivers/input/serio/i8042.c1116
-rw-r--r--drivers/input/serio/i8042.h133
-rw-r--r--drivers/input/serio/libps2.c305
-rw-r--r--drivers/input/serio/maceps2.c176
-rw-r--r--drivers/input/serio/parkbd.c218
-rw-r--r--drivers/input/serio/pcips2.c234
-rw-r--r--drivers/input/serio/q40kbd.c163
-rw-r--r--drivers/input/serio/rpckbd.c156
-rw-r--r--drivers/input/serio/sa1111ps2.c359
-rw-r--r--drivers/input/serio/serio.c859
-rw-r--r--drivers/input/serio/serio_raw.c403
-rw-r--r--drivers/input/serio/serport.c226
26 files changed, 8661 insertions, 0 deletions
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
new file mode 100644
index 000000000000..b3710733b36b
--- /dev/null
+++ b/drivers/input/serio/Kconfig
@@ -0,0 +1,183 @@
1#
2# Input core configuration
3#
4config SERIO
5 tristate "Serial I/O support" if EMBEDDED || !X86
6 default y
7 ---help---
8 Say Yes here if you have any input device that uses serial I/O to
9 communicate with the system. This includes the
10 * standard AT keyboard and PS/2 mouse *
11 as well as serial mice, Sun keyboards, some joysticks and 6dof
12 devices and more.
13
14 If unsure, say Y.
15
16 To compile this driver as a module, choose M here: the
17 module will be called serio.
18
19if SERIO
20
21config SERIO_I8042
22 tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
23 default y
24 depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K
25 ---help---
26 i8042 is the chip over which the standard AT keyboard and PS/2
27 mouse are connected to the computer. If you use these devices,
28 you'll need to say Y here.
29
30 If unsure, say Y.
31
32 To compile this driver as a module, choose M here: the
33 module will be called i8042.
34
35config SERIO_SERPORT
36 tristate "Serial port line discipline"
37 default y
38 ---help---
39 Say Y here if you plan to use an input device (mouse, joystick,
40 tablet, 6dof) that communicates over the RS232 serial (COM) port.
41
42 More information is available: <file:Documentation/input/input.txt>
43
44 If unsure, say Y.
45
46 To compile this driver as a module, choose M here: the
47 module will be called serport.
48
49config SERIO_CT82C710
50 tristate "ct82c710 Aux port controller"
51 depends on X86
52 ---help---
53 Say Y here if you have a Texas Instruments TravelMate notebook
54 equipped with the ct82c710 chip and want to use a mouse connected
55 to the "QuickPort".
56
57 If unsure, say N.
58
59 To compile this driver as a module, choose M here: the
60 module will be called ct82c710.
61
62config SERIO_Q40KBD
63 tristate "Q40 keyboard controller"
64 depends on Q40
65
66config SERIO_PARKBD
67 tristate "Parallel port keyboard adapter"
68 depends on PARPORT
69 ---help---
70 Say Y here if you built a simple parallel port adapter to attach
71 an additional AT keyboard, XT keyboard or PS/2 mouse.
72
73 More information is available: <file:Documentation/input/input.txt>
74
75 If unsure, say N.
76
77 To compile this driver as a module, choose M here: the
78 module will be called parkbd.
79
80config SERIO_RPCKBD
81 tristate "Acorn RiscPC keyboard controller"
82 depends on ARCH_ACORN || ARCH_CLPS7500
83 default y
84 help
85 Say Y here if you have the Acorn RiscPC and want to use an AT
86 keyboard connected to its keyboard controller.
87
88 To compile this driver as a module, choose M here: the
89 module will be called rpckbd.
90
91config SERIO_AMBAKMI
92 tristate "AMBA KMI keyboard controller"
93 depends on ARM_AMBA
94
95config SERIO_SA1111
96 tristate "Intel SA1111 keyboard controller"
97 depends on SA1111
98
99config SERIO_GSCPS2
100 tristate "HP GSC PS/2 keyboard and PS/2 mouse controller"
101 depends on GSC
102 default y
103 help
104 This driver provides support for the PS/2 ports on PA-RISC machines
105 over which HP PS/2 keyboards and PS/2 mice may be connected.
106 If you use these devices, you'll need to say Y here.
107
108 It's safe to enable this driver, so if unsure, say Y.
109
110 To compile this driver as a module, choose M here: the
111 module will be called gscps2.
112
113config HP_SDC
114 tristate "HP System Device Controller i8042 Support"
115 depends on GSC && SERIO
116 default y
117 ---help---
118 This option enables supports for the the "System Device
119 Controller", an i8042 carrying microcode to manage a
120 few miscellanous devices on some Hewlett Packard systems.
121 The SDC itself contains a 10ms resolution timer/clock capable
122 of delivering interrupts on a periodic and one-shot basis.
123 The SDC may also be connected to a battery-backed real-time
124 clock, a basic audio waveform generator, and an HP-HIL Master
125 Link Controller serving up to seven input devices.
126
127 By itself this option is rather useless, but enabling it will
128 enable selection of drivers for the abovementioned devices.
129 It is, however, incompatible with the old, reliable HIL keyboard
130 driver, and the new HIL driver is experimental, so if you plan
131 to use a HIL keyboard as your primary keyboard, you may wish
132 to keep using that driver until the new HIL drivers have had
133 more testing.
134
135config HIL_MLC
136 tristate "HIL MLC Support (needed for HIL input devices)"
137 depends on HP_SDC
138
139config SERIO_PCIPS2
140 tristate "PCI PS/2 keyboard and PS/2 mouse controller"
141 depends on PCI
142 help
143 Say Y here if you have a Mobility Docking station with PS/2
144 keyboard and mice ports.
145
146 To compile this driver as a module, choose M here: the
147 module will be called pcips2.
148
149config SERIO_MACEPS2
150 tristate "SGI O2 MACE PS/2 controller"
151 depends on SGI_IP32
152 help
153 Say Y here if you have SGI O2 workstation and want to use its
154 PS/2 ports.
155
156 To compile this driver as a module, choose M here: the
157 module will be called maceps2.
158
159config SERIO_LIBPS2
160 tristate "PS/2 driver library" if EMBEDDED
161 help
162 Say Y here if you are using a driver for device connected
163 to a PS/2 port, such as PS/2 mouse or standard AT keyboard.
164
165 To compile this driver as a module, choose M here: the
166 module will be called libps2.
167
168config SERIO_RAW
169 tristate "Raw access to serio ports"
170 help
171 Say Y here if you want to have raw access to serio ports, such as
172 AUX ports on i8042 keyboard controller. Each serio port that is
173 bound to this driver will be accessible via a char device with
174 major 10 and dynamically allocated minor. The driver will try
175 allocating minor 1 (that historically corresponds to /dev/psaux)
176 first. To bind this driver to a serio port use sysfs interface:
177
178 echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver
179
180 To compile this driver as a module, choose M here: the
181 module will be called serio_raw.
182
183endif
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
new file mode 100644
index 000000000000..678a8599f9ff
--- /dev/null
+++ b/drivers/input/serio/Makefile
@@ -0,0 +1,23 @@
1#
2# Makefile for the input core drivers.
3#
4
5# Each configuration option enables a list of files.
6
7obj-$(CONFIG_SERIO) += serio.o
8obj-$(CONFIG_SERIO_I8042) += i8042.o
9obj-$(CONFIG_SERIO_PARKBD) += parkbd.o
10obj-$(CONFIG_SERIO_SERPORT) += serport.o
11obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o
12obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o
13obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o
14obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o
15obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o
16obj-$(CONFIG_SERIO_98KBD) += 98kbd-io.o
17obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o
18obj-$(CONFIG_HP_SDC) += hp_sdc.o
19obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o
20obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o
21obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o
22obj-$(CONFIG_SERIO_LIBPS2) += libps2.o
23obj-$(CONFIG_SERIO_RAW) += serio_raw.o
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
new file mode 100644
index 000000000000..9b1ab5e7a98d
--- /dev/null
+++ b/drivers/input/serio/ambakmi.c
@@ -0,0 +1,231 @@
1/*
2 * linux/drivers/input/serio/ambakmi.c
3 *
4 * Copyright (C) 2000-2003 Deep Blue Solutions Ltd.
5 * Copyright (C) 2002 Russell King.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/serio.h>
15#include <linux/errno.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/device.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/err.h>
22
23#include <asm/io.h>
24#include <asm/irq.h>
25#include <asm/hardware/amba.h>
26#include <asm/hardware/amba_kmi.h>
27#include <asm/hardware/clock.h>
28
29#define KMI_BASE (kmi->base)
30
31struct amba_kmi_port {
32 struct serio *io;
33 struct clk *clk;
34 void __iomem *base;
35 unsigned int irq;
36 unsigned int divisor;
37 unsigned int open;
38};
39
40static irqreturn_t amba_kmi_int(int irq, void *dev_id, struct pt_regs *regs)
41{
42 struct amba_kmi_port *kmi = dev_id;
43 unsigned int status = readb(KMIIR);
44 int handled = IRQ_NONE;
45
46 while (status & KMIIR_RXINTR) {
47 serio_interrupt(kmi->io, readb(KMIDATA), 0, regs);
48 status = readb(KMIIR);
49 handled = IRQ_HANDLED;
50 }
51
52 return handled;
53}
54
55static int amba_kmi_write(struct serio *io, unsigned char val)
56{
57 struct amba_kmi_port *kmi = io->port_data;
58 unsigned int timeleft = 10000; /* timeout in 100ms */
59
60 while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--)
61 udelay(10);
62
63 if (timeleft)
64 writeb(val, KMIDATA);
65
66 return timeleft ? 0 : SERIO_TIMEOUT;
67}
68
69static int amba_kmi_open(struct serio *io)
70{
71 struct amba_kmi_port *kmi = io->port_data;
72 unsigned int divisor;
73 int ret;
74
75 ret = clk_use(kmi->clk);
76 if (ret)
77 goto out;
78
79 ret = clk_enable(kmi->clk);
80 if (ret)
81 goto clk_unuse;
82
83 divisor = clk_get_rate(kmi->clk) / 8000000 - 1;
84 writeb(divisor, KMICLKDIV);
85 writeb(KMICR_EN, KMICR);
86
87 ret = request_irq(kmi->irq, amba_kmi_int, 0, "kmi-pl050", kmi);
88 if (ret) {
89 printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
90 writeb(0, KMICR);
91 goto clk_disable;
92 }
93
94 writeb(KMICR_EN | KMICR_RXINTREN, KMICR);
95
96 return 0;
97
98 clk_disable:
99 clk_disable(kmi->clk);
100 clk_unuse:
101 clk_unuse(kmi->clk);
102 out:
103 return ret;
104}
105
106static void amba_kmi_close(struct serio *io)
107{
108 struct amba_kmi_port *kmi = io->port_data;
109
110 writeb(0, KMICR);
111
112 free_irq(kmi->irq, kmi);
113 clk_disable(kmi->clk);
114 clk_unuse(kmi->clk);
115}
116
117static int amba_kmi_probe(struct amba_device *dev, void *id)
118{
119 struct amba_kmi_port *kmi;
120 struct serio *io;
121 int ret;
122
123 ret = amba_request_regions(dev, NULL);
124 if (ret)
125 return ret;
126
127 kmi = kmalloc(sizeof(struct amba_kmi_port), GFP_KERNEL);
128 io = kmalloc(sizeof(struct serio), GFP_KERNEL);
129 if (!kmi || !io) {
130 ret = -ENOMEM;
131 goto out;
132 }
133
134 memset(kmi, 0, sizeof(struct amba_kmi_port));
135 memset(io, 0, sizeof(struct serio));
136
137 io->id.type = SERIO_8042;
138 io->write = amba_kmi_write;
139 io->open = amba_kmi_open;
140 io->close = amba_kmi_close;
141 strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
142 strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
143 io->port_data = kmi;
144 io->dev.parent = &dev->dev;
145
146 kmi->io = io;
147 kmi->base = ioremap(dev->res.start, KMI_SIZE);
148 if (!kmi->base) {
149 ret = -ENOMEM;
150 goto out;
151 }
152
153 kmi->clk = clk_get(&dev->dev, "KMIREFCLK");
154 if (IS_ERR(kmi->clk)) {
155 ret = PTR_ERR(kmi->clk);
156 goto unmap;
157 }
158
159 kmi->irq = dev->irq[0];
160 amba_set_drvdata(dev, kmi);
161
162 serio_register_port(kmi->io);
163 return 0;
164
165 unmap:
166 iounmap(kmi->base);
167 out:
168 kfree(kmi);
169 kfree(io);
170 amba_release_regions(dev);
171 return ret;
172}
173
174static int amba_kmi_remove(struct amba_device *dev)
175{
176 struct amba_kmi_port *kmi = amba_get_drvdata(dev);
177
178 amba_set_drvdata(dev, NULL);
179
180 serio_unregister_port(kmi->io);
181 clk_put(kmi->clk);
182 iounmap(kmi->base);
183 kfree(kmi);
184 amba_release_regions(dev);
185 return 0;
186}
187
188static int amba_kmi_resume(struct amba_device *dev)
189{
190 struct amba_kmi_port *kmi = amba_get_drvdata(dev);
191
192 /* kick the serio layer to rescan this port */
193 serio_reconnect(kmi->io);
194
195 return 0;
196}
197
198static struct amba_id amba_kmi_idtable[] = {
199 {
200 .id = 0x00041050,
201 .mask = 0x000fffff,
202 },
203 { 0, 0 }
204};
205
206static struct amba_driver ambakmi_driver = {
207 .drv = {
208 .name = "kmi-pl050",
209 },
210 .id_table = amba_kmi_idtable,
211 .probe = amba_kmi_probe,
212 .remove = amba_kmi_remove,
213 .resume = amba_kmi_resume,
214};
215
216static int __init amba_kmi_init(void)
217{
218 return amba_driver_register(&ambakmi_driver);
219}
220
221static void __exit amba_kmi_exit(void)
222{
223 amba_driver_unregister(&ambakmi_driver);
224}
225
226module_init(amba_kmi_init);
227module_exit(amba_kmi_exit);
228
229MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
230MODULE_DESCRIPTION("AMBA KMI controller driver");
231MODULE_LICENSE("GPL");
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
new file mode 100644
index 000000000000..dd0f5bd90241
--- /dev/null
+++ b/drivers/input/serio/ct82c710.c
@@ -0,0 +1,225 @@
1/*
2 * $Id: ct82c710.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
3 *
4 * Copyright (c) 1999-2001 Vojtech Pavlik
5 */
6
7/*
8 * 82C710 C&T mouse port chip driver for Linux
9 */
10
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 as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * Should you need to contact me, the author, you can do so either by
27 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
28 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
29 */
30
31#include <linux/delay.h>
32#include <linux/module.h>
33#include <linux/ioport.h>
34#include <linux/config.h>
35#include <linux/init.h>
36#include <linux/interrupt.h>
37#include <linux/serio.h>
38#include <linux/errno.h>
39#include <linux/err.h>
40
41#include <asm/io.h>
42
43MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
44MODULE_DESCRIPTION("82C710 C&T mouse port chip driver");
45MODULE_LICENSE("GPL");
46
47/*
48 * ct82c710 interface
49 */
50
51#define CT82C710_DEV_IDLE 0x01 /* Device Idle */
52#define CT82C710_RX_FULL 0x02 /* Device Char received */
53#define CT82C710_TX_IDLE 0x04 /* Device XMIT Idle */
54#define CT82C710_RESET 0x08 /* Device Reset */
55#define CT82C710_INTS_ON 0x10 /* Device Interrupt On */
56#define CT82C710_ERROR_FLAG 0x20 /* Device Error */
57#define CT82C710_CLEAR 0x40 /* Device Clear */
58#define CT82C710_ENABLE 0x80 /* Device Enable */
59
60#define CT82C710_IRQ 12
61
62#define CT82C710_DATA ct82c710_iores.start
63#define CT82C710_STATUS (ct82c710_iores.start + 1)
64
65static struct serio *ct82c710_port;
66static struct platform_device *ct82c710_device;
67static struct resource ct82c710_iores;
68
69/*
70 * Interrupt handler for the 82C710 mouse port. A character
71 * is waiting in the 82C710.
72 */
73
74static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
75{
76 return serio_interrupt(ct82c710_port, inb(CT82C710_DATA), 0, regs);
77}
78
79/*
80 * Wait for device to send output char and flush any input char.
81 */
82
83static int ct82c170_wait(void)
84{
85 int timeout = 60000;
86
87 while ((inb(CT82C710_STATUS) & (CT82C710_RX_FULL | CT82C710_TX_IDLE | CT82C710_DEV_IDLE))
88 != (CT82C710_DEV_IDLE | CT82C710_TX_IDLE) && timeout) {
89
90 if (inb_p(CT82C710_STATUS) & CT82C710_RX_FULL) inb_p(CT82C710_DATA);
91
92 udelay(1);
93 timeout--;
94 }
95
96 return !timeout;
97}
98
99static void ct82c710_close(struct serio *serio)
100{
101 if (ct82c170_wait())
102 printk(KERN_WARNING "ct82c710.c: Device busy in close()\n");
103
104 outb_p(inb_p(CT82C710_STATUS) & ~(CT82C710_ENABLE | CT82C710_INTS_ON), CT82C710_STATUS);
105
106 if (ct82c170_wait())
107 printk(KERN_WARNING "ct82c710.c: Device busy in close()\n");
108
109 free_irq(CT82C710_IRQ, NULL);
110}
111
112static int ct82c710_open(struct serio *serio)
113{
114 unsigned char status;
115
116 if (request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL))
117 return -1;
118
119 status = inb_p(CT82C710_STATUS);
120
121 status |= (CT82C710_ENABLE | CT82C710_RESET);
122 outb_p(status, CT82C710_STATUS);
123
124 status &= ~(CT82C710_RESET);
125 outb_p(status, CT82C710_STATUS);
126
127 status |= CT82C710_INTS_ON;
128 outb_p(status, CT82C710_STATUS); /* Enable interrupts */
129
130 while (ct82c170_wait()) {
131 printk(KERN_ERR "ct82c710: Device busy in open()\n");
132 status &= ~(CT82C710_ENABLE | CT82C710_INTS_ON);
133 outb_p(status, CT82C710_STATUS);
134 free_irq(CT82C710_IRQ, NULL);
135 return -1;
136 }
137
138 return 0;
139}
140
141/*
142 * Write to the 82C710 mouse device.
143 */
144
145static int ct82c710_write(struct serio *port, unsigned char c)
146{
147 if (ct82c170_wait()) return -1;
148 outb_p(c, CT82C710_DATA);
149 return 0;
150}
151
152/*
153 * See if we can find a 82C710 device. Read mouse address.
154 */
155
156static int __init ct82c710_probe(void)
157{
158 outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */
159 outb_p(0xaa, 0x3fa); /* Inverse of 55 */
160 outb_p(0x36, 0x3fa); /* Address the chip */
161 outb_p(0xe4, 0x3fa); /* 390/4; 390 = config address */
162 outb_p(0x1b, 0x2fa); /* Inverse of e4 */
163 outb_p(0x0f, 0x390); /* Write index */
164 if (inb_p(0x391) != 0xe4) /* Config address found? */
165 return -1; /* No: no 82C710 here */
166
167 outb_p(0x0d, 0x390); /* Write index */
168 ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */
169 ct82c710_iores.end = ct82c710_iores.start + 1;
170 ct82c710_iores.flags = IORESOURCE_IO;
171 outb_p(0x0f, 0x390);
172 outb_p(0x0f, 0x391); /* Close config mode */
173
174 return 0;
175}
176
177static struct serio * __init ct82c710_allocate_port(void)
178{
179 struct serio *serio;
180
181 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
182 if (serio) {
183 memset(serio, 0, sizeof(struct serio));
184 serio->id.type = SERIO_8042;
185 serio->open = ct82c710_open;
186 serio->close = ct82c710_close;
187 serio->write = ct82c710_write;
188 serio->dev.parent = &ct82c710_device->dev;
189 strlcpy(serio->name, "C&T 82c710 mouse port", sizeof(serio->name));
190 snprintf(serio->phys, sizeof(serio->phys), "isa%04lx/serio0", CT82C710_DATA);
191 }
192
193 return serio;
194}
195
196static int __init ct82c710_init(void)
197{
198 if (ct82c710_probe())
199 return -ENODEV;
200
201 ct82c710_device = platform_device_register_simple("ct82c710", -1, &ct82c710_iores, 1);
202 if (IS_ERR(ct82c710_device))
203 return PTR_ERR(ct82c710_device);
204
205 if (!(ct82c710_port = ct82c710_allocate_port())) {
206 platform_device_unregister(ct82c710_device);
207 return -ENOMEM;
208 }
209
210 serio_register_port(ct82c710_port);
211
212 printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n",
213 CT82C710_DATA, CT82C710_IRQ);
214
215 return 0;
216}
217
218static void __exit ct82c710_exit(void)
219{
220 serio_unregister_port(ct82c710_port);
221 platform_device_unregister(ct82c710_device);
222}
223
224module_init(ct82c710_init);
225module_exit(ct82c710_exit);
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
new file mode 100644
index 000000000000..897e4c12b642
--- /dev/null
+++ b/drivers/input/serio/gscps2.c
@@ -0,0 +1,467 @@
1/*
2 * drivers/input/serio/gscps2.c
3 *
4 * Copyright (c) 2004 Helge Deller <deller@gmx.de>
5 * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
6 * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org>
7 *
8 * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
9 * Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca>
10 * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
11 * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
12 * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
13 *
14 * HP GSC PS/2 port driver, found in PA/RISC Workstations
15 *
16 * This file is subject to the terms and conditions of the GNU General Public
17 * License. See the file "COPYING" in the main directory of this archive
18 * for more details.
19 *
20 * TODO:
21 * - Dino testing (did HP ever shipped a machine on which this port
22 * was usable/enabled ?)
23 */
24
25#include <linux/config.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/serio.h>
29#include <linux/input.h>
30#include <linux/interrupt.h>
31#include <linux/spinlock.h>
32#include <linux/delay.h>
33#include <linux/ioport.h>
34#include <linux/pci_ids.h>
35
36#include <asm/irq.h>
37#include <asm/io.h>
38#include <asm/parisc-device.h>
39
40MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@parisc-linux.org>, Helge Deller <deller@gmx.de>");
41MODULE_DESCRIPTION("HP GSC PS2 port driver");
42MODULE_LICENSE("GPL");
43MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
44
45#define PFX "gscps2.c: "
46
47/*
48 * Driver constants
49 */
50
51/* various constants */
52#define ENABLE 1
53#define DISABLE 0
54
55#define GSC_DINO_OFFSET 0x0800 /* offset for DINO controller versus LASI one */
56
57/* PS/2 IO port offsets */
58#define GSC_ID 0x00 /* device ID offset (see: GSC_ID_XXX) */
59#define GSC_RESET 0x00 /* reset port offset */
60#define GSC_RCVDATA 0x04 /* receive port offset */
61#define GSC_XMTDATA 0x04 /* transmit port offset */
62#define GSC_CONTROL 0x08 /* see: Control register bits */
63#define GSC_STATUS 0x0C /* see: Status register bits */
64
65/* Control register bits */
66#define GSC_CTRL_ENBL 0x01 /* enable interface */
67#define GSC_CTRL_LPBXR 0x02 /* loopback operation */
68#define GSC_CTRL_DIAG 0x20 /* directly control clock/data line */
69#define GSC_CTRL_DATDIR 0x40 /* data line direct control */
70#define GSC_CTRL_CLKDIR 0x80 /* clock line direct control */
71
72/* Status register bits */
73#define GSC_STAT_RBNE 0x01 /* Receive Buffer Not Empty */
74#define GSC_STAT_TBNE 0x02 /* Transmit Buffer Not Empty */
75#define GSC_STAT_TERR 0x04 /* Timeout Error */
76#define GSC_STAT_PERR 0x08 /* Parity Error */
77#define GSC_STAT_CMPINTR 0x10 /* Composite Interrupt = irq on any port */
78#define GSC_STAT_DATSHD 0x40 /* Data Line Shadow */
79#define GSC_STAT_CLKSHD 0x80 /* Clock Line Shadow */
80
81/* IDs returned by GSC_ID port register */
82#define GSC_ID_KEYBOARD 0 /* device ID values */
83#define GSC_ID_MOUSE 1
84
85
86static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs);
87
88#define BUFFER_SIZE 0x0f
89
90/* GSC PS/2 port device struct */
91struct gscps2port {
92 struct list_head node;
93 struct parisc_device *padev;
94 struct serio *port;
95 spinlock_t lock;
96 char *addr;
97 u8 act, append; /* position in buffer[] */
98 struct {
99 u8 data;
100 u8 str;
101 } buffer[BUFFER_SIZE+1];
102 int id;
103};
104
105/*
106 * Various HW level routines
107 */
108
109#define gscps2_readb_input(x) readb((x)+GSC_RCVDATA)
110#define gscps2_readb_control(x) readb((x)+GSC_CONTROL)
111#define gscps2_readb_status(x) readb((x)+GSC_STATUS)
112#define gscps2_writeb_control(x, y) writeb((x), (y)+GSC_CONTROL)
113
114
115/*
116 * wait_TBE() - wait for Transmit Buffer Empty
117 */
118
119static int wait_TBE(char *addr)
120{
121 int timeout = 25000; /* device is expected to react within 250 msec */
122 while (gscps2_readb_status(addr) & GSC_STAT_TBNE) {
123 if (!--timeout)
124 return 0; /* This should not happen */
125 udelay(10);
126 }
127 return 1;
128}
129
130
131/*
132 * gscps2_flush() - flush the receive buffer
133 */
134
135static void gscps2_flush(struct gscps2port *ps2port)
136{
137 while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
138 gscps2_readb_input(ps2port->addr);
139 ps2port->act = ps2port->append = 0;
140}
141
142/*
143 * gscps2_writeb_output() - write a byte to the port
144 *
145 * returns 1 on sucess, 0 on error
146 */
147
148static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
149{
150 unsigned long flags;
151 char *addr = ps2port->addr;
152
153 if (!wait_TBE(addr)) {
154 printk(KERN_DEBUG PFX "timeout - could not write byte %#x\n", data);
155 return 0;
156 }
157
158 while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
159 /* wait */;
160
161 spin_lock_irqsave(&ps2port->lock, flags);
162 writeb(data, addr+GSC_XMTDATA);
163 spin_unlock_irqrestore(&ps2port->lock, flags);
164
165 /* this is ugly, but due to timing of the port it seems to be necessary. */
166 mdelay(6);
167
168 /* make sure any received data is returned as fast as possible */
169 /* this is important e.g. when we set the LEDs on the keyboard */
170 gscps2_interrupt(0, NULL, NULL);
171
172 return 1;
173}
174
175
176/*
177 * gscps2_enable() - enables or disables the port
178 */
179
180static void gscps2_enable(struct gscps2port *ps2port, int enable)
181{
182 unsigned long flags;
183 u8 data;
184
185 /* now enable/disable the port */
186 spin_lock_irqsave(&ps2port->lock, flags);
187 gscps2_flush(ps2port);
188 data = gscps2_readb_control(ps2port->addr);
189 if (enable)
190 data |= GSC_CTRL_ENBL;
191 else
192 data &= ~GSC_CTRL_ENBL;
193 gscps2_writeb_control(data, ps2port->addr);
194 spin_unlock_irqrestore(&ps2port->lock, flags);
195 wait_TBE(ps2port->addr);
196 gscps2_flush(ps2port);
197}
198
199/*
200 * gscps2_reset() - resets the PS/2 port
201 */
202
203static void gscps2_reset(struct gscps2port *ps2port)
204{
205 char *addr = ps2port->addr;
206 unsigned long flags;
207
208 /* reset the interface */
209 spin_lock_irqsave(&ps2port->lock, flags);
210 gscps2_flush(ps2port);
211 writeb(0xff, addr+GSC_RESET);
212 gscps2_flush(ps2port);
213 spin_unlock_irqrestore(&ps2port->lock, flags);
214
215 /* enable it */
216 gscps2_enable(ps2port, ENABLE);
217}
218
219static LIST_HEAD(ps2port_list);
220
221/**
222 * gscps2_interrupt() - Interruption service routine
223 *
224 * This function reads received PS/2 bytes and processes them on
225 * all interfaces.
226 * The problematic part here is, that the keyboard and mouse PS/2 port
227 * share the same interrupt and it's not possible to send data if any
228 * one of them holds input data. To solve this problem we try to receive
229 * the data as fast as possible and handle the reporting to the upper layer
230 * later.
231 */
232
233static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs)
234{
235 struct gscps2port *ps2port;
236
237 list_for_each_entry(ps2port, &ps2port_list, node) {
238
239 unsigned long flags;
240 spin_lock_irqsave(&ps2port->lock, flags);
241
242 while ( (ps2port->buffer[ps2port->append].str =
243 gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
244 ps2port->buffer[ps2port->append].data =
245 gscps2_readb_input(ps2port->addr);
246 ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
247 }
248
249 spin_unlock_irqrestore(&ps2port->lock, flags);
250
251 } /* list_for_each_entry */
252
253 /* all data was read from the ports - now report the data to upper layer */
254
255 list_for_each_entry(ps2port, &ps2port_list, node) {
256
257 while (ps2port->act != ps2port->append) {
258
259 unsigned int rxflags;
260 u8 data, status;
261
262 /* Did new data arrived while we read existing data ?
263 If yes, exit now and let the new irq handler start over again */
264 if (gscps2_readb_status(ps2port->addr) & GSC_STAT_CMPINTR)
265 return IRQ_HANDLED;
266
267 status = ps2port->buffer[ps2port->act].str;
268 data = ps2port->buffer[ps2port->act].data;
269
270 ps2port->act = ((ps2port->act+1) & BUFFER_SIZE);
271 rxflags = ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
272 ((status & GSC_STAT_PERR) ? SERIO_PARITY : 0 );
273
274 serio_interrupt(ps2port->port, data, rxflags, regs);
275
276 } /* while() */
277
278 } /* list_for_each_entry */
279
280 return IRQ_HANDLED;
281}
282
283
284/*
285 * gscps2_write() - send a byte out through the aux interface.
286 */
287
288static int gscps2_write(struct serio *port, unsigned char data)
289{
290 struct gscps2port *ps2port = port->port_data;
291
292 if (!gscps2_writeb_output(ps2port, data)) {
293 printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data);
294 return -1;
295 }
296 return 0;
297}
298
299/*
300 * gscps2_open() is called when a port is opened by the higher layer.
301 * It resets and enables the port.
302 */
303
304static int gscps2_open(struct serio *port)
305{
306 struct gscps2port *ps2port = port->port_data;
307
308 gscps2_reset(ps2port);
309
310 gscps2_interrupt(0, NULL, NULL);
311
312 return 0;
313}
314
315/*
316 * gscps2_close() disables the port
317 */
318
319static void gscps2_close(struct serio *port)
320{
321 struct gscps2port *ps2port = port->port_data;
322 gscps2_enable(ps2port, DISABLE);
323}
324
325/**
326 * gscps2_probe() - Probes PS2 devices
327 * @return: success/error report
328 */
329
330static int __init gscps2_probe(struct parisc_device *dev)
331{
332 struct gscps2port *ps2port;
333 struct serio *serio;
334 unsigned long hpa = dev->hpa;
335 int ret;
336
337 if (!dev->irq)
338 return -ENODEV;
339
340 /* Offset for DINO PS/2. Works with LASI even */
341 if (dev->id.sversion == 0x96)
342 hpa += GSC_DINO_OFFSET;
343
344 ps2port = kmalloc(sizeof(struct gscps2port), GFP_KERNEL);
345 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
346 if (!ps2port || !serio) {
347 ret = -ENOMEM;
348 goto fail_nomem;
349 }
350
351 dev_set_drvdata(&dev->dev, ps2port);
352
353 memset(ps2port, 0, sizeof(struct gscps2port));
354 memset(serio, 0, sizeof(struct serio));
355 ps2port->port = serio;
356 ps2port->padev = dev;
357 ps2port->addr = ioremap(hpa, GSC_STATUS + 4);
358 spin_lock_init(&ps2port->lock);
359
360 gscps2_reset(ps2port);
361 ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
362
363 snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
364 (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
365 strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
366 serio->id.type = SERIO_8042;
367 serio->write = gscps2_write;
368 serio->open = gscps2_open;
369 serio->close = gscps2_close;
370 serio->port_data = ps2port;
371 serio->dev.parent = &dev->dev;
372
373 list_add_tail(&ps2port->node, &ps2port_list);
374
375 ret = -EBUSY;
376 if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port))
377 goto fail_miserably;
378
379 if (ps2port->id != GSC_ID_KEYBOARD && ps2port->id != GSC_ID_MOUSE) {
380 printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n",
381 hpa, ps2port->id);
382 ret = -ENODEV;
383 goto fail;
384 }
385
386#if 0
387 if (!request_mem_region(hpa, GSC_STATUS + 4, ps2port->port.name))
388 goto fail;
389#endif
390
391 printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n",
392 ps2port->port->name,
393 ps2port->addr,
394 ps2port->padev->irq,
395 ps2port->port->phys);
396
397 serio_register_port(ps2port->port);
398
399 return 0;
400
401fail:
402 free_irq(dev->irq, ps2port);
403
404fail_miserably:
405 list_del(&ps2port->node);
406 iounmap(ps2port->addr);
407 release_mem_region(dev->hpa, GSC_STATUS + 4);
408
409fail_nomem:
410 kfree(ps2port);
411 kfree(serio);
412 return ret;
413}
414
415/**
416 * gscps2_remove() - Removes PS2 devices
417 * @return: success/error report
418 */
419
420static int __devexit gscps2_remove(struct parisc_device *dev)
421{
422 struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
423
424 serio_unregister_port(ps2port->port);
425 free_irq(dev->irq, ps2port);
426 gscps2_flush(ps2port);
427 list_del(&ps2port->node);
428 iounmap(ps2port->addr);
429#if 0
430 release_mem_region(dev->hpa, GSC_STATUS + 4);
431#endif
432 dev_set_drvdata(&dev->dev, NULL);
433 kfree(ps2port);
434 return 0;
435}
436
437
438static struct parisc_device_id gscps2_device_tbl[] = {
439 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
440#ifdef DINO_TESTED
441 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
442#endif
443 { 0, } /* 0 terminated list */
444};
445
446static struct parisc_driver parisc_ps2_driver = {
447 .name = "GSC PS2",
448 .id_table = gscps2_device_tbl,
449 .probe = gscps2_probe,
450 .remove = gscps2_remove,
451};
452
453static int __init gscps2_init(void)
454{
455 register_parisc_driver(&parisc_ps2_driver);
456 return 0;
457}
458
459static void __exit gscps2_exit(void)
460{
461 unregister_parisc_driver(&parisc_ps2_driver);
462}
463
464
465module_init(gscps2_init);
466module_exit(gscps2_exit);
467
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
new file mode 100644
index 000000000000..c243cb6fdfc4
--- /dev/null
+++ b/drivers/input/serio/hil_mlc.c
@@ -0,0 +1,949 @@
1/*
2 * HIL MLC state machine and serio interface driver
3 *
4 * Copyright (c) 2001 Brian S. Julin
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 *
29 * References:
30 * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
31 *
32 *
33 * Driver theory of operation:
34 *
35 * Some access methods and an ISR is defined by the sub-driver
36 * (e.g. hp_sdc_mlc.c). These methods are expected to provide a
37 * few bits of logic in addition to raw access to the HIL MLC,
38 * specifically, the ISR, which is entirely registered by the
39 * sub-driver and invoked directly, must check for record
40 * termination or packet match, at which point a semaphore must
41 * be cleared and then the hil_mlcs_tasklet must be scheduled.
42 *
43 * The hil_mlcs_tasklet processes the state machine for all MLCs
44 * each time it runs, checking each MLC's progress at the current
45 * node in the state machine, and moving the MLC to subsequent nodes
46 * in the state machine when appropriate. It will reschedule
47 * itself if output is pending. (This rescheduling should be replaced
48 * at some point with a sub-driver-specific mechanism.)
49 *
50 * A timer task prods the tasklet once per second to prevent
51 * hangups when attached devices do not return expected data
52 * and to initiate probes of the loop for new devices.
53 */
54
55#include <linux/hil_mlc.h>
56#include <linux/errno.h>
57#include <linux/kernel.h>
58#include <linux/module.h>
59#include <linux/init.h>
60#include <linux/interrupt.h>
61#include <linux/timer.h>
62#include <linux/sched.h>
63#include <linux/list.h>
64
65MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
66MODULE_DESCRIPTION("HIL MLC serio");
67MODULE_LICENSE("Dual BSD/GPL");
68
69EXPORT_SYMBOL(hil_mlc_register);
70EXPORT_SYMBOL(hil_mlc_unregister);
71
72#define PREFIX "HIL MLC: "
73
74static LIST_HEAD(hil_mlcs);
75static DEFINE_RWLOCK(hil_mlcs_lock);
76static struct timer_list hil_mlcs_kicker;
77static int hil_mlcs_probe;
78
79static void hil_mlcs_process(unsigned long unused);
80DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
81
82
83/* #define HIL_MLC_DEBUG */
84
85/********************** Device info/instance management **********************/
86
87static void hil_mlc_clear_di_map (hil_mlc *mlc, int val) {
88 int j;
89 for (j = val; j < 7 ; j++) {
90 mlc->di_map[j] = -1;
91 }
92}
93
94static void hil_mlc_clear_di_scratch (hil_mlc *mlc) {
95 memset(&(mlc->di_scratch), 0, sizeof(mlc->di_scratch));
96}
97
98static void hil_mlc_copy_di_scratch (hil_mlc *mlc, int idx) {
99 memcpy(&(mlc->di[idx]), &(mlc->di_scratch), sizeof(mlc->di_scratch));
100}
101
102static int hil_mlc_match_di_scratch (hil_mlc *mlc) {
103 int idx;
104
105 for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) {
106 int j, found;
107
108 /* In-use slots are not eligible. */
109 found = 0;
110 for (j = 0; j < 7 ; j++) {
111 if (mlc->di_map[j] == idx) found++;
112 }
113 if (found) continue;
114 if (!memcmp(mlc->di + idx,
115 &(mlc->di_scratch),
116 sizeof(mlc->di_scratch))) break;
117 }
118 return((idx >= HIL_MLC_DEVMEM) ? -1 : idx);
119}
120
121static int hil_mlc_find_free_di(hil_mlc *mlc) {
122 int idx;
123 /* TODO: Pick all-zero slots first, failing that,
124 * randomize the slot picked among those eligible.
125 */
126 for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) {
127 int j, found;
128 found = 0;
129 for (j = 0; j < 7 ; j++) {
130 if (mlc->di_map[j] == idx) found++;
131 }
132 if (!found) break;
133 }
134 return(idx); /* Note: It is guaranteed at least one above will match */
135}
136
137static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) {
138 int idx;
139 for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) {
140 int j, found;
141 found = 0;
142 for (j = 0; j < 7 ; j++) {
143 if (mlc->di_map[j] == idx) found++;
144 }
145 if (!found) mlc->serio_map[idx].di_revmap = -1;
146 }
147}
148
149static void hil_mlc_send_polls(hil_mlc *mlc) {
150 int did, i, cnt;
151 struct serio *serio;
152 struct serio_driver *drv;
153
154 i = cnt = 0;
155 did = (mlc->ipacket[0] & HIL_PKT_ADDR_MASK) >> 8;
156 serio = did ? mlc->serio[mlc->di_map[did - 1]] : NULL;
157 drv = (serio != NULL) ? serio->drv : NULL;
158
159 while (mlc->icount < 15 - i) {
160 hil_packet p;
161 p = mlc->ipacket[i];
162 if (did != (p & HIL_PKT_ADDR_MASK) >> 8) {
163 if (drv == NULL || drv->interrupt == NULL) goto skip;
164
165 drv->interrupt(serio, 0, 0, NULL);
166 drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
167 drv->interrupt(serio, HIL_PKT_CMD >> 8, 0, NULL);
168 drv->interrupt(serio, HIL_CMD_POL + cnt, 0, NULL);
169 skip:
170 did = (p & HIL_PKT_ADDR_MASK) >> 8;
171 serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL;
172 drv = (serio != NULL) ? serio->drv : NULL;
173 cnt = 0;
174 }
175 cnt++; i++;
176 if (drv == NULL || drv->interrupt == NULL) continue;
177 drv->interrupt(serio, (p >> 24), 0, NULL);
178 drv->interrupt(serio, (p >> 16) & 0xff, 0, NULL);
179 drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0, NULL);
180 drv->interrupt(serio, p & 0xff, 0, NULL);
181 }
182}
183
184/*************************** State engine *********************************/
185
186#define HILSEN_SCHED 0x000100 /* Schedule the tasklet */
187#define HILSEN_BREAK 0x000200 /* Wait until next pass */
188#define HILSEN_UP 0x000400 /* relative node#, decrement */
189#define HILSEN_DOWN 0x000800 /* relative node#, increment */
190#define HILSEN_FOLLOW 0x001000 /* use retval as next node# */
191
192#define HILSEN_MASK 0x0000ff
193#define HILSEN_START 0
194#define HILSEN_RESTART 1
195#define HILSEN_DHR 9
196#define HILSEN_DHR2 10
197#define HILSEN_IFC 14
198#define HILSEN_HEAL0 16
199#define HILSEN_HEAL 18
200#define HILSEN_ACF 21
201#define HILSEN_ACF2 22
202#define HILSEN_DISC0 25
203#define HILSEN_DISC 27
204#define HILSEN_MATCH 40
205#define HILSEN_OPERATE 41
206#define HILSEN_PROBE 44
207#define HILSEN_DSR 52
208#define HILSEN_REPOLL 55
209#define HILSEN_IFCACF 58
210#define HILSEN_END 60
211
212#define HILSEN_NEXT (HILSEN_DOWN | 1)
213#define HILSEN_SAME (HILSEN_DOWN | 0)
214#define HILSEN_LAST (HILSEN_UP | 1)
215
216#define HILSEN_DOZE (HILSEN_SAME | HILSEN_SCHED | HILSEN_BREAK)
217#define HILSEN_SLEEP (HILSEN_SAME | HILSEN_BREAK)
218
219static int hilse_match(hil_mlc *mlc, int unused) {
220 int rc;
221 rc = hil_mlc_match_di_scratch(mlc);
222 if (rc == -1) {
223 rc = hil_mlc_find_free_di(mlc);
224 if (rc == -1) goto err;
225#ifdef HIL_MLC_DEBUG
226 printk(KERN_DEBUG PREFIX "new in slot %i\n", rc);
227#endif
228 hil_mlc_copy_di_scratch(mlc, rc);
229 mlc->di_map[mlc->ddi] = rc;
230 mlc->serio_map[rc].di_revmap = mlc->ddi;
231 hil_mlc_clean_serio_map(mlc);
232 serio_rescan(mlc->serio[rc]);
233 return -1;
234 }
235 mlc->di_map[mlc->ddi] = rc;
236#ifdef HIL_MLC_DEBUG
237 printk(KERN_DEBUG PREFIX "same in slot %i\n", rc);
238#endif
239 mlc->serio_map[rc].di_revmap = mlc->ddi;
240 hil_mlc_clean_serio_map(mlc);
241 return 0;
242 err:
243 printk(KERN_ERR PREFIX "Residual device slots exhausted, close some serios!\n");
244 return 1;
245}
246
247/* An LCV used to prevent runaway loops, forces 5 second sleep when reset. */
248static int hilse_init_lcv(hil_mlc *mlc, int unused) {
249 struct timeval tv;
250
251 do_gettimeofday(&tv);
252
253 if(mlc->lcv == 0) goto restart; /* First init, no need to dally */
254 if(tv.tv_sec - mlc->lcv_tv.tv_sec < 5) return -1;
255 restart:
256 mlc->lcv_tv = tv;
257 mlc->lcv = 0;
258 return 0;
259}
260
261static int hilse_inc_lcv(hil_mlc *mlc, int lim) {
262 if (mlc->lcv++ >= lim) return -1;
263 return 0;
264}
265
266#if 0
267static int hilse_set_lcv(hil_mlc *mlc, int val) {
268 mlc->lcv = val;
269 return 0;
270}
271#endif
272
273/* Management of the discovered device index (zero based, -1 means no devs) */
274static int hilse_set_ddi(hil_mlc *mlc, int val) {
275 mlc->ddi = val;
276 hil_mlc_clear_di_map(mlc, val + 1);
277 return 0;
278}
279
280static int hilse_dec_ddi(hil_mlc *mlc, int unused) {
281 mlc->ddi--;
282 if (mlc->ddi <= -1) {
283 mlc->ddi = -1;
284 hil_mlc_clear_di_map(mlc, 0);
285 return -1;
286 }
287 hil_mlc_clear_di_map(mlc, mlc->ddi + 1);
288 return 0;
289}
290
291static int hilse_inc_ddi(hil_mlc *mlc, int unused) {
292 if (mlc->ddi >= 6) {
293 BUG();
294 return -1;
295 }
296 mlc->ddi++;
297 return 0;
298}
299
300static int hilse_take_idd(hil_mlc *mlc, int unused) {
301 int i;
302
303 /* Help the state engine:
304 * Is this a real IDD response or just an echo?
305 *
306 * Real IDD response does not start with a command.
307 */
308 if (mlc->ipacket[0] & HIL_PKT_CMD) goto bail;
309 /* Should have the command echoed further down. */
310 for (i = 1; i < 16; i++) {
311 if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) ==
312 (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) &&
313 (mlc->ipacket[i] & HIL_PKT_CMD) &&
314 ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD))
315 break;
316 }
317 if (i > 15) goto bail;
318 /* And the rest of the packets should still be clear. */
319 while (++i < 16) {
320 if (mlc->ipacket[i]) break;
321 }
322 if (i < 16) goto bail;
323 for (i = 0; i < 16; i++) {
324 mlc->di_scratch.idd[i] =
325 mlc->ipacket[i] & HIL_PKT_DATA_MASK;
326 }
327 /* Next step is to see if RSC supported */
328 if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC)
329 return HILSEN_NEXT;
330 if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD)
331 return HILSEN_DOWN | 4;
332 return 0;
333 bail:
334 mlc->ddi--;
335 return -1; /* This should send us off to ACF */
336}
337
338static int hilse_take_rsc(hil_mlc *mlc, int unused) {
339 int i;
340
341 for (i = 0; i < 16; i++) {
342 mlc->di_scratch.rsc[i] =
343 mlc->ipacket[i] & HIL_PKT_DATA_MASK;
344 }
345 /* Next step is to see if EXD supported (IDD has already been read) */
346 if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD)
347 return HILSEN_NEXT;
348 return 0;
349}
350
351static int hilse_take_exd(hil_mlc *mlc, int unused) {
352 int i;
353
354 for (i = 0; i < 16; i++) {
355 mlc->di_scratch.exd[i] =
356 mlc->ipacket[i] & HIL_PKT_DATA_MASK;
357 }
358 /* Next step is to see if RNM supported. */
359 if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM)
360 return HILSEN_NEXT;
361 return 0;
362}
363
364static int hilse_take_rnm(hil_mlc *mlc, int unused) {
365 int i;
366
367 for (i = 0; i < 16; i++) {
368 mlc->di_scratch.rnm[i] =
369 mlc->ipacket[i] & HIL_PKT_DATA_MASK;
370 }
371 do {
372 char nam[17];
373 snprintf(nam, 16, "%s", mlc->di_scratch.rnm);
374 nam[16] = '\0';
375 printk(KERN_INFO PREFIX "Device name gotten: %s\n", nam);
376 } while (0);
377 return 0;
378}
379
380static int hilse_operate(hil_mlc *mlc, int repoll) {
381
382 if (mlc->opercnt == 0) hil_mlcs_probe = 0;
383 mlc->opercnt = 1;
384
385 hil_mlc_send_polls(mlc);
386
387 if (!hil_mlcs_probe) return 0;
388 hil_mlcs_probe = 0;
389 mlc->opercnt = 0;
390 return 1;
391}
392
393#define FUNC(funct, funct_arg, zero_rc, neg_rc, pos_rc) \
394{ HILSE_FUNC, { func: &funct }, funct_arg, zero_rc, neg_rc, pos_rc },
395#define OUT(pack) \
396{ HILSE_OUT, { packet: pack }, 0, HILSEN_NEXT, HILSEN_DOZE, 0 },
397#define CTS \
398{ HILSE_CTS, { packet: 0 }, 0, HILSEN_NEXT | HILSEN_SCHED | HILSEN_BREAK, HILSEN_DOZE, 0 },
399#define EXPECT(comp, to, got, got_wrong, timed_out) \
400{ HILSE_EXPECT, { packet: comp }, to, got, got_wrong, timed_out },
401#define EXPECT_LAST(comp, to, got, got_wrong, timed_out) \
402{ HILSE_EXPECT_LAST, { packet: comp }, to, got, got_wrong, timed_out },
403#define EXPECT_DISC(comp, to, got, got_wrong, timed_out) \
404{ HILSE_EXPECT_DISC, { packet: comp }, to, got, got_wrong, timed_out },
405#define IN(to, got, got_error, timed_out) \
406{ HILSE_IN, { packet: 0 }, to, got, got_error, timed_out },
407#define OUT_DISC(pack) \
408{ HILSE_OUT_DISC, { packet: pack }, 0, 0, 0, 0 },
409#define OUT_LAST(pack) \
410{ HILSE_OUT_LAST, { packet: pack }, 0, 0, 0, 0 },
411
412struct hilse_node hil_mlc_se[HILSEN_END] = {
413
414 /* 0 HILSEN_START */
415 FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0)
416
417 /* 1 HILSEN_RESTART */
418 FUNC(hilse_inc_lcv, 10, HILSEN_NEXT, HILSEN_START, 0)
419 OUT(HIL_CTRL_ONLY) /* Disable APE */
420 CTS
421
422#define TEST_PACKET(x) \
423(HIL_PKT_CMD | (x << HIL_PKT_ADDR_SHIFT) | x << 4 | x)
424
425 OUT(HIL_DO_ALTER_CTRL | HIL_CTRL_TEST | TEST_PACKET(0x5))
426 EXPECT(HIL_ERR_INT | TEST_PACKET(0x5),
427 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART)
428 OUT(HIL_DO_ALTER_CTRL | HIL_CTRL_TEST | TEST_PACKET(0xa))
429 EXPECT(HIL_ERR_INT | TEST_PACKET(0xa),
430 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART)
431 OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */
432
433 /* 9 HILSEN_DHR */
434 FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0)
435
436 /* 10 HILSEN_DHR2 */
437 FUNC(hilse_inc_lcv, 10, HILSEN_NEXT, HILSEN_START, 0)
438 FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0)
439 OUT(HIL_PKT_CMD | HIL_CMD_DHR)
440 IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT)
441
442 /* 14 HILSEN_IFC */
443 OUT(HIL_PKT_CMD | HIL_CMD_IFC)
444 EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT,
445 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT )
446
447 /* If devices are there, they weren't in PUP or other loopback mode.
448 * We're more concerned at this point with restoring operation
449 * to devices than discovering new ones, so we try to salvage
450 * the loop configuration by closing off the loop.
451 */
452
453 /* 16 HILSEN_HEAL0 */
454 FUNC(hilse_dec_ddi, 0, HILSEN_NEXT, HILSEN_ACF, 0)
455 FUNC(hilse_inc_ddi, 0, HILSEN_NEXT, 0, 0)
456
457 /* 18 HILSEN_HEAL */
458 OUT_LAST(HIL_CMD_ELB)
459 EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT,
460 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT)
461 FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0)
462
463 /* 21 HILSEN_ACF */
464 FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_DOZE, 0)
465
466 /* 22 HILSEN_ACF2 */
467 FUNC(hilse_inc_lcv, 10, HILSEN_NEXT, HILSEN_START, 0)
468 OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1)
469 IN(20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_NEXT)
470
471 /* 25 HILSEN_DISC0 */
472 OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB)
473 EXPECT_DISC(HIL_PKT_CMD | HIL_CMD_ELB | HIL_ERR_INT,
474 20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_DSR)
475
476 /* Only enter here if response just received */
477 /* 27 HILSEN_DISC */
478 OUT_DISC(HIL_PKT_CMD | HIL_CMD_IDD)
479 EXPECT_DISC(HIL_PKT_CMD | HIL_CMD_IDD | HIL_ERR_INT,
480 20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_START)
481 FUNC(hilse_inc_ddi, 0, HILSEN_NEXT, HILSEN_START, 0)
482 FUNC(hilse_take_idd, 0, HILSEN_MATCH, HILSEN_IFCACF, HILSEN_FOLLOW)
483 OUT_LAST(HIL_PKT_CMD | HIL_CMD_RSC)
484 EXPECT_LAST(HIL_PKT_CMD | HIL_CMD_RSC | HIL_ERR_INT,
485 30000, HILSEN_NEXT, HILSEN_DSR, HILSEN_DSR)
486 FUNC(hilse_take_rsc, 0, HILSEN_MATCH, 0, HILSEN_FOLLOW)
487 OUT_LAST(HIL_PKT_CMD | HIL_CMD_EXD)
488 EXPECT_LAST(HIL_PKT_CMD | HIL_CMD_EXD | HIL_ERR_INT,
489 30000, HILSEN_NEXT, HILSEN_DSR, HILSEN_DSR)
490 FUNC(hilse_take_exd, 0, HILSEN_MATCH, 0, HILSEN_FOLLOW)
491 OUT_LAST(HIL_PKT_CMD | HIL_CMD_RNM)
492 EXPECT_LAST(HIL_PKT_CMD | HIL_CMD_RNM | HIL_ERR_INT,
493 30000, HILSEN_NEXT, HILSEN_DSR, HILSEN_DSR)
494 FUNC(hilse_take_rnm, 0, HILSEN_MATCH, 0, 0)
495
496 /* 40 HILSEN_MATCH */
497 FUNC(hilse_match, 0, HILSEN_NEXT, HILSEN_NEXT, /* TODO */ 0)
498
499 /* 41 HILSEN_OPERATE */
500 OUT(HIL_PKT_CMD | HIL_CMD_POL)
501 EXPECT(HIL_PKT_CMD | HIL_CMD_POL | HIL_ERR_INT,
502 20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_NEXT)
503 FUNC(hilse_operate, 0, HILSEN_OPERATE, HILSEN_IFC, HILSEN_NEXT)
504
505 /* 44 HILSEN_PROBE */
506 OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT)
507 IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT)
508 OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB)
509 IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT)
510 OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1)
511 IN(10000, HILSEN_DISC0, HILSEN_DSR, HILSEN_NEXT)
512 OUT_LAST(HIL_PKT_CMD | HIL_CMD_ELB)
513 IN(10000, HILSEN_OPERATE, HILSEN_DSR, HILSEN_DSR)
514
515 /* 52 HILSEN_DSR */
516 FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0)
517 OUT(HIL_PKT_CMD | HIL_CMD_DSR)
518 IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC)
519
520 /* 55 HILSEN_REPOLL */
521 OUT(HIL_PKT_CMD | HIL_CMD_RPL)
522 EXPECT(HIL_PKT_CMD | HIL_CMD_RPL | HIL_ERR_INT,
523 20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_NEXT)
524 FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE)
525
526 /* 58 HILSEN_IFCACF */
527 OUT(HIL_PKT_CMD | HIL_CMD_IFC)
528 EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT,
529 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL)
530
531 /* 60 HILSEN_END */
532};
533
534static inline void hilse_setup_input(hil_mlc *mlc, struct hilse_node *node) {
535
536 switch (node->act) {
537 case HILSE_EXPECT_DISC:
538 mlc->imatch = node->object.packet;
539 mlc->imatch |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT);
540 break;
541 case HILSE_EXPECT_LAST:
542 mlc->imatch = node->object.packet;
543 mlc->imatch |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT);
544 break;
545 case HILSE_EXPECT:
546 mlc->imatch = node->object.packet;
547 break;
548 case HILSE_IN:
549 mlc->imatch = 0;
550 break;
551 default:
552 BUG();
553 }
554 mlc->istarted = 1;
555 mlc->intimeout = node->arg;
556 do_gettimeofday(&(mlc->instart));
557 mlc->icount = 15;
558 memset(mlc->ipacket, 0, 16 * sizeof(hil_packet));
559 if (down_trylock(&(mlc->isem))) BUG();
560
561 return;
562}
563
564#ifdef HIL_MLC_DEBUG
565static int doze = 0;
566static int seidx; /* For debug */
567static int kick = 1;
568#endif
569
570static int hilse_donode (hil_mlc *mlc) {
571 struct hilse_node *node;
572 int nextidx = 0;
573 int sched_long = 0;
574 unsigned long flags;
575
576#ifdef HIL_MLC_DEBUG
577 if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) {
578 printk(KERN_DEBUG PREFIX "z%i \n%s {%i}", doze, kick ? "K" : "", mlc->seidx);
579 doze = 0;
580 }
581 kick = 0;
582
583 seidx = mlc->seidx;
584#endif
585 node = hil_mlc_se + mlc->seidx;
586
587 switch (node->act) {
588 int rc;
589 hil_packet pack;
590
591 case HILSE_FUNC:
592 if (node->object.func == NULL) break;
593 rc = node->object.func(mlc, node->arg);
594 nextidx = (rc > 0) ? node->ugly :
595 ((rc < 0) ? node->bad : node->good);
596 if (nextidx == HILSEN_FOLLOW) nextidx = rc;
597 break;
598 case HILSE_EXPECT_LAST:
599 case HILSE_EXPECT_DISC:
600 case HILSE_EXPECT:
601 case HILSE_IN:
602 /* Already set up from previous HILSE_OUT_* */
603 write_lock_irqsave(&(mlc->lock), flags);
604 rc = mlc->in(mlc, node->arg);
605 if (rc == 2) {
606 nextidx = HILSEN_DOZE;
607 sched_long = 1;
608 write_unlock_irqrestore(&(mlc->lock), flags);
609 break;
610 }
611 if (rc == 1) nextidx = node->ugly;
612 else if (rc == 0) nextidx = node->good;
613 else nextidx = node->bad;
614 mlc->istarted = 0;
615 write_unlock_irqrestore(&(mlc->lock), flags);
616 break;
617 case HILSE_OUT_LAST:
618 write_lock_irqsave(&(mlc->lock), flags);
619 pack = node->object.packet;
620 pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT);
621 goto out;
622 case HILSE_OUT_DISC:
623 write_lock_irqsave(&(mlc->lock), flags);
624 pack = node->object.packet;
625 pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT);
626 goto out;
627 case HILSE_OUT:
628 write_lock_irqsave(&(mlc->lock), flags);
629 pack = node->object.packet;
630 out:
631 if (mlc->istarted) goto out2;
632 /* Prepare to receive input */
633 if ((node + 1)->act & HILSE_IN)
634 hilse_setup_input(mlc, node + 1);
635
636 out2:
637 write_unlock_irqrestore(&(mlc->lock), flags);
638
639 if (down_trylock(&mlc->osem)) {
640 nextidx = HILSEN_DOZE;
641 break;
642 }
643 up(&mlc->osem);
644
645 write_lock_irqsave(&(mlc->lock), flags);
646 if (!(mlc->ostarted)) {
647 mlc->ostarted = 1;
648 mlc->opacket = pack;
649 mlc->out(mlc);
650 nextidx = HILSEN_DOZE;
651 write_unlock_irqrestore(&(mlc->lock), flags);
652 break;
653 }
654 mlc->ostarted = 0;
655 do_gettimeofday(&(mlc->instart));
656 write_unlock_irqrestore(&(mlc->lock), flags);
657 nextidx = HILSEN_NEXT;
658 break;
659 case HILSE_CTS:
660 nextidx = mlc->cts(mlc) ? node->bad : node->good;
661 break;
662 default:
663 BUG();
664 nextidx = 0;
665 break;
666 }
667
668#ifdef HIL_MLC_DEBUG
669 if (nextidx == HILSEN_DOZE) doze++;
670#endif
671
672 while (nextidx & HILSEN_SCHED) {
673 struct timeval tv;
674
675 if (!sched_long) goto sched;
676
677 do_gettimeofday(&tv);
678 tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec);
679 tv.tv_usec -= mlc->instart.tv_usec;
680 if (tv.tv_usec >= mlc->intimeout) goto sched;
681 tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / 1000000;
682 if (!tv.tv_usec) goto sched;
683 mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec);
684 break;
685 sched:
686 tasklet_schedule(&hil_mlcs_tasklet);
687 break;
688 }
689 if (nextidx & HILSEN_DOWN) mlc->seidx += nextidx & HILSEN_MASK;
690 else if (nextidx & HILSEN_UP) mlc->seidx -= nextidx & HILSEN_MASK;
691 else mlc->seidx = nextidx & HILSEN_MASK;
692
693 if (nextidx & HILSEN_BREAK) return 1;
694 return 0;
695}
696
697/******************** tasklet context functions **************************/
698static void hil_mlcs_process(unsigned long unused) {
699 struct list_head *tmp;
700
701 read_lock(&hil_mlcs_lock);
702 list_for_each(tmp, &hil_mlcs) {
703 struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list);
704 while (hilse_donode(mlc) == 0) {
705#ifdef HIL_MLC_DEBUG
706 if (mlc->seidx != 41 &&
707 mlc->seidx != 42 &&
708 mlc->seidx != 43)
709 printk(KERN_DEBUG PREFIX " + ");
710#endif
711 };
712 }
713 read_unlock(&hil_mlcs_lock);
714}
715
716/************************* Keepalive timer task *********************/
717
718void hil_mlcs_timer (unsigned long data) {
719 hil_mlcs_probe = 1;
720 tasklet_schedule(&hil_mlcs_tasklet);
721 /* Re-insert the periodic task. */
722 if (!timer_pending(&hil_mlcs_kicker))
723 mod_timer(&hil_mlcs_kicker, jiffies + HZ);
724}
725
726/******************** user/kernel context functions **********************/
727
728static int hil_mlc_serio_write(struct serio *serio, unsigned char c) {
729 struct hil_mlc_serio_map *map;
730 struct hil_mlc *mlc;
731 struct serio_driver *drv;
732 uint8_t *idx, *last;
733
734 map = serio->port_data;
735 if (map == NULL) {
736 BUG();
737 return -EIO;
738 }
739 mlc = map->mlc;
740 if (mlc == NULL) {
741 BUG();
742 return -EIO;
743 }
744 mlc->serio_opacket[map->didx] |=
745 ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx]));
746
747 if (mlc->serio_oidx[map->didx] >= 3) {
748 /* for now only commands */
749 if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD))
750 return -EIO;
751 switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) {
752 case HIL_CMD_IDD:
753 idx = mlc->di[map->didx].idd;
754 goto emu;
755 case HIL_CMD_RSC:
756 idx = mlc->di[map->didx].rsc;
757 goto emu;
758 case HIL_CMD_EXD:
759 idx = mlc->di[map->didx].exd;
760 goto emu;
761 case HIL_CMD_RNM:
762 idx = mlc->di[map->didx].rnm;
763 goto emu;
764 default:
765 break;
766 }
767 mlc->serio_oidx[map->didx] = 0;
768 mlc->serio_opacket[map->didx] = 0;
769 }
770
771 mlc->serio_oidx[map->didx]++;
772 return -EIO;
773 emu:
774 drv = serio->drv;
775 if (drv == NULL) {
776 BUG();
777 return -EIO;
778 }
779 last = idx + 15;
780 while ((last != idx) && (*last == 0)) last--;
781
782 while (idx != last) {
783 drv->interrupt(serio, 0, 0, NULL);
784 drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
785 drv->interrupt(serio, 0, 0, NULL);
786 drv->interrupt(serio, *idx, 0, NULL);
787 idx++;
788 }
789 drv->interrupt(serio, 0, 0, NULL);
790 drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
791 drv->interrupt(serio, HIL_PKT_CMD >> 8, 0, NULL);
792 drv->interrupt(serio, *idx, 0, NULL);
793
794 mlc->serio_oidx[map->didx] = 0;
795 mlc->serio_opacket[map->didx] = 0;
796
797 return 0;
798}
799
800static int hil_mlc_serio_open(struct serio *serio) {
801 struct hil_mlc_serio_map *map;
802 struct hil_mlc *mlc;
803
804 if (serio->private != NULL) return -EBUSY;
805
806 map = serio->port_data;
807 if (map == NULL) {
808 BUG();
809 return -ENODEV;
810 }
811 mlc = map->mlc;
812 if (mlc == NULL) {
813 BUG();
814 return -ENODEV;
815 }
816
817 return 0;
818}
819
820static void hil_mlc_serio_close(struct serio *serio) {
821 struct hil_mlc_serio_map *map;
822 struct hil_mlc *mlc;
823
824 map = serio->port_data;
825 if (map == NULL) {
826 BUG();
827 return;
828 }
829 mlc = map->mlc;
830 if (mlc == NULL) {
831 BUG();
832 return;
833 }
834
835 serio->private = NULL;
836 serio->drv = NULL;
837 /* TODO wake up interruptable */
838}
839
840int hil_mlc_register(hil_mlc *mlc) {
841 int i;
842 unsigned long flags;
843
844 if (mlc == NULL) {
845 return -EINVAL;
846 }
847
848 mlc->istarted = 0;
849 mlc->ostarted = 0;
850
851 rwlock_init(&mlc->lock);
852 init_MUTEX(&(mlc->osem));
853
854 init_MUTEX(&(mlc->isem));
855 mlc->icount = -1;
856 mlc->imatch = 0;
857
858 mlc->opercnt = 0;
859
860 init_MUTEX_LOCKED(&(mlc->csem));
861
862 hil_mlc_clear_di_scratch(mlc);
863 hil_mlc_clear_di_map(mlc, 0);
864 for (i = 0; i < HIL_MLC_DEVMEM; i++) {
865 struct serio *mlc_serio;
866 hil_mlc_copy_di_scratch(mlc, i);
867 mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL);
868 mlc->serio[i] = mlc_serio;
869 memset(mlc_serio, 0, sizeof(*mlc_serio));
870 mlc_serio->type = SERIO_HIL | SERIO_HIL_MLC;
871 mlc_serio->write = hil_mlc_serio_write;
872 mlc_serio->open = hil_mlc_serio_open;
873 mlc_serio->close = hil_mlc_serio_close;
874 mlc_serio->port_data = &(mlc->serio_map[i]);
875 mlc->serio_map[i].mlc = mlc;
876 mlc->serio_map[i].didx = i;
877 mlc->serio_map[i].di_revmap = -1;
878 mlc->serio_opacket[i] = 0;
879 mlc->serio_oidx[i] = 0;
880 serio_register_port(mlc_serio);
881 }
882
883 mlc->tasklet = &hil_mlcs_tasklet;
884
885 write_lock_irqsave(&hil_mlcs_lock, flags);
886 list_add_tail(&mlc->list, &hil_mlcs);
887 mlc->seidx = HILSEN_START;
888 write_unlock_irqrestore(&hil_mlcs_lock, flags);
889
890 tasklet_schedule(&hil_mlcs_tasklet);
891 return 0;
892}
893
894int hil_mlc_unregister(hil_mlc *mlc) {
895 struct list_head *tmp;
896 unsigned long flags;
897 int i;
898
899 if (mlc == NULL)
900 return -EINVAL;
901
902 write_lock_irqsave(&hil_mlcs_lock, flags);
903 list_for_each(tmp, &hil_mlcs) {
904 if (list_entry(tmp, hil_mlc, list) == mlc)
905 goto found;
906 }
907
908 /* not found in list */
909 write_unlock_irqrestore(&hil_mlcs_lock, flags);
910 tasklet_schedule(&hil_mlcs_tasklet);
911 return -ENODEV;
912
913 found:
914 list_del(tmp);
915 write_unlock_irqrestore(&hil_mlcs_lock, flags);
916
917 for (i = 0; i < HIL_MLC_DEVMEM; i++) {
918 serio_unregister_port(mlc->serio[i]);
919 mlc->serio[i] = NULL;
920 }
921
922 tasklet_schedule(&hil_mlcs_tasklet);
923 return 0;
924}
925
926/**************************** Module interface *************************/
927
928static int __init hil_mlc_init(void)
929{
930 init_timer(&hil_mlcs_kicker);
931 hil_mlcs_kicker.expires = jiffies + HZ;
932 hil_mlcs_kicker.function = &hil_mlcs_timer;
933 add_timer(&hil_mlcs_kicker);
934
935 tasklet_enable(&hil_mlcs_tasklet);
936
937 return 0;
938}
939
940static void __exit hil_mlc_exit(void)
941{
942 del_timer(&hil_mlcs_kicker);
943
944 tasklet_disable(&hil_mlcs_tasklet);
945 tasklet_kill(&hil_mlcs_tasklet);
946}
947
948module_init(hil_mlc_init);
949module_exit(hil_mlc_exit);
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
new file mode 100644
index 000000000000..7629452dd64b
--- /dev/null
+++ b/drivers/input/serio/hp_sdc.c
@@ -0,0 +1,1054 @@
1/*
2 * HP i8042-based System Device Controller driver.
3 *
4 * Copyright (c) 2001 Brian S. Julin
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 *
29 * References:
30 * System Device Controller Microprocessor Firmware Theory of Operation
31 * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
32 * Helge Deller's original hilkbd.c port for PA-RISC.
33 *
34 *
35 * Driver theory of operation:
36 *
37 * hp_sdc_put does all writing to the SDC. ISR can run on a different
38 * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time
39 * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly.
40 *
41 * All data coming back from the SDC is sent via interrupt and can be read
42 * fully in the ISR, so there are no latency/throughput problems there.
43 * The problem is with output, due to the slow clock speed of the SDC
44 * compared to the CPU. This should not be too horrible most of the time,
45 * but if used with HIL devices that support the multibyte transfer command,
46 * keeping outbound throughput flowing at the 6500KBps that the HIL is
47 * capable of is more than can be done at HZ=100.
48 *
49 * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf
50 * is set to 0 when the IBF flag in the status register has cleared. ISR
51 * may do this, and may also access the parts of queued transactions related
52 * to reading data back from the SDC, but otherwise will not touch the
53 * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1.
54 *
55 * The i8042 write index and the values in the 4-byte input buffer
56 * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively,
57 * to minimize the amount of IO needed to the SDC. However these values
58 * do not need to be locked since they are only ever accessed by hp_sdc_put.
59 *
60 * A timer task schedules the tasklet once per second just to make
61 * sure it doesn't freeze up and to allow for bad reads to time out.
62 */
63
64#include <linux/hp_sdc.h>
65#include <linux/sched.h>
66#include <linux/errno.h>
67#include <linux/init.h>
68#include <linux/module.h>
69#include <linux/ioport.h>
70#include <linux/time.h>
71#include <linux/slab.h>
72#include <linux/hil.h>
73#include <asm/io.h>
74#include <asm/system.h>
75
76/* Machine-specific abstraction */
77
78#if defined(__hppa__)
79# include <asm/parisc-device.h>
80# define sdc_readb(p) gsc_readb(p)
81# define sdc_writeb(v,p) gsc_writeb((v),(p))
82#elif defined(__mc68000__)
83# include <asm/uaccess.h>
84# define sdc_readb(p) in_8(p)
85# define sdc_writeb(v,p) out_8((p),(v))
86#else
87# error "HIL is not supported on this platform"
88#endif
89
90#define PREFIX "HP SDC: "
91
92MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
93MODULE_DESCRIPTION("HP i8042-based SDC Driver");
94MODULE_LICENSE("Dual BSD/GPL");
95
96EXPORT_SYMBOL(hp_sdc_request_timer_irq);
97EXPORT_SYMBOL(hp_sdc_request_hil_irq);
98EXPORT_SYMBOL(hp_sdc_request_cooked_irq);
99
100EXPORT_SYMBOL(hp_sdc_release_timer_irq);
101EXPORT_SYMBOL(hp_sdc_release_hil_irq);
102EXPORT_SYMBOL(hp_sdc_release_cooked_irq);
103
104EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
105EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
106
107static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */
108
109/*************** primitives for use in any context *********************/
110static inline uint8_t hp_sdc_status_in8 (void) {
111 uint8_t status;
112 unsigned long flags;
113
114 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
115 status = sdc_readb(hp_sdc.status_io);
116 if (!(status & HP_SDC_STATUS_IBF)) hp_sdc.ibf = 0;
117 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
118
119 return status;
120}
121
122static inline uint8_t hp_sdc_data_in8 (void) {
123 return sdc_readb(hp_sdc.data_io);
124}
125
126static inline void hp_sdc_status_out8 (uint8_t val) {
127 unsigned long flags;
128
129 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
130 hp_sdc.ibf = 1;
131 if ((val & 0xf0) == 0xe0) hp_sdc.wi = 0xff;
132 sdc_writeb(val, hp_sdc.status_io);
133 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
134}
135
136static inline void hp_sdc_data_out8 (uint8_t val) {
137 unsigned long flags;
138
139 write_lock_irqsave(&hp_sdc.ibf_lock, flags);
140 hp_sdc.ibf = 1;
141 sdc_writeb(val, hp_sdc.data_io);
142 write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
143}
144
145/* Care must be taken to only invoke hp_sdc_spin_ibf when
146 * absolutely needed, or in rarely invoked subroutines.
147 * Not only does it waste CPU cycles, it also wastes bus cycles.
148 */
149static inline void hp_sdc_spin_ibf(void) {
150 unsigned long flags;
151 rwlock_t *lock;
152
153 lock = &hp_sdc.ibf_lock;
154
155 read_lock_irqsave(lock, flags);
156 if (!hp_sdc.ibf) {
157 read_unlock_irqrestore(lock, flags);
158 return;
159 }
160 read_unlock(lock);
161 write_lock(lock);
162 while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) {};
163 hp_sdc.ibf = 0;
164 write_unlock_irqrestore(lock, flags);
165}
166
167
168/************************ Interrupt context functions ************************/
169static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) {
170 hp_sdc_transaction *curr;
171
172 read_lock(&hp_sdc.rtq_lock);
173 if (hp_sdc.rcurr < 0) {
174 read_unlock(&hp_sdc.rtq_lock);
175 return;
176 }
177 curr = hp_sdc.tq[hp_sdc.rcurr];
178 read_unlock(&hp_sdc.rtq_lock);
179
180 curr->seq[curr->idx++] = status;
181 curr->seq[curr->idx++] = data;
182 hp_sdc.rqty -= 2;
183 do_gettimeofday(&hp_sdc.rtv);
184
185 if (hp_sdc.rqty <= 0) {
186 /* All data has been gathered. */
187 if(curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) {
188 if (curr->act.semaphore) up(curr->act.semaphore);
189 }
190 if(curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) {
191 if (curr->act.irqhook)
192 curr->act.irqhook(irq, dev_id, status, data);
193 }
194 curr->actidx = curr->idx;
195 curr->idx++;
196 /* Return control of this transaction */
197 write_lock(&hp_sdc.rtq_lock);
198 hp_sdc.rcurr = -1;
199 hp_sdc.rqty = 0;
200 write_unlock(&hp_sdc.rtq_lock);
201 tasklet_schedule(&hp_sdc.task);
202 }
203}
204
205static irqreturn_t hp_sdc_isr(int irq, void *dev_id, struct pt_regs * regs) {
206 uint8_t status, data;
207
208 status = hp_sdc_status_in8();
209 /* Read data unconditionally to advance i8042. */
210 data = hp_sdc_data_in8();
211
212 /* For now we are ignoring these until we get the SDC to behave. */
213 if (((status & 0xf1) == 0x51) && data == 0x82) {
214 return IRQ_HANDLED;
215 }
216
217 switch(status & HP_SDC_STATUS_IRQMASK) {
218 case 0: /* This case is not documented. */
219 break;
220 case HP_SDC_STATUS_USERTIMER:
221 case HP_SDC_STATUS_PERIODIC:
222 case HP_SDC_STATUS_TIMER:
223 read_lock(&hp_sdc.hook_lock);
224 if (hp_sdc.timer != NULL)
225 hp_sdc.timer(irq, dev_id, status, data);
226 read_unlock(&hp_sdc.hook_lock);
227 break;
228 case HP_SDC_STATUS_REG:
229 hp_sdc_take(irq, dev_id, status, data);
230 break;
231 case HP_SDC_STATUS_HILCMD:
232 case HP_SDC_STATUS_HILDATA:
233 read_lock(&hp_sdc.hook_lock);
234 if (hp_sdc.hil != NULL)
235 hp_sdc.hil(irq, dev_id, status, data);
236 read_unlock(&hp_sdc.hook_lock);
237 break;
238 case HP_SDC_STATUS_PUP:
239 read_lock(&hp_sdc.hook_lock);
240 if (hp_sdc.pup != NULL)
241 hp_sdc.pup(irq, dev_id, status, data);
242 else printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n");
243 read_unlock(&hp_sdc.hook_lock);
244 break;
245 default:
246 read_lock(&hp_sdc.hook_lock);
247 if (hp_sdc.cooked != NULL)
248 hp_sdc.cooked(irq, dev_id, status, data);
249 read_unlock(&hp_sdc.hook_lock);
250 break;
251 }
252 return IRQ_HANDLED;
253}
254
255
256static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id, struct pt_regs * regs) {
257 int status;
258
259 status = hp_sdc_status_in8();
260 printk(KERN_WARNING PREFIX "NMI !\n");
261
262#if 0
263 if (status & HP_SDC_NMISTATUS_FHS) {
264 read_lock(&hp_sdc.hook_lock);
265 if (hp_sdc.timer != NULL)
266 hp_sdc.timer(irq, dev_id, status, 0);
267 read_unlock(&hp_sdc.hook_lock);
268 }
269 else {
270 /* TODO: pass this on to the HIL handler, or do SAK here? */
271 printk(KERN_WARNING PREFIX "HIL NMI\n");
272 }
273#endif
274 return IRQ_HANDLED;
275}
276
277
278/***************** Kernel (tasklet) context functions ****************/
279
280unsigned long hp_sdc_put(void);
281
282static void hp_sdc_tasklet(unsigned long foo) {
283
284 write_lock_irq(&hp_sdc.rtq_lock);
285 if (hp_sdc.rcurr >= 0) {
286 struct timeval tv;
287 do_gettimeofday(&tv);
288 if (tv.tv_sec > hp_sdc.rtv.tv_sec) tv.tv_usec += 1000000;
289 if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) {
290 hp_sdc_transaction *curr;
291 uint8_t tmp;
292
293 curr = hp_sdc.tq[hp_sdc.rcurr];
294 /* If this turns out to be a normal failure mode
295 * we'll need to figure out a way to communicate
296 * it back to the application. and be less verbose.
297 */
298 printk(KERN_WARNING PREFIX "read timeout (%ius)!\n",
299 tv.tv_usec - hp_sdc.rtv.tv_usec);
300 curr->idx += hp_sdc.rqty;
301 hp_sdc.rqty = 0;
302 tmp = curr->seq[curr->actidx];
303 curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD;
304 if(tmp & HP_SDC_ACT_SEMAPHORE) {
305 if (curr->act.semaphore)
306 up(curr->act.semaphore);
307 }
308 if(tmp & HP_SDC_ACT_CALLBACK) {
309 /* Note this means that irqhooks may be called
310 * in tasklet/bh context.
311 */
312 if (curr->act.irqhook)
313 curr->act.irqhook(0, 0, 0, 0);
314 }
315 curr->actidx = curr->idx;
316 curr->idx++;
317 hp_sdc.rcurr = -1;
318 }
319 }
320 write_unlock_irq(&hp_sdc.rtq_lock);
321 hp_sdc_put();
322}
323
324unsigned long hp_sdc_put(void) {
325 hp_sdc_transaction *curr;
326 uint8_t act;
327 int idx, curridx;
328
329 int limit = 0;
330
331 write_lock(&hp_sdc.lock);
332
333 /* If i8042 buffers are full, we cannot do anything that
334 requires output, so we skip to the administrativa. */
335 if (hp_sdc.ibf) {
336 hp_sdc_status_in8();
337 if (hp_sdc.ibf) goto finish;
338 }
339
340 anew:
341 /* See if we are in the middle of a sequence. */
342 if (hp_sdc.wcurr < 0) hp_sdc.wcurr = 0;
343 read_lock_irq(&hp_sdc.rtq_lock);
344 if (hp_sdc.rcurr == hp_sdc.wcurr) hp_sdc.wcurr++;
345 read_unlock_irq(&hp_sdc.rtq_lock);
346 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
347 curridx = hp_sdc.wcurr;
348
349 if (hp_sdc.tq[curridx] != NULL) goto start;
350
351 while (++curridx != hp_sdc.wcurr) {
352 if (curridx >= HP_SDC_QUEUE_LEN) {
353 curridx = -1; /* Wrap to top */
354 continue;
355 }
356 read_lock_irq(&hp_sdc.rtq_lock);
357 if (hp_sdc.rcurr == curridx) {
358 read_unlock_irq(&hp_sdc.rtq_lock);
359 continue;
360 }
361 read_unlock_irq(&hp_sdc.rtq_lock);
362 if (hp_sdc.tq[curridx] != NULL) break; /* Found one. */
363 }
364 if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */
365 curridx = -1;
366 }
367 hp_sdc.wcurr = curridx;
368
369 start:
370
371 /* Check to see if the interrupt mask needs to be set. */
372 if (hp_sdc.set_im) {
373 hp_sdc_status_out8(hp_sdc.im | HP_SDC_CMD_SET_IM);
374 hp_sdc.set_im = 0;
375 goto finish;
376 }
377
378 if (hp_sdc.wcurr == -1) goto done;
379
380 curr = hp_sdc.tq[curridx];
381 idx = curr->actidx;
382
383 if (curr->actidx >= curr->endidx) {
384 hp_sdc.tq[curridx] = NULL;
385 /* Interleave outbound data between the transactions. */
386 hp_sdc.wcurr++;
387 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
388 goto finish;
389 }
390
391 act = curr->seq[idx];
392 idx++;
393
394 if (curr->idx >= curr->endidx) {
395 if (act & HP_SDC_ACT_DEALLOC) kfree(curr);
396 hp_sdc.tq[curridx] = NULL;
397 /* Interleave outbound data between the transactions. */
398 hp_sdc.wcurr++;
399 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
400 goto finish;
401 }
402
403 while (act & HP_SDC_ACT_PRECMD) {
404 if (curr->idx != idx) {
405 idx++;
406 act &= ~HP_SDC_ACT_PRECMD;
407 break;
408 }
409 hp_sdc_status_out8(curr->seq[idx]);
410 curr->idx++;
411 /* act finished? */
412 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD)
413 goto actdone;
414 /* skip quantity field if data-out sequence follows. */
415 if (act & HP_SDC_ACT_DATAOUT) curr->idx++;
416 goto finish;
417 }
418 if (act & HP_SDC_ACT_DATAOUT) {
419 int qty;
420
421 qty = curr->seq[idx];
422 idx++;
423 if (curr->idx - idx < qty) {
424 hp_sdc_data_out8(curr->seq[curr->idx]);
425 curr->idx++;
426 /* act finished? */
427 if ((curr->idx - idx >= qty) &&
428 ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT))
429 goto actdone;
430 goto finish;
431 }
432 idx += qty;
433 act &= ~HP_SDC_ACT_DATAOUT;
434 }
435 else while (act & HP_SDC_ACT_DATAREG) {
436 int mask;
437 uint8_t w7[4];
438
439 mask = curr->seq[idx];
440 if (idx != curr->idx) {
441 idx++;
442 idx += !!(mask & 1);
443 idx += !!(mask & 2);
444 idx += !!(mask & 4);
445 idx += !!(mask & 8);
446 act &= ~HP_SDC_ACT_DATAREG;
447 break;
448 }
449
450 w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0];
451 w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1];
452 w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2];
453 w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3];
454
455 if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 ||
456 w7[hp_sdc.wi-0x70] == hp_sdc.r7[hp_sdc.wi-0x70]) {
457 int i = 0;
458
459 /* Need to point the write index register */
460 while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++;
461 if (i < 4) {
462 hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i);
463 hp_sdc.wi = 0x70 + i;
464 goto finish;
465 }
466 idx++;
467 if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG)
468 goto actdone;
469 curr->idx = idx;
470 act &= ~HP_SDC_ACT_DATAREG;
471 break;
472 }
473
474 hp_sdc_data_out8(w7[hp_sdc.wi - 0x70]);
475 hp_sdc.r7[hp_sdc.wi - 0x70] = w7[hp_sdc.wi - 0x70];
476 hp_sdc.wi++; /* write index register autoincrements */
477 {
478 int i = 0;
479
480 while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++;
481 if (i >= 4) {
482 curr->idx = idx + 1;
483 if ((act & HP_SDC_ACT_DURING) ==
484 HP_SDC_ACT_DATAREG)
485 goto actdone;
486 }
487 }
488 goto finish;
489 }
490 /* We don't go any further in the command if there is a pending read,
491 because we don't want interleaved results. */
492 read_lock_irq(&hp_sdc.rtq_lock);
493 if (hp_sdc.rcurr >= 0) {
494 read_unlock_irq(&hp_sdc.rtq_lock);
495 goto finish;
496 }
497 read_unlock_irq(&hp_sdc.rtq_lock);
498
499
500 if (act & HP_SDC_ACT_POSTCMD) {
501 uint8_t postcmd;
502
503 /* curr->idx should == idx at this point. */
504 postcmd = curr->seq[idx];
505 curr->idx++;
506 if (act & HP_SDC_ACT_DATAIN) {
507
508 /* Start a new read */
509 hp_sdc.rqty = curr->seq[curr->idx];
510 do_gettimeofday(&hp_sdc.rtv);
511 curr->idx++;
512 /* Still need to lock here in case of spurious irq. */
513 write_lock_irq(&hp_sdc.rtq_lock);
514 hp_sdc.rcurr = curridx;
515 write_unlock_irq(&hp_sdc.rtq_lock);
516 hp_sdc_status_out8(postcmd);
517 goto finish;
518 }
519 hp_sdc_status_out8(postcmd);
520 goto actdone;
521 }
522
523actdone:
524 if (act & HP_SDC_ACT_SEMAPHORE) {
525 up(curr->act.semaphore);
526 }
527 else if (act & HP_SDC_ACT_CALLBACK) {
528 curr->act.irqhook(0,0,0,0);
529 }
530 if (curr->idx >= curr->endidx) { /* This transaction is over. */
531 if (act & HP_SDC_ACT_DEALLOC) kfree(curr);
532 hp_sdc.tq[curridx] = NULL;
533 }
534 else {
535 curr->actidx = idx + 1;
536 curr->idx = idx + 2;
537 }
538 /* Interleave outbound data between the transactions. */
539 hp_sdc.wcurr++;
540 if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
541
542 finish:
543 /* If by some quirk IBF has cleared and our ISR has run to
544 see that that has happened, do it all again. */
545 if (!hp_sdc.ibf && limit++ < 20) goto anew;
546
547 done:
548 if (hp_sdc.wcurr >= 0) tasklet_schedule(&hp_sdc.task);
549 write_unlock(&hp_sdc.lock);
550 return 0;
551}
552
553/******* Functions called in either user or kernel context ****/
554int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
555 unsigned long flags;
556 int i;
557
558 if (this == NULL) {
559 tasklet_schedule(&hp_sdc.task);
560 return -EINVAL;
561 };
562
563 write_lock_irqsave(&hp_sdc.lock, flags);
564
565 /* Can't have same transaction on queue twice */
566 for (i=0; i < HP_SDC_QUEUE_LEN; i++)
567 if (hp_sdc.tq[i] == this) goto fail;
568
569 this->actidx = 0;
570 this->idx = 1;
571
572 /* Search for empty slot */
573 for (i=0; i < HP_SDC_QUEUE_LEN; i++) {
574 if (hp_sdc.tq[i] == NULL) {
575 hp_sdc.tq[i] = this;
576 write_unlock_irqrestore(&hp_sdc.lock, flags);
577 tasklet_schedule(&hp_sdc.task);
578 return 0;
579 }
580 }
581 write_unlock_irqrestore(&hp_sdc.lock, flags);
582 printk(KERN_WARNING PREFIX "No free slot to add transaction.\n");
583 return -EBUSY;
584
585 fail:
586 write_unlock_irqrestore(&hp_sdc.lock,flags);
587 printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n");
588 return -EINVAL;
589}
590
591int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {
592 unsigned long flags;
593 int i;
594
595 write_lock_irqsave(&hp_sdc.lock, flags);
596
597 /* TODO: don't remove it if it's not done. */
598
599 for (i=0; i < HP_SDC_QUEUE_LEN; i++)
600 if (hp_sdc.tq[i] == this) hp_sdc.tq[i] = NULL;
601
602 write_unlock_irqrestore(&hp_sdc.lock, flags);
603 return 0;
604}
605
606
607
608/********************** User context functions **************************/
609int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) {
610
611 if (callback == NULL || hp_sdc.dev == NULL) {
612 return -EINVAL;
613 }
614 write_lock_irq(&hp_sdc.hook_lock);
615 if (hp_sdc.timer != NULL) {
616 write_unlock_irq(&hp_sdc.hook_lock);
617 return -EBUSY;
618 }
619
620 hp_sdc.timer = callback;
621 /* Enable interrupts from the timers */
622 hp_sdc.im &= ~HP_SDC_IM_FH;
623 hp_sdc.im &= ~HP_SDC_IM_PT;
624 hp_sdc.im &= ~HP_SDC_IM_TIMERS;
625 hp_sdc.set_im = 1;
626 write_unlock_irq(&hp_sdc.hook_lock);
627
628 tasklet_schedule(&hp_sdc.task);
629
630 return 0;
631}
632
633int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) {
634
635 if (callback == NULL || hp_sdc.dev == NULL) {
636 return -EINVAL;
637 }
638 write_lock_irq(&hp_sdc.hook_lock);
639 if (hp_sdc.hil != NULL) {
640 write_unlock_irq(&hp_sdc.hook_lock);
641 return -EBUSY;
642 }
643
644 hp_sdc.hil = callback;
645 hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET);
646 hp_sdc.set_im = 1;
647 write_unlock_irq(&hp_sdc.hook_lock);
648
649 tasklet_schedule(&hp_sdc.task);
650
651 return 0;
652}
653
654int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) {
655
656 if (callback == NULL || hp_sdc.dev == NULL) {
657 return -EINVAL;
658 }
659 write_lock_irq(&hp_sdc.hook_lock);
660 if (hp_sdc.cooked != NULL) {
661 write_unlock_irq(&hp_sdc.hook_lock);
662 return -EBUSY;
663 }
664
665 /* Enable interrupts from the HIL MLC */
666 hp_sdc.cooked = callback;
667 hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET);
668 hp_sdc.set_im = 1;
669 write_unlock_irq(&hp_sdc.hook_lock);
670
671 tasklet_schedule(&hp_sdc.task);
672
673 return 0;
674}
675
676int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) {
677
678
679 write_lock_irq(&hp_sdc.hook_lock);
680 if ((callback != hp_sdc.timer) ||
681 (hp_sdc.timer == NULL)) {
682 write_unlock_irq(&hp_sdc.hook_lock);
683 return -EINVAL;
684 }
685
686 /* Disable interrupts from the timers */
687 hp_sdc.timer = NULL;
688 hp_sdc.im |= HP_SDC_IM_TIMERS;
689 hp_sdc.im |= HP_SDC_IM_FH;
690 hp_sdc.im |= HP_SDC_IM_PT;
691 hp_sdc.set_im = 1;
692 write_unlock_irq(&hp_sdc.hook_lock);
693 tasklet_schedule(&hp_sdc.task);
694
695 return 0;
696}
697
698int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) {
699
700 write_lock_irq(&hp_sdc.hook_lock);
701 if ((callback != hp_sdc.hil) ||
702 (hp_sdc.hil == NULL)) {
703 write_unlock_irq(&hp_sdc.hook_lock);
704 return -EINVAL;
705 }
706
707 hp_sdc.hil = NULL;
708 /* Disable interrupts from HIL only if there is no cooked driver. */
709 if(hp_sdc.cooked == NULL) {
710 hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET);
711 hp_sdc.set_im = 1;
712 }
713 write_unlock_irq(&hp_sdc.hook_lock);
714 tasklet_schedule(&hp_sdc.task);
715
716 return 0;
717}
718
719int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) {
720
721 write_lock_irq(&hp_sdc.hook_lock);
722 if ((callback != hp_sdc.cooked) ||
723 (hp_sdc.cooked == NULL)) {
724 write_unlock_irq(&hp_sdc.hook_lock);
725 return -EINVAL;
726 }
727
728 hp_sdc.cooked = NULL;
729 /* Disable interrupts from HIL only if there is no raw HIL driver. */
730 if(hp_sdc.hil == NULL) {
731 hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET);
732 hp_sdc.set_im = 1;
733 }
734 write_unlock_irq(&hp_sdc.hook_lock);
735 tasklet_schedule(&hp_sdc.task);
736
737 return 0;
738}
739
740/************************* Keepalive timer task *********************/
741
742void hp_sdc_kicker (unsigned long data) {
743 tasklet_schedule(&hp_sdc.task);
744 /* Re-insert the periodic task. */
745 mod_timer(&hp_sdc.kicker, jiffies + HZ);
746}
747
748/************************** Module Initialization ***************************/
749
750#if defined(__hppa__)
751
752static struct parisc_device_id hp_sdc_tbl[] = {
753 {
754 .hw_type = HPHW_FIO,
755 .hversion_rev = HVERSION_REV_ANY_ID,
756 .hversion = HVERSION_ANY_ID,
757 .sversion = 0x73,
758 },
759 { 0, }
760};
761
762MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
763
764static int __init hp_sdc_init_hppa(struct parisc_device *d);
765
766static struct parisc_driver hp_sdc_driver = {
767 .name = "HP SDC",
768 .id_table = hp_sdc_tbl,
769 .probe = hp_sdc_init_hppa,
770};
771
772#endif /* __hppa__ */
773
774static int __init hp_sdc_init(void)
775{
776 int i;
777 char *errstr;
778 hp_sdc_transaction t_sync;
779 uint8_t ts_sync[6];
780 struct semaphore s_sync;
781
782 rwlock_init(&hp_sdc.lock);
783 rwlock_init(&hp_sdc.ibf_lock);
784 rwlock_init(&hp_sdc.rtq_lock);
785 rwlock_init(&hp_sdc.hook_lock);
786
787 hp_sdc.timer = NULL;
788 hp_sdc.hil = NULL;
789 hp_sdc.pup = NULL;
790 hp_sdc.cooked = NULL;
791 hp_sdc.im = HP_SDC_IM_MASK; /* Mask maskable irqs */
792 hp_sdc.set_im = 1;
793 hp_sdc.wi = 0xff;
794 hp_sdc.r7[0] = 0xff;
795 hp_sdc.r7[1] = 0xff;
796 hp_sdc.r7[2] = 0xff;
797 hp_sdc.r7[3] = 0xff;
798 hp_sdc.ibf = 1;
799
800 for (i = 0; i < HP_SDC_QUEUE_LEN; i++) hp_sdc.tq[i] = NULL;
801 hp_sdc.wcurr = -1;
802 hp_sdc.rcurr = -1;
803 hp_sdc.rqty = 0;
804
805 hp_sdc.dev_err = -ENODEV;
806
807 errstr = "IO not found for";
808 if (!hp_sdc.base_io) goto err0;
809
810 errstr = "IRQ not found for";
811 if (!hp_sdc.irq) goto err0;
812
813 hp_sdc.dev_err = -EBUSY;
814
815#if defined(__hppa__)
816 errstr = "IO not available for";
817 if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) goto err0;
818#endif
819
820 errstr = "IRQ not available for";
821 if(request_irq(hp_sdc.irq, &hp_sdc_isr, 0, "HP SDC",
822 (void *) hp_sdc.base_io)) goto err1;
823
824 errstr = "NMI not available for";
825 if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, 0, "HP SDC NMI",
826 (void *) hp_sdc.base_io)) goto err2;
827
828 printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n",
829 (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
830
831 hp_sdc_status_in8();
832 hp_sdc_data_in8();
833
834 tasklet_init(&hp_sdc.task, hp_sdc_tasklet, 0);
835
836 /* Sync the output buffer registers, thus scheduling hp_sdc_tasklet. */
837 t_sync.actidx = 0;
838 t_sync.idx = 1;
839 t_sync.endidx = 6;
840 t_sync.seq = ts_sync;
841 ts_sync[0] = HP_SDC_ACT_DATAREG | HP_SDC_ACT_SEMAPHORE;
842 ts_sync[1] = 0x0f;
843 ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0;
844 t_sync.act.semaphore = &s_sync;
845 init_MUTEX_LOCKED(&s_sync);
846 hp_sdc_enqueue_transaction(&t_sync);
847 down(&s_sync); /* Wait for t_sync to complete */
848
849 /* Create the keepalive task */
850 init_timer(&hp_sdc.kicker);
851 hp_sdc.kicker.expires = jiffies + HZ;
852 hp_sdc.kicker.function = &hp_sdc_kicker;
853 add_timer(&hp_sdc.kicker);
854
855 hp_sdc.dev_err = 0;
856 return 0;
857 err2:
858 free_irq(hp_sdc.irq, NULL);
859 err1:
860 release_region(hp_sdc.data_io, 2);
861 err0:
862 printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n",
863 errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
864 hp_sdc.dev = NULL;
865 return hp_sdc.dev_err;
866}
867
868#if defined(__hppa__)
869
870static int __init hp_sdc_init_hppa(struct parisc_device *d)
871{
872 if (!d) return 1;
873 if (hp_sdc.dev != NULL) return 1; /* We only expect one SDC */
874
875 hp_sdc.dev = d;
876 hp_sdc.irq = d->irq;
877 hp_sdc.nmi = d->aux_irq;
878 hp_sdc.base_io = d->hpa;
879 hp_sdc.data_io = d->hpa + 0x800;
880 hp_sdc.status_io = d->hpa + 0x801;
881
882 return hp_sdc_init();
883}
884
885#endif /* __hppa__ */
886
887#if !defined(__mc68000__) /* Link error on m68k! */
888static void __exit hp_sdc_exit(void)
889#else
890static void hp_sdc_exit(void)
891#endif
892{
893 write_lock_irq(&hp_sdc.lock);
894
895 /* Turn off all maskable "sub-function" irq's. */
896 hp_sdc_spin_ibf();
897 sdc_writeb(HP_SDC_CMD_SET_IM | HP_SDC_IM_MASK, hp_sdc.status_io);
898
899 /* Wait until we know this has been processed by the i8042 */
900 hp_sdc_spin_ibf();
901
902 free_irq(hp_sdc.nmi, NULL);
903 free_irq(hp_sdc.irq, NULL);
904 write_unlock_irq(&hp_sdc.lock);
905
906 del_timer(&hp_sdc.kicker);
907
908 tasklet_kill(&hp_sdc.task);
909
910/* release_region(hp_sdc.data_io, 2); */
911
912#if defined(__hppa__)
913 if (unregister_parisc_driver(&hp_sdc_driver))
914 printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
915#endif
916}
917
918static int __init hp_sdc_register(void)
919{
920 hp_sdc_transaction tq_init;
921 uint8_t tq_init_seq[5];
922 struct semaphore tq_init_sem;
923#if defined(__mc68000__)
924 mm_segment_t fs;
925 unsigned char i;
926#endif
927
928 hp_sdc.dev = NULL;
929 hp_sdc.dev_err = 0;
930#if defined(__hppa__)
931 if (register_parisc_driver(&hp_sdc_driver)) {
932 printk(KERN_WARNING PREFIX "Error registering SDC with system bus tree.\n");
933 return -ENODEV;
934 }
935#elif defined(__mc68000__)
936 if (!MACH_IS_HP300)
937 return -ENODEV;
938
939 hp_sdc.irq = 1;
940 hp_sdc.nmi = 7;
941 hp_sdc.base_io = (unsigned long) 0xf0428000;
942 hp_sdc.data_io = (unsigned long) hp_sdc.base_io + 1;
943 hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3;
944 fs = get_fs();
945 set_fs(KERNEL_DS);
946 if (!get_user(i, (unsigned char *)hp_sdc.data_io))
947 hp_sdc.dev = (void *)1;
948 set_fs(fs);
949 hp_sdc.dev_err = hp_sdc_init();
950#endif
951 if (hp_sdc.dev == NULL) {
952 printk(KERN_WARNING PREFIX "No SDC found.\n");
953 return hp_sdc.dev_err;
954 }
955
956 init_MUTEX_LOCKED(&tq_init_sem);
957
958 tq_init.actidx = 0;
959 tq_init.idx = 1;
960 tq_init.endidx = 5;
961 tq_init.seq = tq_init_seq;
962 tq_init.act.semaphore = &tq_init_sem;
963
964 tq_init_seq[0] =
965 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
966 tq_init_seq[1] = HP_SDC_CMD_READ_KCC;
967 tq_init_seq[2] = 1;
968 tq_init_seq[3] = 0;
969 tq_init_seq[4] = 0;
970
971 hp_sdc_enqueue_transaction(&tq_init);
972
973 down(&tq_init_sem);
974 up(&tq_init_sem);
975
976 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
977 printk(KERN_WARNING PREFIX "Error reading config byte.\n");
978 hp_sdc_exit();
979 return -ENODEV;
980 }
981 hp_sdc.r11 = tq_init_seq[4];
982 if (hp_sdc.r11 & HP_SDC_CFG_NEW) {
983 char *str;
984 printk(KERN_INFO PREFIX "New style SDC\n");
985 tq_init_seq[1] = HP_SDC_CMD_READ_XTD;
986 tq_init.actidx = 0;
987 tq_init.idx = 1;
988 down(&tq_init_sem);
989 hp_sdc_enqueue_transaction(&tq_init);
990 down(&tq_init_sem);
991 up(&tq_init_sem);
992 if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
993 printk(KERN_WARNING PREFIX "Error reading extended config byte.\n");
994 return -ENODEV;
995 }
996 hp_sdc.r7e = tq_init_seq[4];
997 HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str)
998 printk(KERN_INFO PREFIX "Revision: %s\n", str);
999 if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) {
1000 printk(KERN_INFO PREFIX "TI SN76494 beeper present\n");
1001 }
1002 if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) {
1003 printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n");
1004 }
1005 printk(KERN_INFO PREFIX "Spunking the self test register to force PUP "
1006 "on next firmware reset.\n");
1007 tq_init_seq[0] = HP_SDC_ACT_PRECMD |
1008 HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
1009 tq_init_seq[1] = HP_SDC_CMD_SET_STR;
1010 tq_init_seq[2] = 1;
1011 tq_init_seq[3] = 0;
1012 tq_init.actidx = 0;
1013 tq_init.idx = 1;
1014 tq_init.endidx = 4;
1015 down(&tq_init_sem);
1016 hp_sdc_enqueue_transaction(&tq_init);
1017 down(&tq_init_sem);
1018 up(&tq_init_sem);
1019 }
1020 else {
1021 printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n",
1022 (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087");
1023 }
1024
1025 return 0;
1026}
1027
1028module_init(hp_sdc_register);
1029module_exit(hp_sdc_exit);
1030
1031/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64)
1032 * cycles cycles-adj time
1033 * between two consecutive mfctl(16)'s: 4 n/a 63ns
1034 * hp_sdc_spin_ibf when idle: 119 115 1.7us
1035 * gsc_writeb status register: 83 79 1.2us
1036 * IBF to clear after sending SET_IM: 6204 6006 93us
1037 * IBF to clear after sending LOAD_RT: 4467 4352 68us
1038 * IBF to clear after sending two LOAD_RTs: 18974 18859 295us
1039 * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us
1040 * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms
1041 * between IRQ received and ~IBF for above: 2578877 n/a 40ms
1042 *
1043 * Performance stats after a run of this module configuring HIL and
1044 * receiving a few mouse events:
1045 *
1046 * status in8 282508 cycles 7128 calls
1047 * status out8 8404 cycles 341 calls
1048 * data out8 1734 cycles 78 calls
1049 * isr 174324 cycles 617 calls (includes take)
1050 * take 1241 cycles 2 calls
1051 * put 1411504 cycles 6937 calls
1052 * task 1655209 cycles 6937 calls (includes put)
1053 *
1054 */
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c
new file mode 100644
index 000000000000..e3c44ffae674
--- /dev/null
+++ b/drivers/input/serio/hp_sdc_mlc.c
@@ -0,0 +1,358 @@
1/*
2 * Access to HP-HIL MLC through HP System Device Controller.
3 *
4 * Copyright (c) 2001 Brian S. Julin
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 *
29 * References:
30 * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
31 * System Device Controller Microprocessor Firmware Theory of Operation
32 * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
33 *
34 */
35
36#include <linux/hil_mlc.h>
37#include <linux/hp_sdc.h>
38#include <linux/errno.h>
39#include <linux/kernel.h>
40#include <linux/module.h>
41#include <linux/init.h>
42#include <linux/string.h>
43
44#define PREFIX "HP SDC MLC: "
45
46static hil_mlc hp_sdc_mlc;
47
48MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
49MODULE_DESCRIPTION("Glue for onboard HIL MLC in HP-PARISC machines");
50MODULE_LICENSE("Dual BSD/GPL");
51
52struct hp_sdc_mlc_priv_s {
53 int emtestmode;
54 hp_sdc_transaction trans;
55 u8 tseq[16];
56 int got5x;
57} hp_sdc_mlc_priv;
58
59/************************* Interrupt context ******************************/
60static void hp_sdc_mlc_isr (int irq, void *dev_id,
61 uint8_t status, uint8_t data) {
62 int idx;
63 hil_mlc *mlc = &hp_sdc_mlc;
64
65 write_lock(&(mlc->lock));
66 if (mlc->icount < 0) {
67 printk(KERN_WARNING PREFIX "HIL Overflow!\n");
68 up(&mlc->isem);
69 goto out;
70 }
71 idx = 15 - mlc->icount;
72 if ((status & HP_SDC_STATUS_IRQMASK) == HP_SDC_STATUS_HILDATA) {
73 mlc->ipacket[idx] |= data | HIL_ERR_INT;
74 mlc->icount--;
75 if (hp_sdc_mlc_priv.got5x) goto check;
76 if (!idx) goto check;
77 if ((mlc->ipacket[idx-1] & HIL_PKT_ADDR_MASK) !=
78 (mlc->ipacket[idx] & HIL_PKT_ADDR_MASK)) {
79 mlc->ipacket[idx] &= ~HIL_PKT_ADDR_MASK;
80 mlc->ipacket[idx] |= (mlc->ipacket[idx-1]
81 & HIL_PKT_ADDR_MASK);
82 }
83 goto check;
84 }
85 /* We know status is 5X */
86 if (data & HP_SDC_HIL_ISERR) goto err;
87 mlc->ipacket[idx] =
88 (data & HP_SDC_HIL_R1MASK) << HIL_PKT_ADDR_SHIFT;
89 hp_sdc_mlc_priv.got5x = 1;
90 goto out;
91
92 check:
93 hp_sdc_mlc_priv.got5x = 0;
94 if (mlc->imatch == 0) goto done;
95 if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
96 && (mlc->ipacket[idx] == (mlc->imatch | idx))) goto done;
97 if (mlc->ipacket[idx] == mlc->imatch) goto done;
98 goto out;
99
100 err:
101 printk(KERN_DEBUG PREFIX "err code %x\n", data);
102 switch (data) {
103 case HP_SDC_HIL_RC_DONE:
104 printk(KERN_WARNING PREFIX "Bastard SDC reconfigured loop!\n");
105 break;
106 case HP_SDC_HIL_ERR:
107 mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR |
108 HIL_ERR_FERR | HIL_ERR_FOF;
109 break;
110 case HP_SDC_HIL_TO:
111 mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_LERR;
112 break;
113 case HP_SDC_HIL_RC:
114 printk(KERN_WARNING PREFIX "Bastard SDC decided to reconfigure loop!\n");
115 break;
116 default:
117 printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data);
118 break;
119 }
120 /* No more data will be coming due to an error. */
121 done:
122 tasklet_schedule(mlc->tasklet);
123 up(&(mlc->isem));
124 out:
125 write_unlock(&(mlc->lock));
126}
127
128
129/******************** Tasklet or userspace context functions ****************/
130
131static int hp_sdc_mlc_in (hil_mlc *mlc, suseconds_t timeout) {
132 unsigned long flags;
133 struct hp_sdc_mlc_priv_s *priv;
134 int rc = 2;
135
136 priv = mlc->priv;
137
138 write_lock_irqsave(&(mlc->lock), flags);
139
140 /* Try to down the semaphore */
141 if (down_trylock(&(mlc->isem))) {
142 struct timeval tv;
143 if (priv->emtestmode) {
144 mlc->ipacket[0] =
145 HIL_ERR_INT | (mlc->opacket &
146 (HIL_PKT_CMD |
147 HIL_PKT_ADDR_MASK |
148 HIL_PKT_DATA_MASK));
149 mlc->icount = 14;
150 /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */
151 goto wasup;
152 }
153 do_gettimeofday(&tv);
154 tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec);
155 if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) {
156 /* printk("!%i %i",
157 tv.tv_usec - mlc->instart.tv_usec,
158 mlc->intimeout);
159 */
160 rc = 1;
161 up(&(mlc->isem));
162 }
163 goto done;
164 }
165 wasup:
166 up(&(mlc->isem));
167 rc = 0;
168 goto done;
169 done:
170 write_unlock_irqrestore(&(mlc->lock), flags);
171 return rc;
172}
173
174static int hp_sdc_mlc_cts (hil_mlc *mlc) {
175 struct hp_sdc_mlc_priv_s *priv;
176 unsigned long flags;
177
178 priv = mlc->priv;
179
180 write_lock_irqsave(&(mlc->lock), flags);
181
182 /* Try to down the semaphores -- they should be up. */
183 if (down_trylock(&(mlc->isem))) {
184 BUG();
185 goto busy;
186 }
187 if (down_trylock(&(mlc->osem))) {
188 BUG();
189 up(&(mlc->isem));
190 goto busy;
191 }
192 up(&(mlc->isem));
193 up(&(mlc->osem));
194
195 if (down_trylock(&(mlc->csem))) {
196 if (priv->trans.act.semaphore != &(mlc->csem)) goto poll;
197 goto busy;
198 }
199 if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) goto done;
200
201 poll:
202 priv->trans.act.semaphore = &(mlc->csem);
203 priv->trans.actidx = 0;
204 priv->trans.idx = 1;
205 priv->trans.endidx = 5;
206 priv->tseq[0] =
207 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
208 priv->tseq[1] = HP_SDC_CMD_READ_USE;
209 priv->tseq[2] = 1;
210 priv->tseq[3] = 0;
211 priv->tseq[4] = 0;
212 hp_sdc_enqueue_transaction(&(priv->trans));
213 busy:
214 write_unlock_irqrestore(&(mlc->lock), flags);
215 return 1;
216 done:
217 priv->trans.act.semaphore = &(mlc->osem);
218 up(&(mlc->csem));
219 write_unlock_irqrestore(&(mlc->lock), flags);
220 return 0;
221}
222
223static void hp_sdc_mlc_out (hil_mlc *mlc) {
224 struct hp_sdc_mlc_priv_s *priv;
225 unsigned long flags;
226
227 priv = mlc->priv;
228
229 write_lock_irqsave(&(mlc->lock), flags);
230
231 /* Try to down the semaphore -- it should be up. */
232 if (down_trylock(&(mlc->osem))) {
233 BUG();
234 goto done;
235 }
236
237 if (mlc->opacket & HIL_DO_ALTER_CTRL) goto do_control;
238
239 do_data:
240 if (priv->emtestmode) {
241 up(&(mlc->osem));
242 goto done;
243 }
244 /* Shouldn't be sending commands when loop may be busy */
245 if (down_trylock(&(mlc->csem))) {
246 BUG();
247 goto done;
248 }
249 up(&(mlc->csem));
250
251 priv->trans.actidx = 0;
252 priv->trans.idx = 1;
253 priv->trans.act.semaphore = &(mlc->osem);
254 priv->trans.endidx = 6;
255 priv->tseq[0] =
256 HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE;
257 priv->tseq[1] = 0x7;
258 priv->tseq[2] =
259 (mlc->opacket &
260 (HIL_PKT_ADDR_MASK | HIL_PKT_CMD))
261 >> HIL_PKT_ADDR_SHIFT;
262 priv->tseq[3] =
263 (mlc->opacket & HIL_PKT_DATA_MASK)
264 >> HIL_PKT_DATA_SHIFT;
265 priv->tseq[4] = 0; /* No timeout */
266 if (priv->tseq[3] == HIL_CMD_DHR) priv->tseq[4] = 1;
267 priv->tseq[5] = HP_SDC_CMD_DO_HIL;
268 goto enqueue;
269
270 do_control:
271 priv->emtestmode = mlc->opacket & HIL_CTRL_TEST;
272 if ((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE) {
273 BUG(); /* we cannot emulate this, it should not be used. */
274 }
275 if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) goto control_only;
276 if (mlc->opacket & HIL_CTRL_APE) {
277 BUG(); /* Should not send command/data after engaging APE */
278 goto done;
279 }
280 /* Disengaging APE this way would not be valid either since
281 * the loop must be allowed to idle.
282 *
283 * So, it works out that we really never actually send control
284 * and data when using SDC, we just send the data.
285 */
286 goto do_data;
287
288 control_only:
289 priv->trans.actidx = 0;
290 priv->trans.idx = 1;
291 priv->trans.act.semaphore = &(mlc->osem);
292 priv->trans.endidx = 4;
293 priv->tseq[0] =
294 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
295 priv->tseq[1] = HP_SDC_CMD_SET_LPC;
296 priv->tseq[2] = 1;
297 // priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC;
298 priv->tseq[3] = 0;
299 if (mlc->opacket & HIL_CTRL_APE) {
300 priv->tseq[3] |= HP_SDC_LPC_APE_IPF;
301 down_trylock(&(mlc->csem));
302 }
303 enqueue:
304 hp_sdc_enqueue_transaction(&(priv->trans));
305 done:
306 write_unlock_irqrestore(&(mlc->lock), flags);
307}
308
309static int __init hp_sdc_mlc_init(void)
310{
311 hil_mlc *mlc = &hp_sdc_mlc;
312
313 printk(KERN_INFO PREFIX "Registering the System Domain Controller's HIL MLC.\n");
314
315 hp_sdc_mlc_priv.emtestmode = 0;
316 hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq;
317 hp_sdc_mlc_priv.trans.act.semaphore = &(mlc->osem);
318 hp_sdc_mlc_priv.got5x = 0;
319
320 mlc->cts = &hp_sdc_mlc_cts;
321 mlc->in = &hp_sdc_mlc_in;
322 mlc->out = &hp_sdc_mlc_out;
323
324 if (hil_mlc_register(mlc)) {
325 printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n");
326 goto err0;
327 }
328 mlc->priv = &hp_sdc_mlc_priv;
329
330 if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) {
331 printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n");
332 goto err1;
333 }
334 return 0;
335 err1:
336 if (hil_mlc_unregister(mlc)) {
337 printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
338 "This is bad. Could cause an oops.\n");
339 }
340 err0:
341 return -EBUSY;
342}
343
344static void __exit hp_sdc_mlc_exit(void)
345{
346 hil_mlc *mlc = &hp_sdc_mlc;
347 if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) {
348 printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n"
349 "This is bad. Could cause an oops.\n");
350 }
351 if (hil_mlc_unregister(mlc)) {
352 printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
353 "This is bad. Could cause an oops.\n");
354 }
355}
356
357module_init(hp_sdc_mlc_init);
358module_exit(hp_sdc_mlc_exit);
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
new file mode 100644
index 000000000000..c9e633d21d90
--- /dev/null
+++ b/drivers/input/serio/i8042-io.h
@@ -0,0 +1,93 @@
1#ifndef _I8042_IO_H
2#define _I8042_IO_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#ifdef __alpha__
23# define I8042_KBD_IRQ 1
24# define I8042_AUX_IRQ (RTC_PORT(0) == 0x170 ? 9 : 12) /* Jensen is special */
25#elif defined(__arm__)
26/* defined in include/asm-arm/arch-xxx/irqs.h */
27#include <asm/irq.h>
28#elif defined(CONFIG_SUPERH64)
29#include <asm/irq.h>
30#else
31# define I8042_KBD_IRQ 1
32# define I8042_AUX_IRQ 12
33#endif
34
35
36/*
37 * Register numbers.
38 */
39
40#define I8042_COMMAND_REG 0x64
41#define I8042_STATUS_REG 0x64
42#define I8042_DATA_REG 0x60
43
44static inline int i8042_read_data(void)
45{
46 return inb(I8042_DATA_REG);
47}
48
49static inline int i8042_read_status(void)
50{
51 return inb(I8042_STATUS_REG);
52}
53
54static inline void i8042_write_data(int val)
55{
56 outb(val, I8042_DATA_REG);
57}
58
59static inline void i8042_write_command(int val)
60{
61 outb(val, I8042_COMMAND_REG);
62}
63
64static inline int i8042_platform_init(void)
65{
66/*
67 * On some platforms touching the i8042 data register region can do really
68 * bad things. Because of this the region is always reserved on such boxes.
69 */
70#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC64)
71 if (!request_region(I8042_DATA_REG, 16, "i8042"))
72 return -1;
73#endif
74
75 i8042_reset = 1;
76
77#if defined(CONFIG_PPC64)
78 if (check_legacy_ioport(I8042_DATA_REG))
79 return -1;
80 if (!request_region(I8042_DATA_REG, 16, "i8042"))
81 return -1;
82#endif
83 return 0;
84}
85
86static inline void i8042_platform_exit(void)
87{
88#if !defined(__sh__) && !defined(__alpha__) && !defined(CONFIG_PPC64)
89 release_region(I8042_DATA_REG, 16);
90#endif
91}
92
93#endif /* _I8042_IO_H */
diff --git a/drivers/input/serio/i8042-ip22io.h b/drivers/input/serio/i8042-ip22io.h
new file mode 100644
index 000000000000..863b9c95fbb8
--- /dev/null
+++ b/drivers/input/serio/i8042-ip22io.h
@@ -0,0 +1,76 @@
1#ifndef _I8042_IP22_H
2#define _I8042_IP22_H
3
4#include <asm/sgi/ioc.h>
5#include <asm/sgi/ip22.h>
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12
13/*
14 * Names.
15 */
16
17#define I8042_KBD_PHYS_DESC "hpc3ps2/serio0"
18#define I8042_AUX_PHYS_DESC "hpc3ps2/serio1"
19#define I8042_MUX_PHYS_DESC "hpc3ps2/serio%d"
20
21/*
22 * IRQs.
23 */
24
25#define I8042_KBD_IRQ SGI_KEYBD_IRQ
26#define I8042_AUX_IRQ SGI_KEYBD_IRQ
27
28/*
29 * Register numbers.
30 */
31
32#define I8042_COMMAND_REG ((unsigned long)&sgioc->kbdmouse.command)
33#define I8042_STATUS_REG ((unsigned long)&sgioc->kbdmouse.command)
34#define I8042_DATA_REG ((unsigned long)&sgioc->kbdmouse.data)
35
36static inline int i8042_read_data(void)
37{
38 return sgioc->kbdmouse.data;
39}
40
41static inline int i8042_read_status(void)
42{
43 return sgioc->kbdmouse.command;
44}
45
46static inline void i8042_write_data(int val)
47{
48 sgioc->kbdmouse.data = val;
49}
50
51static inline void i8042_write_command(int val)
52{
53 sgioc->kbdmouse.command = val;
54}
55
56static inline int i8042_platform_init(void)
57{
58#if 0
59 /* XXX sgi_kh is a virtual address */
60 if (!request_mem_region(sgi_kh, sizeof(struct hpc_keyb), "i8042"))
61 return 1;
62#endif
63
64 i8042_reset = 1;
65
66 return 0;
67}
68
69static inline void i8042_platform_exit(void)
70{
71#if 0
72 release_mem_region(JAZZ_KEYBOARD_ADDRESS, sizeof(struct hpc_keyb));
73#endif
74}
75
76#endif /* _I8042_IP22_H */
diff --git a/drivers/input/serio/i8042-jazzio.h b/drivers/input/serio/i8042-jazzio.h
new file mode 100644
index 000000000000..5c20ab131488
--- /dev/null
+++ b/drivers/input/serio/i8042-jazzio.h
@@ -0,0 +1,69 @@
1#ifndef _I8042_JAZZ_H
2#define _I8042_JAZZ_H
3
4#include <asm/jazz.h>
5
6/*
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12/*
13 * Names.
14 */
15
16#define I8042_KBD_PHYS_DESC "R4030/serio0"
17#define I8042_AUX_PHYS_DESC "R4030/serio1"
18#define I8042_MUX_PHYS_DESC "R4030/serio%d"
19
20/*
21 * IRQs.
22 */
23
24#define I8042_KBD_IRQ JAZZ_KEYBOARD_IRQ
25#define I8042_AUX_IRQ JAZZ_MOUSE_IRQ
26
27#define I8042_COMMAND_REG ((unsigned long)&jazz_kh->command)
28#define I8042_STATUS_REG ((unsigned long)&jazz_kh->command)
29#define I8042_DATA_REG ((unsigned long)&jazz_kh->data)
30
31static inline int i8042_read_data(void)
32{
33 return jazz_kh->data;
34}
35
36static inline int i8042_read_status(void)
37{
38 return jazz_kh->command;
39}
40
41static inline void i8042_write_data(int val)
42{
43 jazz_kh->data = val;
44}
45
46static inline void i8042_write_command(int val)
47{
48 jazz_kh->command = val;
49}
50
51static inline int i8042_platform_init(void)
52{
53#if 0
54 /* XXX JAZZ_KEYBOARD_ADDRESS is a virtual address */
55 if (!request_mem_region(JAZZ_KEYBOARD_ADDRESS, 2, "i8042"))
56 return 1;
57#endif
58
59 return 0;
60}
61
62static inline void i8042_platform_exit(void)
63{
64#if 0
65 release_mem_region(JAZZ_KEYBOARD_ADDRESS, 2);
66#endif
67}
68
69#endif /* _I8042_JAZZ_H */
diff --git a/drivers/input/serio/i8042-ppcio.h b/drivers/input/serio/i8042-ppcio.h
new file mode 100644
index 000000000000..2906e1b60c04
--- /dev/null
+++ b/drivers/input/serio/i8042-ppcio.h
@@ -0,0 +1,136 @@
1#ifndef _I8042_PPCIO_H
2#define _I8042_PPCIO_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#if defined(CONFIG_WALNUT)
11
12#define I8042_KBD_IRQ 25
13#define I8042_AUX_IRQ 26
14
15#define I8042_KBD_PHYS_DESC "walnutps2/serio0"
16#define I8042_AUX_PHYS_DESC "walnutps2/serio1"
17#define I8042_MUX_PHYS_DESC "walnutps2/serio%d"
18
19extern void *kb_cs;
20extern void *kb_data;
21
22#define I8042_COMMAND_REG (*(int *)kb_cs)
23#define I8042_DATA_REG (*(int *)kb_data)
24
25static inline int i8042_read_data(void)
26{
27 return readb(kb_data);
28}
29
30static inline int i8042_read_status(void)
31{
32 return readb(kb_cs);
33}
34
35static inline void i8042_write_data(int val)
36{
37 writeb(val, kb_data);
38}
39
40static inline void i8042_write_command(int val)
41{
42 writeb(val, kb_cs);
43}
44
45static inline int i8042_platform_init(void)
46{
47 i8042_reset = 1;
48 return 0;
49}
50
51static inline void i8042_platform_exit(void)
52{
53}
54
55#elif defined(CONFIG_SPRUCE)
56
57#define I8042_KBD_IRQ 22
58#define I8042_AUX_IRQ 21
59
60#define I8042_KBD_PHYS_DESC "spruceps2/serio0"
61#define I8042_AUX_PHYS_DESC "spruceps2/serio1"
62#define I8042_MUX_PHYS_DESC "spruceps2/serio%d"
63
64#define I8042_COMMAND_REG 0xff810000
65#define I8042_DATA_REG 0xff810001
66
67static inline int i8042_read_data(void)
68{
69 unsigned long kbd_data;
70
71 __raw_writel(0x00000088, 0xff500008);
72 eieio();
73
74 __raw_writel(0x03000000, 0xff50000c);
75 eieio();
76
77 asm volatile("lis 7,0xff88 \n\
78 lswi 6,7,0x8 \n\
79 mr %0,6"
80 : "=r" (kbd_data) :: "6", "7");
81
82 __raw_writel(0x00000000, 0xff50000c);
83 eieio();
84
85 return (unsigned char)(kbd_data >> 24);
86}
87
88static inline int i8042_read_status(void)
89{
90 unsigned long kbd_status;
91
92 __raw_writel(0x00000088, 0xff500008);
93 eieio();
94
95 __raw_writel(0x03000000, 0xff50000c);
96 eieio();
97
98 asm volatile("lis 7,0xff88 \n\
99 ori 7,7,0x8 \n\
100 lswi 6,7,0x8 \n\
101 mr %0,6"
102 : "=r" (kbd_status) :: "6", "7");
103
104 __raw_writel(0x00000000, 0xff50000c);
105 eieio();
106
107 return (unsigned char)(kbd_status >> 24);
108}
109
110static inline void i8042_write_data(int val)
111{
112 *((unsigned char *)0xff810000) = (char)val;
113}
114
115static inline void i8042_write_command(int val)
116{
117 *((unsigned char *)0xff810001) = (char)val;
118}
119
120static inline int i8042_platform_init(void)
121{
122 i8042_reset = 1;
123 return 0;
124}
125
126static inline void i8042_platform_exit(void)
127{
128}
129
130#else
131
132#include "i8042-io.h"
133
134#endif
135
136#endif /* _I8042_PPCIO_H */
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
new file mode 100644
index 000000000000..da2a19812485
--- /dev/null
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -0,0 +1,116 @@
1#ifndef _I8042_SPARCIO_H
2#define _I8042_SPARCIO_H
3
4#include <linux/config.h>
5#include <asm/io.h>
6
7#ifdef CONFIG_PCI
8#include <asm/oplib.h>
9#include <asm/ebus.h>
10#endif
11
12static int i8042_kbd_irq = -1;
13static int i8042_aux_irq = -1;
14#define I8042_KBD_IRQ i8042_kbd_irq
15#define I8042_AUX_IRQ i8042_aux_irq
16
17#define I8042_KBD_PHYS_DESC "sparcps2/serio0"
18#define I8042_AUX_PHYS_DESC "sparcps2/serio1"
19#define I8042_MUX_PHYS_DESC "sparcps2/serio%d"
20
21static void __iomem *kbd_iobase;
22
23#define I8042_COMMAND_REG (kbd_iobase + 0x64UL)
24#define I8042_DATA_REG (kbd_iobase + 0x60UL)
25
26static inline int i8042_read_data(void)
27{
28 return readb(kbd_iobase + 0x60UL);
29}
30
31static inline int i8042_read_status(void)
32{
33 return readb(kbd_iobase + 0x64UL);
34}
35
36static inline void i8042_write_data(int val)
37{
38 writeb(val, kbd_iobase + 0x60UL);
39}
40
41static inline void i8042_write_command(int val)
42{
43 writeb(val, kbd_iobase + 0x64UL);
44}
45
46#define OBP_PS2KBD_NAME1 "kb_ps2"
47#define OBP_PS2KBD_NAME2 "keyboard"
48#define OBP_PS2MS_NAME1 "kdmouse"
49#define OBP_PS2MS_NAME2 "mouse"
50
51static int i8042_platform_init(void)
52{
53#ifndef CONFIG_PCI
54 return -1;
55#else
56 char prop[128];
57 int len;
58
59 len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop));
60 if (len < 0) {
61 printk("i8042: Cannot get name property of root OBP node.\n");
62 return -1;
63 }
64 if (strncmp(prop, "SUNW,JavaStation-1", len) == 0) {
65 /* Hardcoded values for MrCoffee. */
66 i8042_kbd_irq = i8042_aux_irq = 13 | 0x20;
67 kbd_iobase = ioremap(0x71300060, 8);
68 if (!kbd_iobase)
69 return -1;
70 } else {
71 struct linux_ebus *ebus;
72 struct linux_ebus_device *edev;
73 struct linux_ebus_child *child;
74
75 for_each_ebus(ebus) {
76 for_each_ebusdev(edev, ebus) {
77 if (!strcmp(edev->prom_name, "8042"))
78 goto edev_found;
79 }
80 }
81 return -1;
82
83 edev_found:
84 for_each_edevchild(edev, child) {
85 if (!strcmp(child->prom_name, OBP_PS2KBD_NAME1) ||
86 !strcmp(child->prom_name, OBP_PS2KBD_NAME2)) {
87 i8042_kbd_irq = child->irqs[0];
88 kbd_iobase =
89 ioremap(child->resource[0].start, 8);
90 }
91 if (!strcmp(child->prom_name, OBP_PS2MS_NAME1) ||
92 !strcmp(child->prom_name, OBP_PS2MS_NAME2))
93 i8042_aux_irq = child->irqs[0];
94 }
95 if (i8042_kbd_irq == -1 ||
96 i8042_aux_irq == -1) {
97 printk("i8042: Error, 8042 device lacks both kbd and "
98 "mouse nodes.\n");
99 return -1;
100 }
101 }
102
103 i8042_reset = 1;
104
105 return 0;
106#endif /* CONFIG_PCI */
107}
108
109static inline void i8042_platform_exit(void)
110{
111#ifdef CONFIG_PCI
112 iounmap(kbd_iobase);
113#endif
114}
115
116#endif /* _I8042_SPARCIO_H */
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
new file mode 100644
index 000000000000..f64867808fea
--- /dev/null
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -0,0 +1,333 @@
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
31static int i8042_kbd_irq;
32static 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
42static int i8042_command_reg = 0x64;
43static int i8042_data_reg = 0x60;
44
45
46static inline int i8042_read_data(void)
47{
48 return inb(I8042_DATA_REG);
49}
50
51static inline int i8042_read_status(void)
52{
53 return inb(I8042_STATUS_REG);
54}
55
56static inline void i8042_write_data(int val)
57{
58 outb(val, I8042_DATA_REG);
59}
60
61static 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
70static struct dmi_system_id __initdata i8042_dmi_noloop_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
90/*
91 * Some Fujitsu notebooks are ahving trouble with touhcpads if
92 * active multiplexing mode is activated. Luckily they don't have
93 * external PS/2 ports so we can safely disable it.
94 */
95static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
96 {
97 .ident = "Fujitsu Lifebook P7010/P7010D",
98 .matches = {
99 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
100 DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
101 },
102 },
103 {
104 .ident = "Fujitsu Lifebook P5020D",
105 .matches = {
106 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
107 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
108 },
109 },
110 {
111 .ident = "Fujitsu Lifebook S2000",
112 .matches = {
113 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
114 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
115 },
116 },
117 {
118 .ident = "Fujitsu T70H",
119 .matches = {
120 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
121 DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
122 },
123 },
124 { }
125};
126
127
128
129#endif
130
131
132#ifdef CONFIG_PNP
133#include <linux/pnp.h>
134
135static int i8042_pnp_kbd_registered;
136static int i8042_pnp_aux_registered;
137
138static int i8042_pnp_command_reg;
139static int i8042_pnp_data_reg;
140static int i8042_pnp_kbd_irq;
141static int i8042_pnp_aux_irq;
142
143static char i8042_pnp_kbd_name[32];
144static char i8042_pnp_aux_name[32];
145
146static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
147{
148 if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
149 i8042_pnp_data_reg = pnp_port_start(dev,0);
150
151 if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
152 i8042_pnp_command_reg = pnp_port_start(dev, 1);
153
154 if (pnp_irq_valid(dev,0))
155 i8042_pnp_kbd_irq = pnp_irq(dev, 0);
156
157 strncpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name));
158 if (strlen(pnp_dev_name(dev))) {
159 strncat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
160 strncat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
161 }
162
163 return 0;
164}
165
166static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
167{
168 if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
169 i8042_pnp_data_reg = pnp_port_start(dev,0);
170
171 if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
172 i8042_pnp_command_reg = pnp_port_start(dev, 1);
173
174 if (pnp_irq_valid(dev, 0))
175 i8042_pnp_aux_irq = pnp_irq(dev, 0);
176
177 strncpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name));
178 if (strlen(pnp_dev_name(dev))) {
179 strncat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
180 strncat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
181 }
182
183 return 0;
184}
185
186static struct pnp_device_id pnp_kbd_devids[] = {
187 { .id = "PNP0303", .driver_data = 0 },
188 { .id = "PNP030b", .driver_data = 0 },
189 { .id = "", },
190};
191
192static struct pnp_driver i8042_pnp_kbd_driver = {
193 .name = "i8042 kbd",
194 .id_table = pnp_kbd_devids,
195 .probe = i8042_pnp_kbd_probe,
196};
197
198static struct pnp_device_id pnp_aux_devids[] = {
199 { .id = "PNP0f03", .driver_data = 0 },
200 { .id = "PNP0f0b", .driver_data = 0 },
201 { .id = "PNP0f0e", .driver_data = 0 },
202 { .id = "PNP0f12", .driver_data = 0 },
203 { .id = "PNP0f13", .driver_data = 0 },
204 { .id = "PNP0f19", .driver_data = 0 },
205 { .id = "PNP0f1c", .driver_data = 0 },
206 { .id = "SYN0801", .driver_data = 0 },
207 { .id = "", },
208};
209
210static struct pnp_driver i8042_pnp_aux_driver = {
211 .name = "i8042 aux",
212 .id_table = pnp_aux_devids,
213 .probe = i8042_pnp_aux_probe,
214};
215
216static void i8042_pnp_exit(void)
217{
218 if (i8042_pnp_kbd_registered)
219 pnp_unregister_driver(&i8042_pnp_kbd_driver);
220
221 if (i8042_pnp_aux_registered)
222 pnp_unregister_driver(&i8042_pnp_aux_driver);
223}
224
225static int i8042_pnp_init(void)
226{
227 int result_kbd, result_aux;
228
229 if (i8042_nopnp) {
230 printk("i8042: PNP detection disabled\n");
231 return 0;
232 }
233
234 if ((result_kbd = pnp_register_driver(&i8042_pnp_kbd_driver)) >= 0)
235 i8042_pnp_kbd_registered = 1;
236 if ((result_aux = pnp_register_driver(&i8042_pnp_aux_driver)) >= 0)
237 i8042_pnp_aux_registered = 1;
238
239 if (result_kbd <= 0 && result_aux <= 0) {
240 i8042_pnp_exit();
241#if defined(__ia64__)
242 return -ENODEV;
243#else
244 printk(KERN_WARNING "PNP: No PS/2 controller found. Probing ports directly.\n");
245 return 0;
246#endif
247 }
248
249 if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
250 i8042_pnp_data_reg != i8042_data_reg) || !i8042_pnp_data_reg) {
251 printk(KERN_WARNING "PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
252 i8042_pnp_data_reg, i8042_data_reg);
253 i8042_pnp_data_reg = i8042_data_reg;
254 }
255
256 if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
257 i8042_pnp_command_reg != i8042_command_reg) || !i8042_pnp_command_reg) {
258 printk(KERN_WARNING "PNP: PS/2 controller has invalid command port %#x; using default %#x\n",
259 i8042_pnp_command_reg, i8042_command_reg);
260 i8042_pnp_command_reg = i8042_command_reg;
261 }
262
263 if (!i8042_pnp_kbd_irq) {
264 printk(KERN_WARNING "PNP: PS/2 controller doesn't have KBD irq; using default %#x\n", i8042_kbd_irq);
265 i8042_pnp_kbd_irq = i8042_kbd_irq;
266 }
267
268 if (result_aux > 0 && !i8042_pnp_aux_irq) {
269 printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq);
270 i8042_pnp_aux_irq = i8042_aux_irq;
271 }
272
273#if defined(__ia64__)
274 if (result_aux <= 0)
275 i8042_noaux = 1;
276#endif
277
278 i8042_data_reg = i8042_pnp_data_reg;
279 i8042_command_reg = i8042_pnp_command_reg;
280 i8042_kbd_irq = i8042_pnp_kbd_irq;
281 i8042_aux_irq = i8042_pnp_aux_irq;
282
283 printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %d%s%d\n",
284 i8042_pnp_kbd_name, (result_kbd > 0 && result_aux > 0) ? "," : "", i8042_pnp_aux_name,
285 i8042_data_reg, i8042_command_reg, i8042_kbd_irq,
286 (result_aux > 0) ? "," : "", i8042_aux_irq);
287
288 return 0;
289}
290
291#endif
292
293static inline int i8042_platform_init(void)
294{
295/*
296 * On ix86 platforms touching the i8042 data register region can do really
297 * bad things. Because of this the region is always reserved on ix86 boxes.
298 *
299 * if (!request_region(I8042_DATA_REG, 16, "i8042"))
300 * return -1;
301 */
302
303 i8042_kbd_irq = I8042_MAP_IRQ(1);
304 i8042_aux_irq = I8042_MAP_IRQ(12);
305
306#ifdef CONFIG_PNP
307 if (i8042_pnp_init())
308 return -1;
309#endif
310
311#if defined(__ia64__)
312 i8042_reset = 1;
313#endif
314
315#if defined(__i386__)
316 if (dmi_check_system(i8042_dmi_noloop_table))
317 i8042_noloop = 1;
318
319 if (dmi_check_system(i8042_dmi_nomux_table))
320 i8042_nomux = 1;
321#endif
322
323 return 0;
324}
325
326static inline void i8042_platform_exit(void)
327{
328#ifdef CONFIG_PNP
329 i8042_pnp_exit();
330#endif
331}
332
333#endif /* _I8042_X86IA64IO_H */
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
new file mode 100644
index 000000000000..8e63e464d361
--- /dev/null
+++ b/drivers/input/serio/i8042.c
@@ -0,0 +1,1116 @@
1/*
2 * i8042 keyboard and mouse controller driver for Linux
3 *
4 * Copyright (c) 1999-2004 Vojtech Pavlik
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12
13#include <linux/delay.h>
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/config.h>
19#include <linux/init.h>
20#include <linux/serio.h>
21#include <linux/err.h>
22#include <linux/rcupdate.h>
23
24#include <asm/io.h>
25
26MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
27MODULE_DESCRIPTION("i8042 keyboard and mouse controller driver");
28MODULE_LICENSE("GPL");
29
30static unsigned int i8042_noaux;
31module_param_named(noaux, i8042_noaux, bool, 0);
32MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
33
34static unsigned int i8042_nomux;
35module_param_named(nomux, i8042_nomux, bool, 0);
36MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
37
38static unsigned int i8042_unlock;
39module_param_named(unlock, i8042_unlock, bool, 0);
40MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
41
42static unsigned int i8042_reset;
43module_param_named(reset, i8042_reset, bool, 0);
44MODULE_PARM_DESC(reset, "Reset controller during init and cleanup.");
45
46static unsigned int i8042_direct;
47module_param_named(direct, i8042_direct, bool, 0);
48MODULE_PARM_DESC(direct, "Put keyboard port into non-translated mode.");
49
50static unsigned int i8042_dumbkbd;
51module_param_named(dumbkbd, i8042_dumbkbd, bool, 0);
52MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard");
53
54static unsigned int i8042_noloop;
55module_param_named(noloop, i8042_noloop, bool, 0);
56MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port");
57
58static unsigned int i8042_blink_frequency = 500;
59module_param_named(panicblink, i8042_blink_frequency, uint, 0600);
60MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics");
61
62#ifdef CONFIG_PNP
63static int i8042_nopnp;
64module_param_named(nopnp, i8042_nopnp, bool, 0);
65MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
66#endif
67
68#define DEBUG
69#ifdef DEBUG
70static int i8042_debug;
71module_param_named(debug, i8042_debug, bool, 0600);
72MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
73#endif
74
75__obsolete_setup("i8042_noaux");
76__obsolete_setup("i8042_nomux");
77__obsolete_setup("i8042_unlock");
78__obsolete_setup("i8042_reset");
79__obsolete_setup("i8042_direct");
80__obsolete_setup("i8042_dumbkbd");
81
82#include "i8042.h"
83
84static DEFINE_SPINLOCK(i8042_lock);
85
86struct i8042_port {
87 struct serio *serio;
88 int irq;
89 unsigned char disable;
90 unsigned char irqen;
91 unsigned char exists;
92 signed char mux;
93 char name[8];
94};
95
96#define I8042_KBD_PORT_NO 0
97#define I8042_AUX_PORT_NO 1
98#define I8042_MUX_PORT_NO 2
99#define I8042_NUM_PORTS (I8042_NUM_MUX_PORTS + 2)
100static struct i8042_port i8042_ports[I8042_NUM_PORTS] = {
101 {
102 .disable = I8042_CTR_KBDDIS,
103 .irqen = I8042_CTR_KBDINT,
104 .mux = -1,
105 .name = "KBD",
106 },
107 {
108 .disable = I8042_CTR_AUXDIS,
109 .irqen = I8042_CTR_AUXINT,
110 .mux = -1,
111 .name = "AUX",
112 }
113};
114
115static unsigned char i8042_initial_ctr;
116static unsigned char i8042_ctr;
117static unsigned char i8042_mux_open;
118static unsigned char i8042_mux_present;
119static struct timer_list i8042_timer;
120static struct platform_device *i8042_platform_device;
121
122
123/*
124 * Shared IRQ's require a device pointer, but this driver doesn't support
125 * multiple devices
126 */
127#define i8042_request_irq_cookie (&i8042_timer)
128
129static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
130
131/*
132 * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
133 * be ready for reading values from it / writing values to it.
134 * Called always with i8042_lock held.
135 */
136
137static int i8042_wait_read(void)
138{
139 int i = 0;
140 while ((~i8042_read_status() & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) {
141 udelay(50);
142 i++;
143 }
144 return -(i == I8042_CTL_TIMEOUT);
145}
146
147static int i8042_wait_write(void)
148{
149 int i = 0;
150 while ((i8042_read_status() & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) {
151 udelay(50);
152 i++;
153 }
154 return -(i == I8042_CTL_TIMEOUT);
155}
156
157/*
158 * i8042_flush() flushes all data that may be in the keyboard and mouse buffers
159 * of the i8042 down the toilet.
160 */
161
162static int i8042_flush(void)
163{
164 unsigned long flags;
165 unsigned char data, str;
166 int i = 0;
167
168 spin_lock_irqsave(&i8042_lock, flags);
169
170 while (((str = i8042_read_status()) & I8042_STR_OBF) && (i < I8042_BUFFER_SIZE)) {
171 udelay(50);
172 data = i8042_read_data();
173 i++;
174 dbg("%02x <- i8042 (flush, %s)", data,
175 str & I8042_STR_AUXDATA ? "aux" : "kbd");
176 }
177
178 spin_unlock_irqrestore(&i8042_lock, flags);
179
180 return i;
181}
182
183/*
184 * i8042_command() executes a command on the i8042. It also sends the input
185 * parameter(s) of the commands to it, and receives the output value(s). The
186 * parameters are to be stored in the param array, and the output is placed
187 * into the same array. The number of the parameters and output values is
188 * encoded in bits 8-11 of the command number.
189 */
190
191static int i8042_command(unsigned char *param, int command)
192{
193 unsigned long flags;
194 int retval = 0, i = 0;
195
196 if (i8042_noloop && command == I8042_CMD_AUX_LOOP)
197 return -1;
198
199 spin_lock_irqsave(&i8042_lock, flags);
200
201 retval = i8042_wait_write();
202 if (!retval) {
203 dbg("%02x -> i8042 (command)", command & 0xff);
204 i8042_write_command(command & 0xff);
205 }
206
207 if (!retval)
208 for (i = 0; i < ((command >> 12) & 0xf); i++) {
209 if ((retval = i8042_wait_write())) break;
210 dbg("%02x -> i8042 (parameter)", param[i]);
211 i8042_write_data(param[i]);
212 }
213
214 if (!retval)
215 for (i = 0; i < ((command >> 8) & 0xf); i++) {
216 if ((retval = i8042_wait_read())) break;
217 if (i8042_read_status() & I8042_STR_AUXDATA)
218 param[i] = ~i8042_read_data();
219 else
220 param[i] = i8042_read_data();
221 dbg("%02x <- i8042 (return)", param[i]);
222 }
223
224 spin_unlock_irqrestore(&i8042_lock, flags);
225
226 if (retval)
227 dbg(" -- i8042 (timeout)");
228
229 return retval;
230}
231
232/*
233 * i8042_kbd_write() sends a byte out through the keyboard interface.
234 */
235
236static int i8042_kbd_write(struct serio *port, unsigned char c)
237{
238 unsigned long flags;
239 int retval = 0;
240
241 spin_lock_irqsave(&i8042_lock, flags);
242
243 if(!(retval = i8042_wait_write())) {
244 dbg("%02x -> i8042 (kbd-data)", c);
245 i8042_write_data(c);
246 }
247
248 spin_unlock_irqrestore(&i8042_lock, flags);
249
250 return retval;
251}
252
253/*
254 * i8042_aux_write() sends a byte out through the aux interface.
255 */
256
257static int i8042_aux_write(struct serio *serio, unsigned char c)
258{
259 struct i8042_port *port = serio->port_data;
260 int retval;
261
262/*
263 * Send the byte out.
264 */
265
266 if (port->mux == -1)
267 retval = i8042_command(&c, I8042_CMD_AUX_SEND);
268 else
269 retval = i8042_command(&c, I8042_CMD_MUX_SEND + port->mux);
270
271/*
272 * Make sure the interrupt happens and the character is received even
273 * in the case the IRQ isn't wired, so that we can receive further
274 * characters later.
275 */
276
277 i8042_interrupt(0, NULL, NULL);
278 return retval;
279}
280
281/*
282 * i8042_activate_port() enables port on a chip.
283 */
284
285static int i8042_activate_port(struct i8042_port *port)
286{
287 if (!port->serio)
288 return -1;
289
290 i8042_flush();
291
292 /*
293 * Enable port again here because it is disabled if we are
294 * resuming (normally it is enabled already).
295 */
296 i8042_ctr &= ~port->disable;
297
298 i8042_ctr |= port->irqen;
299
300 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
301 i8042_ctr &= ~port->irqen;
302 return -1;
303 }
304
305 return 0;
306}
307
308
309/*
310 * i8042_open() is called when a port is open by the higher layer.
311 * It allocates the interrupt and calls i8042_enable_port.
312 */
313
314static int i8042_open(struct serio *serio)
315{
316 struct i8042_port *port = serio->port_data;
317
318 if (port->mux != -1)
319 if (i8042_mux_open++)
320 return 0;
321
322 if (request_irq(port->irq, i8042_interrupt,
323 SA_SHIRQ, "i8042", i8042_request_irq_cookie)) {
324 printk(KERN_ERR "i8042.c: Can't get irq %d for %s, unregistering the port.\n", port->irq, port->name);
325 goto irq_fail;
326 }
327
328 if (i8042_activate_port(port)) {
329 printk(KERN_ERR "i8042.c: Can't activate %s, unregistering the port\n", port->name);
330 goto activate_fail;
331 }
332
333 i8042_interrupt(0, NULL, NULL);
334
335 return 0;
336
337activate_fail:
338 free_irq(port->irq, i8042_request_irq_cookie);
339
340irq_fail:
341 serio_unregister_port_delayed(serio);
342
343 return -1;
344}
345
346/*
347 * i8042_close() frees the interrupt, so that it can possibly be used
348 * by another driver. We never know - if the user doesn't have a mouse,
349 * the BIOS could have used the AUX interrupt for PCI.
350 */
351
352static void i8042_close(struct serio *serio)
353{
354 struct i8042_port *port = serio->port_data;
355
356 if (port->mux != -1)
357 if (--i8042_mux_open)
358 return;
359
360 i8042_ctr &= ~port->irqen;
361
362 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
363 printk(KERN_WARNING "i8042.c: Can't write CTR while closing %s.\n", port->name);
364/*
365 * We still want to continue and free IRQ so if more data keeps coming in
366 * kernel will just ignore the irq.
367 */
368 }
369
370 free_irq(port->irq, i8042_request_irq_cookie);
371
372 i8042_flush();
373}
374
375/*
376 * i8042_start() is called by serio core when port is about to finish
377 * registering. It will mark port as existing so i8042_interrupt can
378 * start sending data through it.
379 */
380static int i8042_start(struct serio *serio)
381{
382 struct i8042_port *port = serio->port_data;
383
384 port->exists = 1;
385 mb();
386 return 0;
387}
388
389/*
390 * i8042_stop() marks serio port as non-existing so i8042_interrupt
391 * will not try to send data to the port that is about to go away.
392 * The function is called by serio core as part of unregister procedure.
393 */
394static void i8042_stop(struct serio *serio)
395{
396 struct i8042_port *port = serio->port_data;
397
398 port->exists = 0;
399 synchronize_kernel();
400 port->serio = NULL;
401}
402
403/*
404 * i8042_interrupt() is the most important function in this driver -
405 * it handles the interrupts from the i8042, and sends incoming bytes
406 * to the upper layers.
407 */
408
409static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
410{
411 struct i8042_port *port;
412 unsigned long flags;
413 unsigned char str, data;
414 unsigned int dfl;
415 unsigned int port_no;
416 int ret;
417
418 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
419
420 spin_lock_irqsave(&i8042_lock, flags);
421 str = i8042_read_status();
422 if (unlikely(~str & I8042_STR_OBF)) {
423 spin_unlock_irqrestore(&i8042_lock, flags);
424 if (irq) dbg("Interrupt %d, without any data", irq);
425 ret = 0;
426 goto out;
427 }
428 data = i8042_read_data();
429 spin_unlock_irqrestore(&i8042_lock, flags);
430
431 if (i8042_mux_present && (str & I8042_STR_AUXDATA)) {
432 static unsigned long last_transmit;
433 static unsigned char last_str;
434
435 dfl = 0;
436 if (str & I8042_STR_MUXERR) {
437 dbg("MUX error, status is %02x, data is %02x", str, data);
438 switch (data) {
439 default:
440/*
441 * When MUXERR condition is signalled the data register can only contain
442 * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately
443 * it is not always the case. Some KBC just get confused which port the
444 * data came from and signal error leaving the data intact. They _do not_
445 * revert to legacy mode (actually I've never seen KBC reverting to legacy
446 * mode yet, when we see one we'll add proper handling).
447 * Anyway, we will assume that the data came from the same serio last byte
448 * was transmitted (if transmission happened not too long ago).
449 */
450 if (time_before(jiffies, last_transmit + HZ/10)) {
451 str = last_str;
452 break;
453 }
454 /* fall through - report timeout */
455 case 0xfd:
456 case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break;
457 case 0xff: dfl = SERIO_PARITY; data = 0xfe; break;
458 }
459 }
460
461 port_no = I8042_MUX_PORT_NO + ((str >> 6) & 3);
462 last_str = str;
463 last_transmit = jiffies;
464 } else {
465
466 dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
467 ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0);
468
469 port_no = (str & I8042_STR_AUXDATA) ?
470 I8042_AUX_PORT_NO : I8042_KBD_PORT_NO;
471 }
472
473 port = &i8042_ports[port_no];
474
475 dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
476 data, port->name, irq,
477 dfl & SERIO_PARITY ? ", bad parity" : "",
478 dfl & SERIO_TIMEOUT ? ", timeout" : "");
479
480 if (likely(port->exists))
481 serio_interrupt(port->serio, data, dfl, regs);
482
483 ret = 1;
484out:
485 return IRQ_RETVAL(ret);
486}
487
488/*
489 * i8042_set_mux_mode checks whether the controller has an active
490 * multiplexor and puts the chip into Multiplexed (1) or Legacy (0) mode.
491 */
492
493static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
494{
495
496 unsigned char param;
497/*
498 * Get rid of bytes in the queue.
499 */
500
501 i8042_flush();
502
503/*
504 * Internal loopback test - send three bytes, they should come back from the
505 * mouse interface, the last should be version. Note that we negate mouseport
506 * command responses for the i8042_check_aux() routine.
507 */
508
509 param = 0xf0;
510 if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0x0f)
511 return -1;
512 param = mode ? 0x56 : 0xf6;
513 if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != (mode ? 0xa9 : 0x09))
514 return -1;
515 param = mode ? 0xa4 : 0xa5;
516 if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == (mode ? 0x5b : 0x5a))
517 return -1;
518
519 if (mux_version)
520 *mux_version = ~param;
521
522 return 0;
523}
524
525
526/*
527 * i8042_enable_mux_ports enables 4 individual AUX ports after
528 * the controller has been switched into Multiplexed mode
529 */
530
531static int i8042_enable_mux_ports(void)
532{
533 unsigned char param;
534 int i;
535/*
536 * Disable all muxed ports by disabling AUX.
537 */
538
539 i8042_ctr |= I8042_CTR_AUXDIS;
540 i8042_ctr &= ~I8042_CTR_AUXINT;
541
542 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
543 printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n");
544 return -1;
545 }
546
547/*
548 * Enable all muxed ports.
549 */
550
551 for (i = 0; i < 4; i++) {
552 i8042_command(&param, I8042_CMD_MUX_PFX + i);
553 i8042_command(&param, I8042_CMD_AUX_ENABLE);
554 }
555
556 return 0;
557}
558
559
560/*
561 * i8042_check_mux() checks whether the controller supports the PS/2 Active
562 * Multiplexing specification by Synaptics, Phoenix, Insyde and
563 * LCS/Telegraphics.
564 */
565
566static int __init i8042_check_mux(void)
567{
568 unsigned char mux_version;
569
570 if (i8042_set_mux_mode(1, &mux_version))
571 return -1;
572
573 /* Workaround for interference with USB Legacy emulation */
574 /* that causes a v10.12 MUX to be found. */
575 if (mux_version == 0xAC)
576 return -1;
577
578 printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
579 (mux_version >> 4) & 0xf, mux_version & 0xf);
580
581 if (i8042_enable_mux_ports())
582 return -1;
583
584 i8042_mux_present = 1;
585 return 0;
586}
587
588
589/*
590 * i8042_check_aux() applies as much paranoia as it can at detecting
591 * the presence of an AUX interface.
592 */
593
594static int __init i8042_check_aux(void)
595{
596 unsigned char param;
597 static int i8042_check_aux_cookie;
598
599/*
600 * Check if AUX irq is available. If it isn't, then there is no point
601 * in trying to detect AUX presence.
602 */
603
604 if (request_irq(i8042_ports[I8042_AUX_PORT_NO].irq, i8042_interrupt,
605 SA_SHIRQ, "i8042", &i8042_check_aux_cookie))
606 return -1;
607 free_irq(i8042_ports[I8042_AUX_PORT_NO].irq, &i8042_check_aux_cookie);
608
609/*
610 * Get rid of bytes in the queue.
611 */
612
613 i8042_flush();
614
615/*
616 * Internal loopback test - filters out AT-type i8042's. Unfortunately
617 * SiS screwed up and their 5597 doesn't support the LOOP command even
618 * though it has an AUX port.
619 */
620
621 param = 0x5a;
622 if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa5) {
623
624/*
625 * External connection test - filters out AT-soldered PS/2 i8042's
626 * 0x00 - no error, 0x01-0x03 - clock/data stuck, 0xff - general error
627 * 0xfa - no error on some notebooks which ignore the spec
628 * Because it's common for chipsets to return error on perfectly functioning
629 * AUX ports, we test for this only when the LOOP command failed.
630 */
631
632 if (i8042_command(&param, I8042_CMD_AUX_TEST)
633 || (param && param != 0xfa && param != 0xff))
634 return -1;
635 }
636
637/*
638 * Bit assignment test - filters out PS/2 i8042's in AT mode
639 */
640
641 if (i8042_command(&param, I8042_CMD_AUX_DISABLE))
642 return -1;
643 if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
644 printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");
645 printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n");
646 }
647
648 if (i8042_command(&param, I8042_CMD_AUX_ENABLE))
649 return -1;
650 if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
651 return -1;
652
653/*
654 * Disable the interface.
655 */
656
657 i8042_ctr |= I8042_CTR_AUXDIS;
658 i8042_ctr &= ~I8042_CTR_AUXINT;
659
660 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
661 return -1;
662
663 return 0;
664}
665
666
667/*
668 * i8042_port_register() marks the device as existing,
669 * registers it, and reports to the user.
670 */
671
672static int __init i8042_port_register(struct i8042_port *port)
673{
674 i8042_ctr &= ~port->disable;
675
676 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
677 printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
678 kfree(port->serio);
679 port->serio = NULL;
680 i8042_ctr |= port->disable;
681 return -1;
682 }
683
684 printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
685 port->name,
686 (unsigned long) I8042_DATA_REG,
687 (unsigned long) I8042_COMMAND_REG,
688 port->irq);
689
690 serio_register_port(port->serio);
691
692 return 0;
693}
694
695
696static void i8042_timer_func(unsigned long data)
697{
698 i8042_interrupt(0, NULL, NULL);
699}
700
701
702/*
703 * i8042_controller init initializes the i8042 controller, and,
704 * most importantly, sets it into non-xlated mode if that's
705 * desired.
706 */
707
708static int i8042_controller_init(void)
709{
710 unsigned long flags;
711
712/*
713 * Test the i8042. We need to know if it thinks it's working correctly
714 * before doing anything else.
715 */
716
717 if (i8042_flush() == I8042_BUFFER_SIZE) {
718 printk(KERN_ERR "i8042.c: No controller found.\n");
719 return -1;
720 }
721
722 if (i8042_reset) {
723
724 unsigned char param;
725
726 if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
727 printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
728 return -1;
729 }
730
731 if (param != I8042_RET_CTL_TEST) {
732 printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
733 param, I8042_RET_CTL_TEST);
734 return -1;
735 }
736 }
737
738/*
739 * Save the CTR for restoral on unload / reboot.
740 */
741
742 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
743 printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n");
744 return -1;
745 }
746
747 i8042_initial_ctr = i8042_ctr;
748
749/*
750 * Disable the keyboard interface and interrupt.
751 */
752
753 i8042_ctr |= I8042_CTR_KBDDIS;
754 i8042_ctr &= ~I8042_CTR_KBDINT;
755
756/*
757 * Handle keylock.
758 */
759
760 spin_lock_irqsave(&i8042_lock, flags);
761 if (~i8042_read_status() & I8042_STR_KEYLOCK) {
762 if (i8042_unlock)
763 i8042_ctr |= I8042_CTR_IGNKEYLOCK;
764 else
765 printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
766 }
767 spin_unlock_irqrestore(&i8042_lock, flags);
768
769/*
770 * If the chip is configured into nontranslated mode by the BIOS, don't
771 * bother enabling translating and be happy.
772 */
773
774 if (~i8042_ctr & I8042_CTR_XLATE)
775 i8042_direct = 1;
776
777/*
778 * Set nontranslated mode for the kbd interface if requested by an option.
779 * After this the kbd interface becomes a simple serial in/out, like the aux
780 * interface is. We don't do this by default, since it can confuse notebook
781 * BIOSes.
782 */
783
784 if (i8042_direct)
785 i8042_ctr &= ~I8042_CTR_XLATE;
786
787/*
788 * Write CTR back.
789 */
790
791 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
792 printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");
793 return -1;
794 }
795
796 return 0;
797}
798
799
800/*
801 * Reset the controller.
802 */
803static void i8042_controller_reset(void)
804{
805 unsigned char param;
806
807/*
808 * Reset the controller if requested.
809 */
810
811 if (i8042_reset)
812 if (i8042_command(&param, I8042_CMD_CTL_TEST))
813 printk(KERN_ERR "i8042.c: i8042 controller reset timeout.\n");
814
815/*
816 * Disable MUX mode if present.
817 */
818
819 if (i8042_mux_present)
820 i8042_set_mux_mode(0, NULL);
821
822/*
823 * Restore the original control register setting.
824 */
825
826 i8042_ctr = i8042_initial_ctr;
827
828 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
829 printk(KERN_WARNING "i8042.c: Can't restore CTR.\n");
830}
831
832
833/*
834 * Here we try to reset everything back to a state in which the BIOS will be
835 * able to talk to the hardware when rebooting.
836 */
837
838static void i8042_controller_cleanup(void)
839{
840 int i;
841
842 i8042_flush();
843
844/*
845 * Reset anything that is connected to the ports.
846 */
847
848 for (i = 0; i < I8042_NUM_PORTS; i++)
849 if (i8042_ports[i].exists)
850 serio_cleanup(i8042_ports[i].serio);
851
852 i8042_controller_reset();
853}
854
855
856/*
857 * i8042_panic_blink() will flash the keyboard LEDs and is called when
858 * kernel panics. Flashing LEDs is useful for users running X who may
859 * not see the console and will help distingushing panics from "real"
860 * lockups.
861 *
862 * Note that DELAY has a limit of 10ms so we will not get stuck here
863 * waiting for KBC to free up even if KBD interrupt is off
864 */
865
866#define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0)
867
868static long i8042_panic_blink(long count)
869{
870 long delay = 0;
871 static long last_blink;
872 static char led;
873
874 /*
875 * We expect frequency to be about 1/2s. KDB uses about 1s.
876 * Make sure they are different.
877 */
878 if (!i8042_blink_frequency)
879 return 0;
880 if (count - last_blink < i8042_blink_frequency)
881 return 0;
882
883 led ^= 0x01 | 0x04;
884 while (i8042_read_status() & I8042_STR_IBF)
885 DELAY;
886 i8042_write_data(0xed); /* set leds */
887 DELAY;
888 while (i8042_read_status() & I8042_STR_IBF)
889 DELAY;
890 DELAY;
891 i8042_write_data(led);
892 DELAY;
893 last_blink = count;
894 return delay;
895}
896
897#undef DELAY
898
899/*
900 * Here we try to restore the original BIOS settings
901 */
902
903static int i8042_suspend(struct device *dev, pm_message_t state, u32 level)
904{
905 if (level == SUSPEND_DISABLE) {
906 del_timer_sync(&i8042_timer);
907 i8042_controller_reset();
908 }
909
910 return 0;
911}
912
913
914/*
915 * Here we try to reset everything back to a state in which suspended
916 */
917
918static int i8042_resume(struct device *dev, u32 level)
919{
920 int i;
921
922 if (level != RESUME_ENABLE)
923 return 0;
924
925 if (i8042_controller_init()) {
926 printk(KERN_ERR "i8042: resume failed\n");
927 return -1;
928 }
929
930 if (i8042_mux_present)
931 if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports())
932 printk(KERN_WARNING "i8042: failed to resume active multiplexor, mouse won't work.\n");
933
934/*
935 * Activate all ports.
936 */
937
938 for (i = 0; i < I8042_NUM_PORTS; i++)
939 i8042_activate_port(&i8042_ports[i]);
940
941/*
942 * Restart timer (for polling "stuck" data)
943 */
944 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
945
946 panic_blink = i8042_panic_blink;
947
948 return 0;
949
950}
951
952/*
953 * We need to reset the 8042 back to original mode on system shutdown,
954 * because otherwise BIOSes will be confused.
955 */
956
957static void i8042_shutdown(struct device *dev)
958{
959 i8042_controller_cleanup();
960}
961
962static struct device_driver i8042_driver = {
963 .name = "i8042",
964 .bus = &platform_bus_type,
965 .suspend = i8042_suspend,
966 .resume = i8042_resume,
967 .shutdown = i8042_shutdown,
968};
969
970static void __init i8042_create_kbd_port(void)
971{
972 struct serio *serio;
973 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
974
975 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
976 if (serio) {
977 memset(serio, 0, sizeof(struct serio));
978 serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL;
979 serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write;
980 serio->open = i8042_open;
981 serio->close = i8042_close;
982 serio->start = i8042_start;
983 serio->stop = i8042_stop;
984 serio->port_data = port;
985 serio->dev.parent = &i8042_platform_device->dev;
986 strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
987 strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
988
989 port->serio = serio;
990 i8042_port_register(port);
991 }
992}
993
994static void __init i8042_create_aux_port(void)
995{
996 struct serio *serio;
997 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
998
999 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
1000 if (serio) {
1001 memset(serio, 0, sizeof(struct serio));
1002 serio->id.type = SERIO_8042;
1003 serio->write = i8042_aux_write;
1004 serio->open = i8042_open;
1005 serio->close = i8042_close;
1006 serio->start = i8042_start;
1007 serio->stop = i8042_stop;
1008 serio->port_data = port;
1009 serio->dev.parent = &i8042_platform_device->dev;
1010 strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
1011 strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
1012
1013 port->serio = serio;
1014 i8042_port_register(port);
1015 }
1016}
1017
1018static void __init i8042_create_mux_port(int index)
1019{
1020 struct serio *serio;
1021 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
1022
1023 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
1024 if (serio) {
1025 memset(serio, 0, sizeof(struct serio));
1026 serio->id.type = SERIO_8042;
1027 serio->write = i8042_aux_write;
1028 serio->open = i8042_open;
1029 serio->close = i8042_close;
1030 serio->start = i8042_start;
1031 serio->stop = i8042_stop;
1032 serio->port_data = port;
1033 serio->dev.parent = &i8042_platform_device->dev;
1034 snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
1035 snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
1036
1037 *port = i8042_ports[I8042_AUX_PORT_NO];
1038 port->exists = 0;
1039 snprintf(port->name, sizeof(port->name), "AUX%d", index);
1040 port->mux = index;
1041 port->serio = serio;
1042 i8042_port_register(port);
1043 }
1044}
1045
1046static int __init i8042_init(void)
1047{
1048 int i;
1049 int err;
1050
1051 dbg_init();
1052
1053 init_timer(&i8042_timer);
1054 i8042_timer.function = i8042_timer_func;
1055
1056 if (i8042_platform_init())
1057 return -EBUSY;
1058
1059 i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
1060 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
1061
1062 if (i8042_controller_init()) {
1063 i8042_platform_exit();
1064 return -ENODEV;
1065 }
1066
1067 err = driver_register(&i8042_driver);
1068 if (err) {
1069 i8042_platform_exit();
1070 return err;
1071 }
1072
1073 i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0);
1074 if (IS_ERR(i8042_platform_device)) {
1075 driver_unregister(&i8042_driver);
1076 i8042_platform_exit();
1077 return PTR_ERR(i8042_platform_device);
1078 }
1079
1080 if (!i8042_noaux && !i8042_check_aux()) {
1081 if (!i8042_nomux && !i8042_check_mux())
1082 for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
1083 i8042_create_mux_port(i);
1084 else
1085 i8042_create_aux_port();
1086 }
1087
1088 i8042_create_kbd_port();
1089
1090 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
1091
1092 return 0;
1093}
1094
1095static void __exit i8042_exit(void)
1096{
1097 int i;
1098
1099 i8042_controller_cleanup();
1100
1101 for (i = 0; i < I8042_NUM_PORTS; i++)
1102 if (i8042_ports[i].exists)
1103 serio_unregister_port(i8042_ports[i].serio);
1104
1105 del_timer_sync(&i8042_timer);
1106
1107 platform_device_unregister(i8042_platform_device);
1108 driver_unregister(&i8042_driver);
1109
1110 i8042_platform_exit();
1111
1112 panic_blink = NULL;
1113}
1114
1115module_init(i8042_init);
1116module_exit(i8042_exit);
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
new file mode 100644
index 000000000000..13835039a2a7
--- /dev/null
+++ b/drivers/input/serio/i8042.h
@@ -0,0 +1,133 @@
1#ifndef _I8042_H
2#define _I8042_H
3
4#include <linux/config.h>
5
6/*
7 * Copyright (c) 1999-2002 Vojtech Pavlik
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 */
13
14/*
15 * Arch-dependent inline functions and defines.
16 */
17
18#if defined(CONFIG_MACH_JAZZ)
19#include "i8042-jazzio.h"
20#elif defined(CONFIG_SGI_IP22)
21#include "i8042-ip22io.h"
22#elif defined(CONFIG_PPC)
23#include "i8042-ppcio.h"
24#elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
25#include "i8042-sparcio.h"
26#elif defined(CONFIG_X86) || defined(CONFIG_IA64)
27#include "i8042-x86ia64io.h"
28#else
29#include "i8042-io.h"
30#endif
31
32/*
33 * This is in 50us units, the time we wait for the i8042 to react. This
34 * has to be long enough for the i8042 itself to timeout on sending a byte
35 * to a non-existent mouse.
36 */
37
38#define I8042_CTL_TIMEOUT 10000
39
40/*
41 * When the device isn't opened and it's interrupts aren't used, we poll it at
42 * regular intervals to see if any characters arrived. If yes, we can start
43 * probing for any mouse / keyboard connected. This is the period of the
44 * polling.
45 */
46
47#define I8042_POLL_PERIOD HZ/20
48
49/*
50 * Status register bits.
51 */
52
53#define I8042_STR_PARITY 0x80
54#define I8042_STR_TIMEOUT 0x40
55#define I8042_STR_AUXDATA 0x20
56#define I8042_STR_KEYLOCK 0x10
57#define I8042_STR_CMDDAT 0x08
58#define I8042_STR_MUXERR 0x04
59#define I8042_STR_IBF 0x02
60#define I8042_STR_OBF 0x01
61
62/*
63 * Control register bits.
64 */
65
66#define I8042_CTR_KBDINT 0x01
67#define I8042_CTR_AUXINT 0x02
68#define I8042_CTR_IGNKEYLOCK 0x08
69#define I8042_CTR_KBDDIS 0x10
70#define I8042_CTR_AUXDIS 0x20
71#define I8042_CTR_XLATE 0x40
72
73/*
74 * Commands.
75 */
76
77#define I8042_CMD_CTL_RCTR 0x0120
78#define I8042_CMD_CTL_WCTR 0x1060
79#define I8042_CMD_CTL_TEST 0x01aa
80
81#define I8042_CMD_KBD_DISABLE 0x00ad
82#define I8042_CMD_KBD_ENABLE 0x00ae
83#define I8042_CMD_KBD_TEST 0x01ab
84#define I8042_CMD_KBD_LOOP 0x11d2
85
86#define I8042_CMD_AUX_DISABLE 0x00a7
87#define I8042_CMD_AUX_ENABLE 0x00a8
88#define I8042_CMD_AUX_TEST 0x01a9
89#define I8042_CMD_AUX_SEND 0x10d4
90#define I8042_CMD_AUX_LOOP 0x11d3
91
92#define I8042_CMD_MUX_PFX 0x0090
93#define I8042_CMD_MUX_SEND 0x1090
94
95/*
96 * Return codes.
97 */
98
99#define I8042_RET_CTL_TEST 0x55
100
101/*
102 * Expected maximum internal i8042 buffer size. This is used for flushing
103 * the i8042 buffers.
104 */
105
106#define I8042_BUFFER_SIZE 16
107
108/*
109 * Number of AUX ports on controllers supporting active multiplexing
110 * specification
111 */
112
113#define I8042_NUM_MUX_PORTS 4
114
115/*
116 * Debug.
117 */
118
119#ifdef DEBUG
120static unsigned long i8042_start_time;
121#define dbg_init() do { i8042_start_time = jiffies; } while (0)
122#define dbg(format, arg...) \
123 do { \
124 if (i8042_debug) \
125 printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" , \
126 ## arg, (int) (jiffies - i8042_start_time)); \
127 } while (0)
128#else
129#define dbg_init() do { } while (0)
130#define dbg(format, arg...) do {} while (0)
131#endif
132
133#endif /* _I8042_H */
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
new file mode 100644
index 000000000000..c978657068c5
--- /dev/null
+++ b/drivers/input/serio/libps2.c
@@ -0,0 +1,305 @@
1/*
2 * PS/2 driver library
3 *
4 * Copyright (c) 1999-2002 Vojtech Pavlik
5 * Copyright (c) 2004 Dmitry Torokhov
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 */
13
14#include <linux/delay.h>
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/slab.h>
18#include <linux/interrupt.h>
19#include <linux/input.h>
20#include <linux/serio.h>
21#include <linux/init.h>
22#include <linux/libps2.h>
23
24#define DRIVER_DESC "PS/2 driver library"
25
26MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
27MODULE_DESCRIPTION("PS/2 driver library");
28MODULE_LICENSE("GPL");
29
30EXPORT_SYMBOL(ps2_init);
31EXPORT_SYMBOL(ps2_sendbyte);
32EXPORT_SYMBOL(ps2_command);
33EXPORT_SYMBOL(ps2_schedule_command);
34EXPORT_SYMBOL(ps2_handle_ack);
35EXPORT_SYMBOL(ps2_handle_response);
36EXPORT_SYMBOL(ps2_cmd_aborted);
37
38/* Work structure to schedule execution of a command */
39struct ps2work {
40 struct work_struct work;
41 struct ps2dev *ps2dev;
42 int command;
43 unsigned char param[0];
44};
45
46
47/*
48 * ps2_sendbyte() sends a byte to the mouse, and waits for acknowledge.
49 * It doesn't handle retransmission, though it could - because when there would
50 * be need for retransmissions, the mouse has to be replaced anyway.
51 *
52 * ps2_sendbyte() can only be called from a process context
53 */
54
55int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
56{
57 serio_pause_rx(ps2dev->serio);
58 ps2dev->nak = 1;
59 ps2dev->flags |= PS2_FLAG_ACK;
60 serio_continue_rx(ps2dev->serio);
61
62 if (serio_write(ps2dev->serio, byte) == 0)
63 wait_event_timeout(ps2dev->wait,
64 !(ps2dev->flags & PS2_FLAG_ACK),
65 msecs_to_jiffies(timeout));
66
67 serio_pause_rx(ps2dev->serio);
68 ps2dev->flags &= ~PS2_FLAG_ACK;
69 serio_continue_rx(ps2dev->serio);
70
71 return -ps2dev->nak;
72}
73
74/*
75 * ps2_command() sends a command and its parameters to the mouse,
76 * then waits for the response and puts it in the param array.
77 *
78 * ps2_command() can only be called from a process context
79 */
80
81int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
82{
83 int timeout;
84 int send = (command >> 12) & 0xf;
85 int receive = (command >> 8) & 0xf;
86 int rc = -1;
87 int i;
88
89 down(&ps2dev->cmd_sem);
90
91 serio_pause_rx(ps2dev->serio);
92 ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
93 ps2dev->cmdcnt = receive;
94 if (receive && param)
95 for (i = 0; i < receive; i++)
96 ps2dev->cmdbuf[(receive - 1) - i] = param[i];
97 serio_continue_rx(ps2dev->serio);
98
99 /*
100 * Some devices (Synaptics) peform the reset before
101 * ACKing the reset command, and so it can take a long
102 * time before the ACK arrrives.
103 */
104 if (command & 0xff)
105 if (ps2_sendbyte(ps2dev, command & 0xff,
106 command == PS2_CMD_RESET_BAT ? 1000 : 200))
107 goto out;
108
109 for (i = 0; i < send; i++)
110 if (ps2_sendbyte(ps2dev, param[i], 200))
111 goto out;
112
113 /*
114 * The reset command takes a long time to execute.
115 */
116 timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
117
118 timeout = wait_event_timeout(ps2dev->wait,
119 !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
120
121 if (ps2dev->cmdcnt && timeout > 0) {
122
123 if (command == PS2_CMD_RESET_BAT && timeout > msecs_to_jiffies(100)) {
124 /*
125 * Device has sent the first response byte
126 * after a reset command, reset is thus done,
127 * shorten the timeout. The next byte will come
128 * soon (keyboard) or not at all (mouse).
129 */
130 timeout = msecs_to_jiffies(100);
131 }
132
133 if (command == PS2_CMD_GETID &&
134 ps2dev->cmdbuf[receive - 1] != 0xab && /* Regular keyboards */
135 ps2dev->cmdbuf[receive - 1] != 0xac && /* NCD Sun keyboard */
136 ps2dev->cmdbuf[receive - 1] != 0x2b && /* Trust keyboard, translated */
137 ps2dev->cmdbuf[receive - 1] != 0x5d && /* Trust keyboard */
138 ps2dev->cmdbuf[receive - 1] != 0x60 && /* NMB SGI keyboard, translated */
139 ps2dev->cmdbuf[receive - 1] != 0x47) { /* NMB SGI keyboard */
140 /*
141 * Device behind the port is not a keyboard
142 * so we don't need to wait for the 2nd byte
143 * of ID response.
144 */
145 serio_pause_rx(ps2dev->serio);
146 ps2dev->flags = ps2dev->cmdcnt = 0;
147 serio_continue_rx(ps2dev->serio);
148 }
149
150 wait_event_timeout(ps2dev->wait,
151 !(ps2dev->flags & PS2_FLAG_CMD), timeout);
152 }
153
154 if (param)
155 for (i = 0; i < receive; i++)
156 param[i] = ps2dev->cmdbuf[(receive - 1) - i];
157
158 if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1))
159 goto out;
160
161 rc = 0;
162
163out:
164 serio_pause_rx(ps2dev->serio);
165 ps2dev->flags = 0;
166 serio_continue_rx(ps2dev->serio);
167
168 up(&ps2dev->cmd_sem);
169 return rc;
170}
171
172/*
173 * ps2_execute_scheduled_command() sends a command, previously scheduled by
174 * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.)
175 */
176
177static void ps2_execute_scheduled_command(void *data)
178{
179 struct ps2work *ps2work = data;
180
181 ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command);
182 kfree(ps2work);
183}
184
185/*
186 * ps2_schedule_command() allows to schedule delayed execution of a PS/2
187 * command and can be used to issue a command from an interrupt or softirq
188 * context.
189 */
190
191int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command)
192{
193 struct ps2work *ps2work;
194 int send = (command >> 12) & 0xf;
195 int receive = (command >> 8) & 0xf;
196
197 if (!(ps2work = kmalloc(sizeof(struct ps2work) + max(send, receive), GFP_ATOMIC)))
198 return -1;
199
200 memset(ps2work, 0, sizeof(struct ps2work));
201 ps2work->ps2dev = ps2dev;
202 ps2work->command = command;
203 memcpy(ps2work->param, param, send);
204 INIT_WORK(&ps2work->work, ps2_execute_scheduled_command, ps2work);
205
206 if (!schedule_work(&ps2work->work)) {
207 kfree(ps2work);
208 return -1;
209 }
210
211 return 0;
212}
213
214/*
215 * ps2_init() initializes ps2dev structure
216 */
217
218void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
219{
220 init_MUTEX(&ps2dev->cmd_sem);
221 init_waitqueue_head(&ps2dev->wait);
222 ps2dev->serio = serio;
223}
224
225/*
226 * ps2_handle_ack() is supposed to be used in interrupt handler
227 * to properly process ACK/NAK of a command from a PS/2 device.
228 */
229
230int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
231{
232 switch (data) {
233 case PS2_RET_ACK:
234 ps2dev->nak = 0;
235 break;
236
237 case PS2_RET_NAK:
238 ps2dev->nak = 1;
239 break;
240
241 /*
242 * Workaround for mice which don't ACK the Get ID command.
243 * These are valid mouse IDs that we recognize.
244 */
245 case 0x00:
246 case 0x03:
247 case 0x04:
248 if (ps2dev->flags & PS2_FLAG_WAITID) {
249 ps2dev->nak = 0;
250 break;
251 }
252 /* Fall through */
253 default:
254 return 0;
255 }
256
257
258 if (!ps2dev->nak && ps2dev->cmdcnt)
259 ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
260
261 ps2dev->flags &= ~PS2_FLAG_ACK;
262 wake_up(&ps2dev->wait);
263
264 if (data != PS2_RET_ACK)
265 ps2_handle_response(ps2dev, data);
266
267 return 1;
268}
269
270/*
271 * ps2_handle_response() is supposed to be used in interrupt handler
272 * to properly store device's response to a command and notify process
273 * waiting for completion of the command.
274 */
275
276int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data)
277{
278 if (ps2dev->cmdcnt)
279 ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
280
281 if (ps2dev->flags & PS2_FLAG_CMD1) {
282 ps2dev->flags &= ~PS2_FLAG_CMD1;
283 if (ps2dev->cmdcnt)
284 wake_up(&ps2dev->wait);
285 }
286
287 if (!ps2dev->cmdcnt) {
288 ps2dev->flags &= ~PS2_FLAG_CMD;
289 wake_up(&ps2dev->wait);
290 }
291
292 return 1;
293}
294
295void ps2_cmd_aborted(struct ps2dev *ps2dev)
296{
297 if (ps2dev->flags & PS2_FLAG_ACK)
298 ps2dev->nak = 1;
299
300 if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
301 wake_up(&ps2dev->wait);
302
303 ps2dev->flags = 0;
304}
305
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
new file mode 100644
index 000000000000..9880fc145d90
--- /dev/null
+++ b/drivers/input/serio/maceps2.c
@@ -0,0 +1,176 @@
1/*
2 * SGI O2 MACE PS2 controller driver for linux
3 *
4 * Copyright (C) 2002 Vivien Chappelier
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation
9 */
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/serio.h>
13#include <linux/errno.h>
14#include <linux/interrupt.h>
15#include <linux/ioport.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/slab.h>
19#include <linux/spinlock.h>
20#include <linux/err.h>
21
22#include <asm/io.h>
23#include <asm/irq.h>
24#include <asm/system.h>
25#include <asm/ip32/mace.h>
26#include <asm/ip32/ip32_ints.h>
27
28MODULE_AUTHOR("Vivien Chappelier <vivien.chappelier@linux-mips.org");
29MODULE_DESCRIPTION("SGI O2 MACE PS2 controller driver");
30MODULE_LICENSE("GPL");
31
32#define MACE_PS2_TIMEOUT 10000 /* in 50us unit */
33
34#define PS2_STATUS_CLOCK_SIGNAL BIT(0) /* external clock signal */
35#define PS2_STATUS_CLOCK_INHIBIT BIT(1) /* clken output signal */
36#define PS2_STATUS_TX_INPROGRESS BIT(2) /* transmission in progress */
37#define PS2_STATUS_TX_EMPTY BIT(3) /* empty transmit buffer */
38#define PS2_STATUS_RX_FULL BIT(4) /* full receive buffer */
39#define PS2_STATUS_RX_INPROGRESS BIT(5) /* reception in progress */
40#define PS2_STATUS_ERROR_PARITY BIT(6) /* parity error */
41#define PS2_STATUS_ERROR_FRAMING BIT(7) /* framing error */
42
43#define PS2_CONTROL_TX_CLOCK_DISABLE BIT(0) /* inhibit clock signal after TX */
44#define PS2_CONTROL_TX_ENABLE BIT(1) /* transmit enable */
45#define PS2_CONTROL_TX_INT_ENABLE BIT(2) /* enable transmit interrupt */
46#define PS2_CONTROL_RX_INT_ENABLE BIT(3) /* enable receive interrupt */
47#define PS2_CONTROL_RX_CLOCK_ENABLE BIT(4) /* pause reception if set to 0 */
48#define PS2_CONTROL_RESET BIT(5) /* reset */
49
50struct maceps2_data {
51 struct mace_ps2port *port;
52 int irq;
53};
54
55static struct maceps2_data port_data[2];
56static struct serio *maceps2_port[2];
57static struct platform_device *maceps2_device;
58
59static int maceps2_write(struct serio *dev, unsigned char val)
60{
61 struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
62 unsigned int timeout = MACE_PS2_TIMEOUT;
63
64 do {
65 if (port->status & PS2_STATUS_TX_EMPTY) {
66 port->tx = val;
67 return 0;
68 }
69 udelay(50);
70 } while (timeout--);
71
72 return -1;
73}
74
75static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
76 struct pt_regs *regs)
77{
78 struct serio *dev = dev_id;
79 struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
80 unsigned long byte;
81
82 if (port->status & PS2_STATUS_RX_FULL) {
83 byte = port->rx;
84 serio_interrupt(dev, byte & 0xff, 0, regs);
85 }
86
87 return IRQ_HANDLED;
88}
89
90static int maceps2_open(struct serio *dev)
91{
92 struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
93
94 if (request_irq(data->irq, maceps2_interrupt, 0, "PS2 port", dev)) {
95 printk(KERN_ERR "Could not allocate PS/2 IRQ\n");
96 return -EBUSY;
97 }
98
99 /* Reset port */
100 data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
101 udelay(100);
102
103 /* Enable interrupts */
104 data->port->control = PS2_CONTROL_RX_CLOCK_ENABLE |
105 PS2_CONTROL_TX_ENABLE |
106 PS2_CONTROL_RX_INT_ENABLE;
107
108 return 0;
109}
110
111static void maceps2_close(struct serio *dev)
112{
113 struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
114
115 data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
116 udelay(100);
117 free_irq(data->irq, dev);
118}
119
120
121static struct serio * __init maceps2_allocate_port(int idx)
122{
123 struct serio *serio;
124
125 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
126 if (serio) {
127 memset(serio, 0, sizeof(struct serio));
128 serio->id.type = SERIO_8042;
129 serio->write = maceps2_write;
130 serio->open = maceps2_open;
131 serio->close = maceps2_close;
132 snprintf(serio->name, sizeof(serio->name), "MACE PS/2 port%d", idx);
133 snprintf(serio->phys, sizeof(serio->phys), "mace/serio%d", idx);
134 serio->port_data = &port_data[idx];
135 serio->dev.parent = &maceps2_device->dev;
136 }
137
138 return serio;
139}
140
141
142static int __init maceps2_init(void)
143{
144 maceps2_device = platform_device_register_simple("maceps2", -1, NULL, 0);
145 if (IS_ERR(maceps2_device))
146 return PTR_ERR(maceps2_device);
147
148 port_data[0].port = &mace->perif.ps2.keyb;
149 port_data[0].irq = MACEISA_KEYB_IRQ;
150 port_data[1].port = &mace->perif.ps2.mouse;
151 port_data[1].irq = MACEISA_MOUSE_IRQ;
152
153 maceps2_port[0] = maceps2_allocate_port(0);
154 maceps2_port[1] = maceps2_allocate_port(1);
155 if (!maceps2_port[0] || !maceps2_port[1]) {
156 kfree(maceps2_port[0]);
157 kfree(maceps2_port[1]);
158 platform_device_unregister(maceps2_device);
159 return -ENOMEM;
160 }
161
162 serio_register_port(maceps2_port[0]);
163 serio_register_port(maceps2_port[1]);
164
165 return 0;
166}
167
168static void __exit maceps2_exit(void)
169{
170 serio_unregister_port(maceps2_port[0]);
171 serio_unregister_port(maceps2_port[1]);
172 platform_device_unregister(maceps2_device);
173}
174
175module_init(maceps2_init);
176module_exit(maceps2_exit);
diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
new file mode 100644
index 000000000000..1d15c2819818
--- /dev/null
+++ b/drivers/input/serio/parkbd.c
@@ -0,0 +1,218 @@
1/*
2 * Parallel port to Keyboard port adapter driver for Linux
3 *
4 * Copyright (c) 1999-2004 Vojtech Pavlik
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12
13/*
14 * To connect an AT or XT keyboard to the parallel port, a fairly simple adapter
15 * can be made:
16 *
17 * Parallel port Keyboard port
18 *
19 * +5V --------------------- +5V (4)
20 *
21 * ______
22 * +5V -------|______|--.
23 * |
24 * ACK (10) ------------|
25 * |--- KBD CLOCK (5)
26 * STROBE (1) ---|<|----'
27 *
28 * ______
29 * +5V -------|______|--.
30 * |
31 * BUSY (11) -----------|
32 * |--- KBD DATA (1)
33 * AUTOFD (14) --|<|----'
34 *
35 * GND (18-25) ------------- GND (3)
36 *
37 * The diodes can be fairly any type, and the resistors should be somewhere
38 * around 5 kOhm, but the adapter will likely work without the resistors,
39 * too.
40 *
41 * The +5V source can be taken either from USB, from mouse or keyboard ports,
42 * or from a joystick port. Unfortunately, the parallel port of a PC doesn't
43 * have a +5V pin, and feeding the keyboard from signal pins is out of question
44 * with 300 mA power reqirement of a typical AT keyboard.
45 */
46
47#include <linux/module.h>
48#include <linux/parport.h>
49#include <linux/init.h>
50#include <linux/serio.h>
51
52MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
53MODULE_DESCRIPTION("Parallel port to Keyboard port adapter driver");
54MODULE_LICENSE("GPL");
55
56static unsigned int parkbd_pp_no;
57module_param_named(port, parkbd_pp_no, int, 0);
58MODULE_PARM_DESC(port, "Parallel port the adapter is connected to (default is 0)");
59
60static unsigned int parkbd_mode = SERIO_8042;
61module_param_named(mode, parkbd_mode, uint, 0);
62MODULE_PARM_DESC(mode, "Mode of operation: XT = 0/AT = 1 (default)");
63
64#define PARKBD_CLOCK 0x01 /* Strobe & Ack */
65#define PARKBD_DATA 0x02 /* AutoFd & Busy */
66
67static int parkbd_buffer;
68static int parkbd_counter;
69static unsigned long parkbd_last;
70static int parkbd_writing;
71static unsigned long parkbd_start;
72
73static struct pardevice *parkbd_dev;
74static struct serio *parkbd_port;
75
76static int parkbd_readlines(void)
77{
78 return (parport_read_status(parkbd_dev->port) >> 6) ^ 2;
79}
80
81static void parkbd_writelines(int data)
82{
83 parport_write_control(parkbd_dev->port, (~data & 3) | 0x10);
84}
85
86static int parkbd_write(struct serio *port, unsigned char c)
87{
88 unsigned char p;
89
90 if (!parkbd_mode) return -1;
91
92 p = c ^ (c >> 4);
93 p = p ^ (p >> 2);
94 p = p ^ (p >> 1);
95
96 parkbd_counter = 0;
97 parkbd_writing = 1;
98 parkbd_buffer = c | (((int) (~p & 1)) << 8) | 0x600;
99
100 parkbd_writelines(2);
101
102 return 0;
103}
104
105static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
106{
107
108 if (parkbd_writing) {
109
110 if (parkbd_counter && ((parkbd_counter == 11) || time_after(jiffies, parkbd_last + HZ/100))) {
111 parkbd_counter = 0;
112 parkbd_buffer = 0;
113 parkbd_writing = 0;
114 parkbd_writelines(3);
115 return;
116 }
117
118 parkbd_writelines(((parkbd_buffer >> parkbd_counter++) & 1) | 2);
119
120 if (parkbd_counter == 11) {
121 parkbd_counter = 0;
122 parkbd_buffer = 0;
123 parkbd_writing = 0;
124 parkbd_writelines(3);
125 }
126
127 } else {
128
129 if ((parkbd_counter == parkbd_mode + 10) || time_after(jiffies, parkbd_last + HZ/100)) {
130 parkbd_counter = 0;
131 parkbd_buffer = 0;
132 }
133
134 parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;
135
136 if (parkbd_counter == parkbd_mode + 10)
137 serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
138 }
139
140 parkbd_last = jiffies;
141}
142
143static int parkbd_getport(void)
144{
145 struct parport *pp;
146
147 pp = parport_find_number(parkbd_pp_no);
148
149 if (pp == NULL) {
150 printk(KERN_ERR "parkbd: no such parport\n");
151 return -ENODEV;
152 }
153
154 parkbd_dev = parport_register_device(pp, "parkbd", NULL, NULL, parkbd_interrupt, PARPORT_DEV_EXCL, NULL);
155 parport_put_port(pp);
156
157 if (!parkbd_dev)
158 return -ENODEV;
159
160 if (parport_claim(parkbd_dev)) {
161 parport_unregister_device(parkbd_dev);
162 return -EBUSY;
163 }
164
165 parkbd_start = jiffies;
166
167 return 0;
168}
169
170static struct serio * __init parkbd_allocate_serio(void)
171{
172 struct serio *serio;
173
174 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
175 if (serio) {
176 memset(serio, 0, sizeof(struct serio));
177 serio->id.type = parkbd_mode;
178 serio->write = parkbd_write,
179 strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name));
180 snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", parkbd_dev->port->name);
181 }
182
183 return serio;
184}
185
186static int __init parkbd_init(void)
187{
188 int err;
189
190 err = parkbd_getport();
191 if (err)
192 return err;
193
194 parkbd_port = parkbd_allocate_serio();
195 if (!parkbd_port) {
196 parport_release(parkbd_dev);
197 return -ENOMEM;
198 }
199
200 parkbd_writelines(3);
201
202 serio_register_port(parkbd_port);
203
204 printk(KERN_INFO "serio: PARKBD %s adapter on %s\n",
205 parkbd_mode ? "AT" : "XT", parkbd_dev->port->name);
206
207 return 0;
208}
209
210static void __exit parkbd_exit(void)
211{
212 parport_release(parkbd_dev);
213 serio_unregister_port(parkbd_port);
214 parport_unregister_device(parkbd_dev);
215}
216
217module_init(parkbd_init);
218module_exit(parkbd_exit);
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
new file mode 100644
index 000000000000..1e139c5e59de
--- /dev/null
+++ b/drivers/input/serio/pcips2.c
@@ -0,0 +1,234 @@
1/*
2 * linux/drivers/input/serio/pcips2.c
3 *
4 * Copyright (C) 2003 Russell King, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License.
9 *
10 * I'm not sure if this is a generic PS/2 PCI interface or specific to
11 * the Mobility Electronics docking station.
12 */
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/ioport.h>
16#include <linux/input.h>
17#include <linux/pci.h>
18#include <linux/init.h>
19#include <linux/serio.h>
20#include <linux/delay.h>
21#include <asm/io.h>
22
23#define PS2_CTRL (0)
24#define PS2_STATUS (1)
25#define PS2_DATA (2)
26
27#define PS2_CTRL_CLK (1<<0)
28#define PS2_CTRL_DAT (1<<1)
29#define PS2_CTRL_TXIRQ (1<<2)
30#define PS2_CTRL_ENABLE (1<<3)
31#define PS2_CTRL_RXIRQ (1<<4)
32
33#define PS2_STAT_CLK (1<<0)
34#define PS2_STAT_DAT (1<<1)
35#define PS2_STAT_PARITY (1<<2)
36#define PS2_STAT_RXFULL (1<<5)
37#define PS2_STAT_TXBUSY (1<<6)
38#define PS2_STAT_TXEMPTY (1<<7)
39
40struct pcips2_data {
41 struct serio *io;
42 unsigned int base;
43 struct pci_dev *dev;
44};
45
46static int pcips2_write(struct serio *io, unsigned char val)
47{
48 struct pcips2_data *ps2if = io->port_data;
49 unsigned int stat;
50
51 do {
52 stat = inb(ps2if->base + PS2_STATUS);
53 cpu_relax();
54 } while (!(stat & PS2_STAT_TXEMPTY));
55
56 outb(val, ps2if->base + PS2_DATA);
57
58 return 0;
59}
60
61static irqreturn_t pcips2_interrupt(int irq, void *devid, struct pt_regs *regs)
62{
63 struct pcips2_data *ps2if = devid;
64 unsigned char status, scancode;
65 int handled = 0;
66
67 do {
68 unsigned int flag;
69
70 status = inb(ps2if->base + PS2_STATUS);
71 if (!(status & PS2_STAT_RXFULL))
72 break;
73 handled = 1;
74 scancode = inb(ps2if->base + PS2_DATA);
75 if (status == 0xff && scancode == 0xff)
76 break;
77
78 flag = (status & PS2_STAT_PARITY) ? 0 : SERIO_PARITY;
79
80 if (hweight8(scancode) & 1)
81 flag ^= SERIO_PARITY;
82
83 serio_interrupt(ps2if->io, scancode, flag, regs);
84 } while (1);
85 return IRQ_RETVAL(handled);
86}
87
88static void pcips2_flush_input(struct pcips2_data *ps2if)
89{
90 unsigned char status, scancode;
91
92 do {
93 status = inb(ps2if->base + PS2_STATUS);
94 if (!(status & PS2_STAT_RXFULL))
95 break;
96 scancode = inb(ps2if->base + PS2_DATA);
97 if (status == 0xff && scancode == 0xff)
98 break;
99 } while (1);
100}
101
102static int pcips2_open(struct serio *io)
103{
104 struct pcips2_data *ps2if = io->port_data;
105 int ret, val = 0;
106
107 outb(PS2_CTRL_ENABLE, ps2if->base);
108 pcips2_flush_input(ps2if);
109
110 ret = request_irq(ps2if->dev->irq, pcips2_interrupt, SA_SHIRQ,
111 "pcips2", ps2if);
112 if (ret == 0)
113 val = PS2_CTRL_ENABLE | PS2_CTRL_RXIRQ;
114
115 outb(val, ps2if->base);
116
117 return ret;
118}
119
120static void pcips2_close(struct serio *io)
121{
122 struct pcips2_data *ps2if = io->port_data;
123
124 outb(0, ps2if->base);
125
126 free_irq(ps2if->dev->irq, ps2if);
127}
128
129static int __devinit pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id)
130{
131 struct pcips2_data *ps2if;
132 struct serio *serio;
133 int ret;
134
135 ret = pci_enable_device(dev);
136 if (ret)
137 goto out;
138
139 ret = pci_request_regions(dev, "pcips2");
140 if (ret)
141 goto disable;
142
143 ps2if = kmalloc(sizeof(struct pcips2_data), GFP_KERNEL);
144 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
145 if (!ps2if || !serio) {
146 ret = -ENOMEM;
147 goto release;
148 }
149
150 memset(ps2if, 0, sizeof(struct pcips2_data));
151 memset(serio, 0, sizeof(struct serio));
152
153 serio->id.type = SERIO_8042;
154 serio->write = pcips2_write;
155 serio->open = pcips2_open;
156 serio->close = pcips2_close;
157 strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
158 strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
159 serio->port_data = ps2if;
160 serio->dev.parent = &dev->dev;
161 ps2if->io = serio;
162 ps2if->dev = dev;
163 ps2if->base = pci_resource_start(dev, 0);
164
165 pci_set_drvdata(dev, ps2if);
166
167 serio_register_port(ps2if->io);
168 return 0;
169
170 release:
171 kfree(ps2if);
172 kfree(serio);
173 pci_release_regions(dev);
174 disable:
175 pci_disable_device(dev);
176 out:
177 return ret;
178}
179
180static void __devexit pcips2_remove(struct pci_dev *dev)
181{
182 struct pcips2_data *ps2if = pci_get_drvdata(dev);
183
184 serio_unregister_port(ps2if->io);
185 pci_set_drvdata(dev, NULL);
186 kfree(ps2if);
187 pci_release_regions(dev);
188 pci_disable_device(dev);
189}
190
191static struct pci_device_id pcips2_ids[] = {
192 {
193 .vendor = 0x14f2, /* MOBILITY */
194 .device = 0x0123, /* Keyboard */
195 .subvendor = PCI_ANY_ID,
196 .subdevice = PCI_ANY_ID,
197 .class = PCI_CLASS_INPUT_KEYBOARD << 8,
198 .class_mask = 0xffff00,
199 },
200 {
201 .vendor = 0x14f2, /* MOBILITY */
202 .device = 0x0124, /* Mouse */
203 .subvendor = PCI_ANY_ID,
204 .subdevice = PCI_ANY_ID,
205 .class = PCI_CLASS_INPUT_MOUSE << 8,
206 .class_mask = 0xffff00,
207 },
208 { 0, }
209};
210
211static struct pci_driver pcips2_driver = {
212 .name = "pcips2",
213 .id_table = pcips2_ids,
214 .probe = pcips2_probe,
215 .remove = __devexit_p(pcips2_remove),
216};
217
218static int __init pcips2_init(void)
219{
220 return pci_register_driver(&pcips2_driver);
221}
222
223static void __exit pcips2_exit(void)
224{
225 pci_unregister_driver(&pcips2_driver);
226}
227
228module_init(pcips2_init);
229module_exit(pcips2_exit);
230
231MODULE_LICENSE("GPL");
232MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
233MODULE_DESCRIPTION("PCI PS/2 keyboard/mouse driver");
234MODULE_DEVICE_TABLE(pci, pcips2_ids);
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
new file mode 100644
index 000000000000..46093c507988
--- /dev/null
+++ b/drivers/input/serio/q40kbd.c
@@ -0,0 +1,163 @@
1/*
2 * $Id: q40kbd.c,v 1.12 2002/02/02 22:26:44 vojtech Exp $
3 *
4 * Copyright (c) 2000-2001 Vojtech Pavlik
5 *
6 * Based on the work of:
7 * Richard Zidlicky <Richard.Zidlicky@stud.informatik.uni-erlangen.de>
8 */
9
10/*
11 * Q40 PS/2 keyboard controller driver for Linux/m68k
12 */
13
14/*
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 * Should you need to contact me, the author, you can do so either by
30 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
31 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
32 */
33
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/serio.h>
37#include <linux/interrupt.h>
38#include <linux/err.h>
39#include <linux/bitops.h>
40
41#include <asm/io.h>
42#include <asm/uaccess.h>
43#include <asm/q40_master.h>
44#include <asm/irq.h>
45#include <asm/q40ints.h>
46
47MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
48MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
49MODULE_LICENSE("GPL");
50
51DEFINE_SPINLOCK(q40kbd_lock);
52static struct serio *q40kbd_port;
53static struct platform_device *q40kbd_device;
54
55static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
56{
57 unsigned long flags;
58
59 spin_lock_irqsave(&q40kbd_lock, flags);
60
61 if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
62 serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0, regs);
63
64 master_outb(-1, KEYBOARD_UNLOCK_REG);
65
66 spin_unlock_irqrestore(&q40kbd_lock, flags);
67
68 return IRQ_HANDLED;
69}
70
71/*
72 * q40kbd_flush() flushes all data that may be in the keyboard buffers
73 */
74
75static void q40kbd_flush(void)
76{
77 int maxread = 100;
78 unsigned long flags;
79
80 spin_lock_irqsave(&q40kbd_lock, flags);
81
82 while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
83 master_inb(KEYCODE_REG);
84
85 spin_unlock_irqrestore(&q40kbd_lock, flags);
86}
87
88/*
89 * q40kbd_open() is called when a port is open by the higher layer.
90 * It allocates the interrupt and enables in in the chip.
91 */
92
93static int q40kbd_open(struct serio *port)
94{
95 q40kbd_flush();
96
97 if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) {
98 printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD);
99 return -1;
100 }
101
102 /* off we go */
103 master_outb(-1, KEYBOARD_UNLOCK_REG);
104 master_outb(1, KEY_IRQ_ENABLE_REG);
105
106 return 0;
107}
108
109static void q40kbd_close(struct serio *port)
110{
111 master_outb(0, KEY_IRQ_ENABLE_REG);
112 master_outb(-1, KEYBOARD_UNLOCK_REG);
113 free_irq(Q40_IRQ_KEYBOARD, NULL);
114
115 q40kbd_flush();
116}
117
118static struct serio * __init q40kbd_allocate_port(void)
119{
120 struct serio *serio;
121
122 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
123 if (serio) {
124 memset(serio, 0, sizeof(struct serio));
125 serio->id.type = SERIO_8042;
126 serio->open = q40kbd_open;
127 serio->close = q40kbd_close;
128 serio->dev.parent = &q40kbd_device->dev;
129 strlcpy(serio->name, "Q40 Kbd Port", sizeof(serio->name));
130 strlcpy(serio->phys, "Q40", sizeof(serio->phys));
131 }
132
133 return serio;
134}
135
136static int __init q40kbd_init(void)
137{
138 if (!MACH_IS_Q40)
139 return -EIO;
140
141 q40kbd_device = platform_device_register_simple("q40kbd", -1, NULL, 0);
142 if (IS_ERR(q40kbd_device))
143 return PTR_ERR(q40kbd_device);
144
145 if (!(q40kbd_port = q40kbd_allocate_port())) {
146 platform_device_unregister(q40kbd_device);
147 return -ENOMEM;
148 }
149
150 serio_register_port(q40kbd_port);
151 printk(KERN_INFO "serio: Q40 kbd registered\n");
152
153 return 0;
154}
155
156static void __exit q40kbd_exit(void)
157{
158 serio_unregister_port(q40kbd_port);
159 platform_device_unregister(q40kbd_device);
160}
161
162module_init(q40kbd_init);
163module_exit(q40kbd_exit);
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
new file mode 100644
index 000000000000..106f5eefd89a
--- /dev/null
+++ b/drivers/input/serio/rpckbd.c
@@ -0,0 +1,156 @@
1/*
2 * $Id: rpckbd.c,v 1.7 2001/09/25 10:12:07 vojtech Exp $
3 *
4 * Copyright (c) 2000-2001 Vojtech Pavlik
5 * Copyright (c) 2002 Russell King
6 */
7
8/*
9 * Acorn RiscPC PS/2 keyboard controller driver for Linux/ARM
10 */
11
12/*
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 * Should you need to contact me, the author, you can do so either by
28 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
29 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
30 */
31
32#include <linux/module.h>
33#include <linux/interrupt.h>
34#include <linux/init.h>
35#include <linux/serio.h>
36#include <linux/err.h>
37
38#include <asm/irq.h>
39#include <asm/hardware.h>
40#include <asm/io.h>
41#include <asm/hardware/iomd.h>
42#include <asm/system.h>
43
44MODULE_AUTHOR("Vojtech Pavlik, Russell King");
45MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
46MODULE_LICENSE("GPL");
47
48static int rpckbd_write(struct serio *port, unsigned char val)
49{
50 while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
51 cpu_relax();
52
53 iomd_writeb(val, IOMD_KARTTX);
54
55 return 0;
56}
57
58static irqreturn_t rpckbd_rx(int irq, void *dev_id, struct pt_regs *regs)
59{
60 struct serio *port = dev_id;
61 unsigned int byte;
62 int handled = IRQ_NONE;
63
64 while (iomd_readb(IOMD_KCTRL) & (1 << 5)) {
65 byte = iomd_readb(IOMD_KARTRX);
66
67 serio_interrupt(port, byte, 0, regs);
68 handled = IRQ_HANDLED;
69 }
70 return handled;
71}
72
73static irqreturn_t rpckbd_tx(int irq, void *dev_id, struct pt_regs *regs)
74{
75 return IRQ_HANDLED;
76}
77
78static int rpckbd_open(struct serio *port)
79{
80 /* Reset the keyboard state machine. */
81 iomd_writeb(0, IOMD_KCTRL);
82 iomd_writeb(8, IOMD_KCTRL);
83 iomd_readb(IOMD_KARTRX);
84
85 if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) {
86 printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n");
87 return -EBUSY;
88 }
89
90 if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) {
91 printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n");
92 free_irq(IRQ_KEYBOARDRX, NULL);
93 return -EBUSY;
94 }
95
96 return 0;
97}
98
99static void rpckbd_close(struct serio *port)
100{
101 free_irq(IRQ_KEYBOARDRX, port);
102 free_irq(IRQ_KEYBOARDTX, port);
103}
104
105/*
106 * Allocate and initialize serio structure for subsequent registration
107 * with serio core.
108 */
109static int __devinit rpckbd_probe(struct device *dev)
110{
111 struct serio *serio;
112
113 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
114 if (!serio)
115 return -ENOMEM;
116
117 memset(serio, 0, sizeof(struct serio));
118 serio->id.type = SERIO_8042;
119 serio->write = rpckbd_write;
120 serio->open = rpckbd_open;
121 serio->close = rpckbd_close;
122 serio->dev.parent = dev;
123 strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
124 strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
125
126 dev_set_drvdata(dev, serio);
127 serio_register_port(serio);
128 return 0;
129}
130
131static int __devexit rpckbd_remove(struct device *dev)
132{
133 struct serio *serio = dev_get_drvdata(dev);
134 serio_unregister_port(serio);
135 return 0;
136}
137
138static struct device_driver rpckbd_driver = {
139 .name = "kart",
140 .bus = &platform_bus_type,
141 .probe = rpckbd_probe,
142 .remove = __devexit_p(rpckbd_remove),
143};
144
145static int __init rpckbd_init(void)
146{
147 return driver_register(&rpckbd_driver);
148}
149
150static void __exit rpckbd_exit(void)
151{
152 driver_unregister(&rpckbd_driver);
153}
154
155module_init(rpckbd_init);
156module_exit(rpckbd_exit);
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
new file mode 100644
index 000000000000..3f0df3330fb2
--- /dev/null
+++ b/drivers/input/serio/sa1111ps2.c
@@ -0,0 +1,359 @@
1/*
2 * linux/drivers/input/serio/sa1111ps2.c
3 *
4 * Copyright (C) 2002 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License.
9 */
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/input.h>
13#include <linux/serio.h>
14#include <linux/errno.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/slab.h>
20#include <linux/spinlock.h>
21
22#include <asm/io.h>
23#include <asm/irq.h>
24#include <asm/system.h>
25
26#include <asm/hardware/sa1111.h>
27
28struct ps2if {
29 struct serio *io;
30 struct sa1111_dev *dev;
31 void __iomem *base;
32 unsigned int open;
33 spinlock_t lock;
34 unsigned int head;
35 unsigned int tail;
36 unsigned char buf[4];
37};
38
39/*
40 * Read all bytes waiting in the PS2 port. There should be
41 * at the most one, but we loop for safety. If there was a
42 * framing error, we have to manually clear the status.
43 */
44static irqreturn_t ps2_rxint(int irq, void *dev_id, struct pt_regs *regs)
45{
46 struct ps2if *ps2if = dev_id;
47 unsigned int scancode, flag, status;
48
49 status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
50 while (status & PS2STAT_RXF) {
51 if (status & PS2STAT_STP)
52 sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT);
53
54 flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) |
55 (status & PS2STAT_RXP ? 0 : SERIO_PARITY);
56
57 scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff;
58
59 if (hweight8(scancode) & 1)
60 flag ^= SERIO_PARITY;
61
62 serio_interrupt(ps2if->io, scancode, flag, regs);
63
64 status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
65 }
66
67 return IRQ_HANDLED;
68}
69
70/*
71 * Completion of ps2 write
72 */
73static irqreturn_t ps2_txint(int irq, void *dev_id, struct pt_regs *regs)
74{
75 struct ps2if *ps2if = dev_id;
76 unsigned int status;
77
78 spin_lock(&ps2if->lock);
79 status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
80 if (ps2if->head == ps2if->tail) {
81 disable_irq(irq);
82 /* done */
83 } else if (status & PS2STAT_TXE) {
84 sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA);
85 ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1);
86 }
87 spin_unlock(&ps2if->lock);
88
89 return IRQ_HANDLED;
90}
91
92/*
93 * Write a byte to the PS2 port. We have to wait for the
94 * port to indicate that the transmitter is empty.
95 */
96static int ps2_write(struct serio *io, unsigned char val)
97{
98 struct ps2if *ps2if = io->port_data;
99 unsigned long flags;
100 unsigned int head;
101
102 spin_lock_irqsave(&ps2if->lock, flags);
103
104 /*
105 * If the TX register is empty, we can go straight out.
106 */
107 if (sa1111_readl(ps2if->base + SA1111_PS2STAT) & PS2STAT_TXE) {
108 sa1111_writel(val, ps2if->base + SA1111_PS2DATA);
109 } else {
110 if (ps2if->head == ps2if->tail)
111 enable_irq(ps2if->dev->irq[1]);
112 head = (ps2if->head + 1) & (sizeof(ps2if->buf) - 1);
113 if (head != ps2if->tail) {
114 ps2if->buf[ps2if->head] = val;
115 ps2if->head = head;
116 }
117 }
118
119 spin_unlock_irqrestore(&ps2if->lock, flags);
120 return 0;
121}
122
123static int ps2_open(struct serio *io)
124{
125 struct ps2if *ps2if = io->port_data;
126 int ret;
127
128 sa1111_enable_device(ps2if->dev);
129
130 ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0,
131 SA1111_DRIVER_NAME(ps2if->dev), ps2if);
132 if (ret) {
133 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
134 ps2if->dev->irq[0], ret);
135 return ret;
136 }
137
138 ret = request_irq(ps2if->dev->irq[1], ps2_txint, 0,
139 SA1111_DRIVER_NAME(ps2if->dev), ps2if);
140 if (ret) {
141 printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
142 ps2if->dev->irq[1], ret);
143 free_irq(ps2if->dev->irq[0], ps2if);
144 return ret;
145 }
146
147 ps2if->open = 1;
148
149 enable_irq_wake(ps2if->dev->irq[0]);
150
151 sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR);
152 return 0;
153}
154
155static void ps2_close(struct serio *io)
156{
157 struct ps2if *ps2if = io->port_data;
158
159 sa1111_writel(0, ps2if->base + SA1111_PS2CR);
160
161 disable_irq_wake(ps2if->dev->irq[0]);
162
163 ps2if->open = 0;
164
165 free_irq(ps2if->dev->irq[1], ps2if);
166 free_irq(ps2if->dev->irq[0], ps2if);
167
168 sa1111_disable_device(ps2if->dev);
169}
170
171/*
172 * Clear the input buffer.
173 */
174static void __init ps2_clear_input(struct ps2if *ps2if)
175{
176 int maxread = 100;
177
178 while (maxread--) {
179 if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff)
180 break;
181 }
182}
183
184static inline unsigned int
185ps2_test_one(struct ps2if *ps2if, unsigned int mask)
186{
187 unsigned int val;
188
189 sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR);
190
191 udelay(2);
192
193 val = sa1111_readl(ps2if->base + SA1111_PS2STAT);
194 return val & (PS2STAT_KBC | PS2STAT_KBD);
195}
196
197/*
198 * Test the keyboard interface. We basically check to make sure that
199 * we can drive each line to the keyboard independently of each other.
200 */
201static int __init ps2_test(struct ps2if *ps2if)
202{
203 unsigned int stat;
204 int ret = 0;
205
206 stat = ps2_test_one(ps2if, PS2CR_FKC);
207 if (stat != PS2STAT_KBD) {
208 printk("PS/2 interface test failed[1]: %02x\n", stat);
209 ret = -ENODEV;
210 }
211
212 stat = ps2_test_one(ps2if, 0);
213 if (stat != (PS2STAT_KBC | PS2STAT_KBD)) {
214 printk("PS/2 interface test failed[2]: %02x\n", stat);
215 ret = -ENODEV;
216 }
217
218 stat = ps2_test_one(ps2if, PS2CR_FKD);
219 if (stat != PS2STAT_KBC) {
220 printk("PS/2 interface test failed[3]: %02x\n", stat);
221 ret = -ENODEV;
222 }
223
224 sa1111_writel(0, ps2if->base + SA1111_PS2CR);
225
226 return ret;
227}
228
229/*
230 * Add one device to this driver.
231 */
232static int ps2_probe(struct sa1111_dev *dev)
233{
234 struct ps2if *ps2if;
235 struct serio *serio;
236 int ret;
237
238 ps2if = kmalloc(sizeof(struct ps2if), GFP_KERNEL);
239 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
240 if (!ps2if || !serio) {
241 ret = -ENOMEM;
242 goto free;
243 }
244
245 memset(ps2if, 0, sizeof(struct ps2if));
246 memset(serio, 0, sizeof(struct serio));
247
248 serio->id.type = SERIO_8042;
249 serio->write = ps2_write;
250 serio->open = ps2_open;
251 serio->close = ps2_close;
252 strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
253 strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
254 serio->port_data = ps2if;
255 serio->dev.parent = &dev->dev;
256 ps2if->io = serio;
257 ps2if->dev = dev;
258 sa1111_set_drvdata(dev, ps2if);
259
260 spin_lock_init(&ps2if->lock);
261
262 /*
263 * Request the physical region for this PS2 port.
264 */
265 if (!request_mem_region(dev->res.start,
266 dev->res.end - dev->res.start + 1,
267 SA1111_DRIVER_NAME(dev))) {
268 ret = -EBUSY;
269 goto free;
270 }
271
272 /*
273 * Our parent device has already mapped the region.
274 */
275 ps2if->base = dev->mapbase;
276
277 sa1111_enable_device(ps2if->dev);
278
279 /* Incoming clock is 8MHz */
280 sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV);
281 sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT);
282
283 /*
284 * Flush any pending input.
285 */
286 ps2_clear_input(ps2if);
287
288 /*
289 * Test the keyboard interface.
290 */
291 ret = ps2_test(ps2if);
292 if (ret)
293 goto out;
294
295 /*
296 * Flush any pending input.
297 */
298 ps2_clear_input(ps2if);
299
300 sa1111_disable_device(ps2if->dev);
301 serio_register_port(ps2if->io);
302 return 0;
303
304 out:
305 sa1111_disable_device(ps2if->dev);
306 release_mem_region(dev->res.start,
307 dev->res.end - dev->res.start + 1);
308 free:
309 sa1111_set_drvdata(dev, NULL);
310 kfree(ps2if);
311 kfree(serio);
312 return ret;
313}
314
315/*
316 * Remove one device from this driver.
317 */
318static int ps2_remove(struct sa1111_dev *dev)
319{
320 struct ps2if *ps2if = sa1111_get_drvdata(dev);
321
322 serio_unregister_port(ps2if->io);
323 release_mem_region(dev->res.start,
324 dev->res.end - dev->res.start + 1);
325 sa1111_set_drvdata(dev, NULL);
326
327 kfree(ps2if);
328
329 return 0;
330}
331
332/*
333 * Our device driver structure
334 */
335static struct sa1111_driver ps2_driver = {
336 .drv = {
337 .name = "sa1111-ps2",
338 },
339 .devid = SA1111_DEVID_PS2,
340 .probe = ps2_probe,
341 .remove = ps2_remove,
342};
343
344static int __init ps2_init(void)
345{
346 return sa1111_driver_register(&ps2_driver);
347}
348
349static void __exit ps2_exit(void)
350{
351 sa1111_driver_unregister(&ps2_driver);
352}
353
354module_init(ps2_init);
355module_exit(ps2_exit);
356
357MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
358MODULE_DESCRIPTION("SA1111 PS2 controller driver");
359MODULE_LICENSE("GPL");
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
new file mode 100644
index 000000000000..3313e2daeab0
--- /dev/null
+++ b/drivers/input/serio/serio.c
@@ -0,0 +1,859 @@
1/*
2 * The Serio abstraction module
3 *
4 * Copyright (c) 1999-2004 Vojtech Pavlik
5 * Copyright (c) 2004 Dmitry Torokhov
6 * Copyright (c) 2003 Daniele Bellucci
7 */
8
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 as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * Should you need to contact me, the author, you can do so either by
25 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
26 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
27 */
28
29#include <linux/stddef.h>
30#include <linux/module.h>
31#include <linux/serio.h>
32#include <linux/errno.h>
33#include <linux/wait.h>
34#include <linux/completion.h>
35#include <linux/sched.h>
36#include <linux/smp_lock.h>
37#include <linux/slab.h>
38
39MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
40MODULE_DESCRIPTION("Serio abstraction core");
41MODULE_LICENSE("GPL");
42
43EXPORT_SYMBOL(serio_interrupt);
44EXPORT_SYMBOL(__serio_register_port);
45EXPORT_SYMBOL(serio_unregister_port);
46EXPORT_SYMBOL(__serio_unregister_port_delayed);
47EXPORT_SYMBOL(__serio_register_driver);
48EXPORT_SYMBOL(serio_unregister_driver);
49EXPORT_SYMBOL(serio_open);
50EXPORT_SYMBOL(serio_close);
51EXPORT_SYMBOL(serio_rescan);
52EXPORT_SYMBOL(serio_reconnect);
53
54/*
55 * serio_sem protects entire serio subsystem and is taken every time
56 * serio port or driver registrered or unregistered.
57 */
58static DECLARE_MUTEX(serio_sem);
59
60static LIST_HEAD(serio_list);
61
62static struct bus_type serio_bus = {
63 .name = "serio",
64};
65
66static void serio_add_port(struct serio *serio);
67static void serio_destroy_port(struct serio *serio);
68static void serio_reconnect_port(struct serio *serio);
69static void serio_disconnect_port(struct serio *serio);
70
71static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
72{
73 while (ids->type || ids->proto) {
74 if ((ids->type == SERIO_ANY || ids->type == serio->id.type) &&
75 (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) &&
76 (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) &&
77 (ids->id == SERIO_ANY || ids->id == serio->id.id))
78 return 1;
79 ids++;
80 }
81 return 0;
82}
83
84/*
85 * Basic serio -> driver core mappings
86 */
87
88static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
89{
90 down_write(&serio_bus.subsys.rwsem);
91
92 if (serio_match_port(drv->id_table, serio)) {
93 serio->dev.driver = &drv->driver;
94 if (drv->connect(serio, drv)) {
95 serio->dev.driver = NULL;
96 goto out;
97 }
98 device_bind_driver(&serio->dev);
99 }
100out:
101 up_write(&serio_bus.subsys.rwsem);
102}
103
104static void serio_release_driver(struct serio *serio)
105{
106 down_write(&serio_bus.subsys.rwsem);
107 device_release_driver(&serio->dev);
108 up_write(&serio_bus.subsys.rwsem);
109}
110
111static void serio_find_driver(struct serio *serio)
112{
113 down_write(&serio_bus.subsys.rwsem);
114 device_attach(&serio->dev);
115 up_write(&serio_bus.subsys.rwsem);
116}
117
118
119/*
120 * Serio event processing.
121 */
122
123enum serio_event_type {
124 SERIO_RESCAN,
125 SERIO_RECONNECT,
126 SERIO_REGISTER_PORT,
127 SERIO_UNREGISTER_PORT,
128 SERIO_REGISTER_DRIVER,
129};
130
131struct serio_event {
132 enum serio_event_type type;
133 void *object;
134 struct module *owner;
135 struct list_head node;
136};
137
138static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */
139static LIST_HEAD(serio_event_list);
140static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
141static DECLARE_COMPLETION(serio_exited);
142static int serio_pid;
143
144static void serio_queue_event(void *object, struct module *owner,
145 enum serio_event_type event_type)
146{
147 unsigned long flags;
148 struct serio_event *event;
149
150 spin_lock_irqsave(&serio_event_lock, flags);
151
152 /*
153 * Scan event list for the other events for the same serio port,
154 * starting with the most recent one. If event is the same we
155 * do not need add new one. If event is of different type we
156 * need to add this event and should not look further because
157 * we need to preseve sequence of distinct events.
158 */
159 list_for_each_entry_reverse(event, &serio_event_list, node) {
160 if (event->object == object) {
161 if (event->type == event_type)
162 goto out;
163 break;
164 }
165 }
166
167 if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
168 if (!try_module_get(owner)) {
169 printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type);
170 goto out;
171 }
172
173 event->type = event_type;
174 event->object = object;
175 event->owner = owner;
176
177 list_add_tail(&event->node, &serio_event_list);
178 wake_up(&serio_wait);
179 } else {
180 printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type);
181 }
182out:
183 spin_unlock_irqrestore(&serio_event_lock, flags);
184}
185
186static void serio_free_event(struct serio_event *event)
187{
188 module_put(event->owner);
189 kfree(event);
190}
191
192static void serio_remove_duplicate_events(struct serio_event *event)
193{
194 struct list_head *node, *next;
195 struct serio_event *e;
196 unsigned long flags;
197
198 spin_lock_irqsave(&serio_event_lock, flags);
199
200 list_for_each_safe(node, next, &serio_event_list) {
201 e = list_entry(node, struct serio_event, node);
202 if (event->object == e->object) {
203 /*
204 * If this event is of different type we should not
205 * look further - we only suppress duplicate events
206 * that were sent back-to-back.
207 */
208 if (event->type != e->type)
209 break;
210
211 list_del_init(node);
212 serio_free_event(e);
213 }
214 }
215
216 spin_unlock_irqrestore(&serio_event_lock, flags);
217}
218
219
220static struct serio_event *serio_get_event(void)
221{
222 struct serio_event *event;
223 struct list_head *node;
224 unsigned long flags;
225
226 spin_lock_irqsave(&serio_event_lock, flags);
227
228 if (list_empty(&serio_event_list)) {
229 spin_unlock_irqrestore(&serio_event_lock, flags);
230 return NULL;
231 }
232
233 node = serio_event_list.next;
234 event = list_entry(node, struct serio_event, node);
235 list_del_init(node);
236
237 spin_unlock_irqrestore(&serio_event_lock, flags);
238
239 return event;
240}
241
242static void serio_handle_events(void)
243{
244 struct serio_event *event;
245 struct serio_driver *serio_drv;
246
247 down(&serio_sem);
248
249 while ((event = serio_get_event())) {
250
251 switch (event->type) {
252 case SERIO_REGISTER_PORT:
253 serio_add_port(event->object);
254 break;
255
256 case SERIO_UNREGISTER_PORT:
257 serio_disconnect_port(event->object);
258 serio_destroy_port(event->object);
259 break;
260
261 case SERIO_RECONNECT:
262 serio_reconnect_port(event->object);
263 break;
264
265 case SERIO_RESCAN:
266 serio_disconnect_port(event->object);
267 serio_find_driver(event->object);
268 break;
269
270 case SERIO_REGISTER_DRIVER:
271 serio_drv = event->object;
272 driver_register(&serio_drv->driver);
273 break;
274
275 default:
276 break;
277 }
278
279 serio_remove_duplicate_events(event);
280 serio_free_event(event);
281 }
282
283 up(&serio_sem);
284}
285
286/*
287 * Remove all events that have been submitted for a given serio port.
288 */
289static void serio_remove_pending_events(struct serio *serio)
290{
291 struct list_head *node, *next;
292 struct serio_event *event;
293 unsigned long flags;
294
295 spin_lock_irqsave(&serio_event_lock, flags);
296
297 list_for_each_safe(node, next, &serio_event_list) {
298 event = list_entry(node, struct serio_event, node);
299 if (event->object == serio) {
300 list_del_init(node);
301 serio_free_event(event);
302 }
303 }
304
305 spin_unlock_irqrestore(&serio_event_lock, flags);
306}
307
308/*
309 * Destroy child serio port (if any) that has not been fully registered yet.
310 *
311 * Note that we rely on the fact that port can have only one child and therefore
312 * only one child registration request can be pending. Additionally, children
313 * are registered by driver's connect() handler so there can't be a grandchild
314 * pending registration together with a child.
315 */
316static struct serio *serio_get_pending_child(struct serio *parent)
317{
318 struct serio_event *event;
319 struct serio *serio, *child = NULL;
320 unsigned long flags;
321
322 spin_lock_irqsave(&serio_event_lock, flags);
323
324 list_for_each_entry(event, &serio_event_list, node) {
325 if (event->type == SERIO_REGISTER_PORT) {
326 serio = event->object;
327 if (serio->parent == parent) {
328 child = serio;
329 break;
330 }
331 }
332 }
333
334 spin_unlock_irqrestore(&serio_event_lock, flags);
335 return child;
336}
337
338static int serio_thread(void *nothing)
339{
340 lock_kernel();
341 daemonize("kseriod");
342 allow_signal(SIGTERM);
343
344 do {
345 serio_handle_events();
346 wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
347 try_to_freeze(PF_FREEZE);
348 } while (!signal_pending(current));
349
350 printk(KERN_DEBUG "serio: kseriod exiting\n");
351
352 unlock_kernel();
353 complete_and_exit(&serio_exited, 0);
354}
355
356
357/*
358 * Serio port operations
359 */
360
361static ssize_t serio_show_description(struct device *dev, char *buf)
362{
363 struct serio *serio = to_serio_port(dev);
364 return sprintf(buf, "%s\n", serio->name);
365}
366
367static ssize_t serio_show_id_type(struct device *dev, char *buf)
368{
369 struct serio *serio = to_serio_port(dev);
370 return sprintf(buf, "%02x\n", serio->id.type);
371}
372
373static ssize_t serio_show_id_proto(struct device *dev, char *buf)
374{
375 struct serio *serio = to_serio_port(dev);
376 return sprintf(buf, "%02x\n", serio->id.proto);
377}
378
379static ssize_t serio_show_id_id(struct device *dev, char *buf)
380{
381 struct serio *serio = to_serio_port(dev);
382 return sprintf(buf, "%02x\n", serio->id.id);
383}
384
385static ssize_t serio_show_id_extra(struct device *dev, char *buf)
386{
387 struct serio *serio = to_serio_port(dev);
388 return sprintf(buf, "%02x\n", serio->id.extra);
389}
390
391static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count)
392{
393 struct serio *serio = to_serio_port(dev);
394 struct device_driver *drv;
395 int retval;
396
397 retval = down_interruptible(&serio_sem);
398 if (retval)
399 return retval;
400
401 retval = count;
402 if (!strncmp(buf, "none", count)) {
403 serio_disconnect_port(serio);
404 } else if (!strncmp(buf, "reconnect", count)) {
405 serio_reconnect_port(serio);
406 } else if (!strncmp(buf, "rescan", count)) {
407 serio_disconnect_port(serio);
408 serio_find_driver(serio);
409 } else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
410 serio_disconnect_port(serio);
411 serio_bind_driver(serio, to_serio_driver(drv));
412 put_driver(drv);
413 } else {
414 retval = -EINVAL;
415 }
416
417 up(&serio_sem);
418
419 return retval;
420}
421
422static ssize_t serio_show_bind_mode(struct device *dev, char *buf)
423{
424 struct serio *serio = to_serio_port(dev);
425 return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto");
426}
427
428static ssize_t serio_set_bind_mode(struct device *dev, const char *buf, size_t count)
429{
430 struct serio *serio = to_serio_port(dev);
431 int retval;
432
433 retval = count;
434 if (!strncmp(buf, "manual", count)) {
435 serio->manual_bind = 1;
436 } else if (!strncmp(buf, "auto", count)) {
437 serio->manual_bind = 0;
438 } else {
439 retval = -EINVAL;
440 }
441
442 return retval;
443}
444
445static struct device_attribute serio_device_attrs[] = {
446 __ATTR(description, S_IRUGO, serio_show_description, NULL),
447 __ATTR(id_type, S_IRUGO, serio_show_id_type, NULL),
448 __ATTR(id_proto, S_IRUGO, serio_show_id_proto, NULL),
449 __ATTR(id_id, S_IRUGO, serio_show_id_id, NULL),
450 __ATTR(id_extra, S_IRUGO, serio_show_id_extra, NULL),
451 __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver),
452 __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode),
453 __ATTR_NULL
454};
455
456
457static void serio_release_port(struct device *dev)
458{
459 struct serio *serio = to_serio_port(dev);
460
461 kfree(serio);
462 module_put(THIS_MODULE);
463}
464
465/*
466 * Prepare serio port for registration.
467 */
468static void serio_init_port(struct serio *serio)
469{
470 static atomic_t serio_no = ATOMIC_INIT(0);
471
472 __module_get(THIS_MODULE);
473
474 spin_lock_init(&serio->lock);
475 init_MUTEX(&serio->drv_sem);
476 device_initialize(&serio->dev);
477 snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id),
478 "serio%ld", (long)atomic_inc_return(&serio_no) - 1);
479 serio->dev.bus = &serio_bus;
480 serio->dev.release = serio_release_port;
481 if (serio->parent)
482 serio->dev.parent = &serio->parent->dev;
483}
484
485/*
486 * Complete serio port registration.
487 * Driver core will attempt to find appropriate driver for the port.
488 */
489static void serio_add_port(struct serio *serio)
490{
491 if (serio->parent) {
492 serio_pause_rx(serio->parent);
493 serio->parent->child = serio;
494 serio_continue_rx(serio->parent);
495 }
496
497 list_add_tail(&serio->node, &serio_list);
498 if (serio->start)
499 serio->start(serio);
500 device_add(&serio->dev);
501 serio->registered = 1;
502}
503
504/*
505 * serio_destroy_port() completes deregistration process and removes
506 * port from the system
507 */
508static void serio_destroy_port(struct serio *serio)
509{
510 struct serio *child;
511
512 child = serio_get_pending_child(serio);
513 if (child) {
514 serio_remove_pending_events(child);
515 put_device(&child->dev);
516 }
517
518 if (serio->stop)
519 serio->stop(serio);
520
521 if (serio->parent) {
522 serio_pause_rx(serio->parent);
523 serio->parent->child = NULL;
524 serio_continue_rx(serio->parent);
525 serio->parent = NULL;
526 }
527
528 if (serio->registered) {
529 device_del(&serio->dev);
530 list_del_init(&serio->node);
531 serio->registered = 0;
532 }
533
534 serio_remove_pending_events(serio);
535 put_device(&serio->dev);
536}
537
538/*
539 * Reconnect serio port and all its children (re-initialize attached devices)
540 */
541static void serio_reconnect_port(struct serio *serio)
542{
543 do {
544 if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
545 serio_disconnect_port(serio);
546 serio_find_driver(serio);
547 /* Ok, old children are now gone, we are done */
548 break;
549 }
550 serio = serio->child;
551 } while (serio);
552}
553
554/*
555 * serio_disconnect_port() unbinds a port from its driver. As a side effect
556 * all child ports are unbound and destroyed.
557 */
558static void serio_disconnect_port(struct serio *serio)
559{
560 struct serio *s, *parent;
561
562 if (serio->child) {
563 /*
564 * Children ports should be disconnected and destroyed
565 * first, staring with the leaf one, since we don't want
566 * to do recursion
567 */
568 for (s = serio; s->child; s = s->child)
569 /* empty */;
570
571 do {
572 parent = s->parent;
573
574 serio_release_driver(s);
575 serio_destroy_port(s);
576 } while ((s = parent) != serio);
577 }
578
579 /*
580 * Ok, no children left, now disconnect this port
581 */
582 serio_release_driver(serio);
583}
584
585void serio_rescan(struct serio *serio)
586{
587 serio_queue_event(serio, NULL, SERIO_RESCAN);
588}
589
590void serio_reconnect(struct serio *serio)
591{
592 serio_queue_event(serio, NULL, SERIO_RECONNECT);
593}
594
595/*
596 * Submits register request to kseriod for subsequent execution.
597 * Note that port registration is always asynchronous.
598 */
599void __serio_register_port(struct serio *serio, struct module *owner)
600{
601 serio_init_port(serio);
602 serio_queue_event(serio, owner, SERIO_REGISTER_PORT);
603}
604
605/*
606 * Synchronously unregisters serio port.
607 */
608void serio_unregister_port(struct serio *serio)
609{
610 down(&serio_sem);
611 serio_disconnect_port(serio);
612 serio_destroy_port(serio);
613 up(&serio_sem);
614}
615
616/*
617 * Submits register request to kseriod for subsequent execution.
618 * Can be used when it is not obvious whether the serio_sem is
619 * taken or not and when delayed execution is feasible.
620 */
621void __serio_unregister_port_delayed(struct serio *serio, struct module *owner)
622{
623 serio_queue_event(serio, owner, SERIO_UNREGISTER_PORT);
624}
625
626
627/*
628 * Serio driver operations
629 */
630
631static ssize_t serio_driver_show_description(struct device_driver *drv, char *buf)
632{
633 struct serio_driver *driver = to_serio_driver(drv);
634 return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
635}
636
637static ssize_t serio_driver_show_bind_mode(struct device_driver *drv, char *buf)
638{
639 struct serio_driver *serio_drv = to_serio_driver(drv);
640 return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto");
641}
642
643static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char *buf, size_t count)
644{
645 struct serio_driver *serio_drv = to_serio_driver(drv);
646 int retval;
647
648 retval = count;
649 if (!strncmp(buf, "manual", count)) {
650 serio_drv->manual_bind = 1;
651 } else if (!strncmp(buf, "auto", count)) {
652 serio_drv->manual_bind = 0;
653 } else {
654 retval = -EINVAL;
655 }
656
657 return retval;
658}
659
660
661static struct driver_attribute serio_driver_attrs[] = {
662 __ATTR(description, S_IRUGO, serio_driver_show_description, NULL),
663 __ATTR(bind_mode, S_IWUSR | S_IRUGO,
664 serio_driver_show_bind_mode, serio_driver_set_bind_mode),
665 __ATTR_NULL
666};
667
668static int serio_driver_probe(struct device *dev)
669{
670 struct serio *serio = to_serio_port(dev);
671 struct serio_driver *drv = to_serio_driver(dev->driver);
672
673 return drv->connect(serio, drv);
674}
675
676static int serio_driver_remove(struct device *dev)
677{
678 struct serio *serio = to_serio_port(dev);
679 struct serio_driver *drv = to_serio_driver(dev->driver);
680
681 drv->disconnect(serio);
682 return 0;
683}
684
685void __serio_register_driver(struct serio_driver *drv, struct module *owner)
686{
687 drv->driver.bus = &serio_bus;
688 drv->driver.probe = serio_driver_probe;
689 drv->driver.remove = serio_driver_remove;
690
691 serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER);
692}
693
694void serio_unregister_driver(struct serio_driver *drv)
695{
696 struct serio *serio;
697
698 down(&serio_sem);
699 drv->manual_bind = 1; /* so serio_find_driver ignores it */
700
701start_over:
702 list_for_each_entry(serio, &serio_list, node) {
703 if (serio->drv == drv) {
704 serio_disconnect_port(serio);
705 serio_find_driver(serio);
706 /* we could've deleted some ports, restart */
707 goto start_over;
708 }
709 }
710
711 driver_unregister(&drv->driver);
712 up(&serio_sem);
713}
714
715static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
716{
717 down(&serio->drv_sem);
718 serio_pause_rx(serio);
719 serio->drv = drv;
720 serio_continue_rx(serio);
721 up(&serio->drv_sem);
722}
723
724static int serio_bus_match(struct device *dev, struct device_driver *drv)
725{
726 struct serio *serio = to_serio_port(dev);
727 struct serio_driver *serio_drv = to_serio_driver(drv);
728
729 if (serio->manual_bind || serio_drv->manual_bind)
730 return 0;
731
732 return serio_match_port(serio_drv->id_table, serio);
733}
734
735#ifdef CONFIG_HOTPLUG
736
737#define PUT_ENVP(fmt, val) \
738do { \
739 envp[i++] = buffer; \
740 length += snprintf(buffer, buffer_size - length, fmt, val); \
741 if (buffer_size - length <= 0 || i >= num_envp) \
742 return -ENOMEM; \
743 length++; \
744 buffer += length; \
745} while (0)
746static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
747{
748 struct serio *serio;
749 int i = 0;
750 int length = 0;
751
752 if (!dev)
753 return -ENODEV;
754
755 serio = to_serio_port(dev);
756
757 PUT_ENVP("SERIO_TYPE=%02x", serio->id.type);
758 PUT_ENVP("SERIO_PROTO=%02x", serio->id.proto);
759 PUT_ENVP("SERIO_ID=%02x", serio->id.id);
760 PUT_ENVP("SERIO_EXTRA=%02x", serio->id.extra);
761
762 envp[i] = NULL;
763
764 return 0;
765}
766#undef PUT_ENVP
767
768#else
769
770static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
771{
772 return -ENODEV;
773}
774
775#endif /* CONFIG_HOTPLUG */
776
777static int serio_resume(struct device *dev)
778{
779 struct serio *serio = to_serio_port(dev);
780
781 if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
782 serio_disconnect_port(serio);
783 /*
784 * Driver re-probing can take a while, so better let kseriod
785 * deal with it.
786 */
787 serio_rescan(serio);
788 }
789
790 return 0;
791}
792
793/* called from serio_driver->connect/disconnect methods under serio_sem */
794int serio_open(struct serio *serio, struct serio_driver *drv)
795{
796 serio_set_drv(serio, drv);
797
798 if (serio->open && serio->open(serio)) {
799 serio_set_drv(serio, NULL);
800 return -1;
801 }
802 return 0;
803}
804
805/* called from serio_driver->connect/disconnect methods under serio_sem */
806void serio_close(struct serio *serio)
807{
808 if (serio->close)
809 serio->close(serio);
810
811 serio_set_drv(serio, NULL);
812}
813
814irqreturn_t serio_interrupt(struct serio *serio,
815 unsigned char data, unsigned int dfl, struct pt_regs *regs)
816{
817 unsigned long flags;
818 irqreturn_t ret = IRQ_NONE;
819
820 spin_lock_irqsave(&serio->lock, flags);
821
822 if (likely(serio->drv)) {
823 ret = serio->drv->interrupt(serio, data, dfl, regs);
824 } else if (!dfl && serio->registered) {
825 serio_rescan(serio);
826 ret = IRQ_HANDLED;
827 }
828
829 spin_unlock_irqrestore(&serio->lock, flags);
830
831 return ret;
832}
833
834static int __init serio_init(void)
835{
836 if (!(serio_pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL))) {
837 printk(KERN_ERR "serio: Failed to start kseriod\n");
838 return -1;
839 }
840
841 serio_bus.dev_attrs = serio_device_attrs;
842 serio_bus.drv_attrs = serio_driver_attrs;
843 serio_bus.match = serio_bus_match;
844 serio_bus.hotplug = serio_hotplug;
845 serio_bus.resume = serio_resume;
846 bus_register(&serio_bus);
847
848 return 0;
849}
850
851static void __exit serio_exit(void)
852{
853 bus_unregister(&serio_bus);
854 kill_proc(serio_pid, SIGTERM, 1);
855 wait_for_completion(&serio_exited);
856}
857
858module_init(serio_init);
859module_exit(serio_exit);
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
new file mode 100644
index 000000000000..d914e7e93db4
--- /dev/null
+++ b/drivers/input/serio/serio_raw.c
@@ -0,0 +1,403 @@
1/*
2 * Raw serio device providing access to a raw byte stream from underlying
3 * serio port. Closely emulates behavior of pre-2.6 /dev/psaux device
4 *
5 * Copyright (c) 2004 Dmitry Torokhov
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#include <linux/slab.h>
13#include <linux/poll.h>
14#include <linux/module.h>
15#include <linux/serio.h>
16#include <linux/init.h>
17#include <linux/major.h>
18#include <linux/device.h>
19#include <linux/devfs_fs_kernel.h>
20#include <linux/miscdevice.h>
21#include <linux/wait.h>
22
23#define DRIVER_DESC "Raw serio driver"
24
25MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
26MODULE_DESCRIPTION(DRIVER_DESC);
27MODULE_LICENSE("GPL");
28
29#define SERIO_RAW_QUEUE_LEN 64
30struct serio_raw {
31 unsigned char queue[SERIO_RAW_QUEUE_LEN];
32 unsigned int tail, head;
33
34 char name[16];
35 unsigned int refcnt;
36 struct serio *serio;
37 struct miscdevice dev;
38 wait_queue_head_t wait;
39 struct list_head list;
40 struct list_head node;
41};
42
43struct serio_raw_list {
44 struct fasync_struct *fasync;
45 struct serio_raw *serio_raw;
46 struct list_head node;
47};
48
49static DECLARE_MUTEX(serio_raw_sem);
50static LIST_HEAD(serio_raw_list);
51static unsigned int serio_raw_no;
52
53/*********************************************************************
54 * Interface with userspace (file operations) *
55 *********************************************************************/
56
57static int serio_raw_fasync(int fd, struct file *file, int on)
58{
59 struct serio_raw_list *list = file->private_data;
60 int retval;
61
62 retval = fasync_helper(fd, file, on, &list->fasync);
63 return retval < 0 ? retval : 0;
64}
65
66static struct serio_raw *serio_raw_locate(int minor)
67{
68 struct serio_raw *serio_raw;
69
70 list_for_each_entry(serio_raw, &serio_raw_list, node) {
71 if (serio_raw->dev.minor == minor)
72 return serio_raw;
73 }
74
75 return NULL;
76}
77
78static int serio_raw_open(struct inode *inode, struct file *file)
79{
80 struct serio_raw *serio_raw;
81 struct serio_raw_list *list;
82 int retval = 0;
83
84 retval = down_interruptible(&serio_raw_sem);
85 if (retval)
86 return retval;
87
88 if (!(serio_raw = serio_raw_locate(iminor(inode)))) {
89 retval = -ENODEV;
90 goto out;
91 }
92
93 if (!serio_raw->serio) {
94 retval = -ENODEV;
95 goto out;
96 }
97
98 if (!(list = kmalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
99 retval = -ENOMEM;
100 goto out;
101 }
102
103 memset(list, 0, sizeof(struct serio_raw_list));
104 list->serio_raw = serio_raw;
105 file->private_data = list;
106
107 serio_raw->refcnt++;
108 list_add_tail(&list->node, &serio_raw->list);
109
110out:
111 up(&serio_raw_sem);
112 return retval;
113}
114
115static int serio_raw_cleanup(struct serio_raw *serio_raw)
116{
117 if (--serio_raw->refcnt == 0) {
118 misc_deregister(&serio_raw->dev);
119 list_del_init(&serio_raw->node);
120 kfree(serio_raw);
121
122 return 1;
123 }
124
125 return 0;
126}
127
128static int serio_raw_release(struct inode *inode, struct file *file)
129{
130 struct serio_raw_list *list = file->private_data;
131 struct serio_raw *serio_raw = list->serio_raw;
132
133 down(&serio_raw_sem);
134
135 serio_raw_fasync(-1, file, 0);
136 serio_raw_cleanup(serio_raw);
137
138 up(&serio_raw_sem);
139 return 0;
140}
141
142static int serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
143{
144 unsigned long flags;
145 int empty;
146
147 spin_lock_irqsave(&serio_raw->serio->lock, flags);
148
149 empty = serio_raw->head == serio_raw->tail;
150 if (!empty) {
151 *c = serio_raw->queue[serio_raw->tail];
152 serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
153 }
154
155 spin_unlock_irqrestore(&serio_raw->serio->lock, flags);
156
157 return !empty;
158}
159
160static ssize_t serio_raw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
161{
162 struct serio_raw_list *list = file->private_data;
163 struct serio_raw *serio_raw = list->serio_raw;
164 char c;
165 ssize_t retval = 0;
166
167 if (!serio_raw->serio)
168 return -ENODEV;
169
170 if (serio_raw->head == serio_raw->tail && (file->f_flags & O_NONBLOCK))
171 return -EAGAIN;
172
173 retval = wait_event_interruptible(list->serio_raw->wait,
174 serio_raw->head != serio_raw->tail || !serio_raw->serio);
175 if (retval)
176 return retval;
177
178 if (!serio_raw->serio)
179 return -ENODEV;
180
181 while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) {
182 if (put_user(c, buffer++))
183 return -EFAULT;
184 retval++;
185 }
186
187 return retval;
188}
189
190static ssize_t serio_raw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
191{
192 struct serio_raw_list *list = file->private_data;
193 ssize_t written = 0;
194 int retval;
195 unsigned char c;
196
197 retval = down_interruptible(&serio_raw_sem);
198 if (retval)
199 return retval;
200
201 if (!list->serio_raw->serio) {
202 retval = -ENODEV;
203 goto out;
204 }
205
206 if (count > 32)
207 count = 32;
208
209 while (count--) {
210 if (get_user(c, buffer++)) {
211 retval = -EFAULT;
212 goto out;
213 }
214 if (serio_write(list->serio_raw->serio, c)) {
215 retval = -EIO;
216 goto out;
217 }
218 written++;
219 };
220
221out:
222 up(&serio_raw_sem);
223 return written;
224}
225
226static unsigned int serio_raw_poll(struct file *file, poll_table *wait)
227{
228 struct serio_raw_list *list = file->private_data;
229
230 poll_wait(file, &list->serio_raw->wait, wait);
231
232 if (list->serio_raw->head != list->serio_raw->tail)
233 return POLLIN | POLLRDNORM;
234
235 return 0;
236}
237
238static struct file_operations serio_raw_fops = {
239 .owner = THIS_MODULE,
240 .open = serio_raw_open,
241 .release = serio_raw_release,
242 .read = serio_raw_read,
243 .write = serio_raw_write,
244 .poll = serio_raw_poll,
245 .fasync = serio_raw_fasync,
246};
247
248
249/*********************************************************************
250 * Interface with serio port *
251 *********************************************************************/
252
253static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
254 unsigned int dfl, struct pt_regs *regs)
255{
256 struct serio_raw *serio_raw = serio_get_drvdata(serio);
257 struct serio_raw_list *list;
258 unsigned int head = serio_raw->head;
259
260 /* we are holding serio->lock here so we are prootected */
261 serio_raw->queue[head] = data;
262 head = (head + 1) % SERIO_RAW_QUEUE_LEN;
263 if (likely(head != serio_raw->tail)) {
264 serio_raw->head = head;
265 list_for_each_entry(list, &serio_raw->list, node)
266 kill_fasync(&list->fasync, SIGIO, POLL_IN);
267 wake_up_interruptible(&serio_raw->wait);
268 }
269
270 return IRQ_HANDLED;
271}
272
273static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
274{
275 struct serio_raw *serio_raw;
276 int err;
277
278 if (!(serio_raw = kmalloc(sizeof(struct serio_raw), GFP_KERNEL))) {
279 printk(KERN_ERR "serio_raw.c: can't allocate memory for a device\n");
280 return -ENOMEM;
281 }
282
283 down(&serio_raw_sem);
284
285 memset(serio_raw, 0, sizeof(struct serio_raw));
286 snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++);
287 serio_raw->refcnt = 1;
288 serio_raw->serio = serio;
289 INIT_LIST_HEAD(&serio_raw->list);
290 init_waitqueue_head(&serio_raw->wait);
291
292 serio_set_drvdata(serio, serio_raw);
293
294 err = serio_open(serio, drv);
295 if (err)
296 goto out_free;
297
298 list_add_tail(&serio_raw->node, &serio_raw_list);
299
300 serio_raw->dev.minor = PSMOUSE_MINOR;
301 serio_raw->dev.name = serio_raw->name;
302 serio_raw->dev.fops = &serio_raw_fops;
303
304 err = misc_register(&serio_raw->dev);
305 if (err) {
306 serio_raw->dev.minor = MISC_DYNAMIC_MINOR;
307 err = misc_register(&serio_raw->dev);
308 }
309
310 if (err) {
311 printk(KERN_INFO "serio_raw: failed to register raw access device for %s\n",
312 serio->phys);
313 goto out_close;
314 }
315
316 printk(KERN_INFO "serio_raw: raw access enabled on %s (%s, minor %d)\n",
317 serio->phys, serio_raw->name, serio_raw->dev.minor);
318 goto out;
319
320out_close:
321 serio_close(serio);
322 list_del_init(&serio_raw->node);
323out_free:
324 serio_set_drvdata(serio, NULL);
325 kfree(serio_raw);
326out:
327 up(&serio_raw_sem);
328 return err;
329}
330
331static int serio_raw_reconnect(struct serio *serio)
332{
333 struct serio_raw *serio_raw = serio_get_drvdata(serio);
334 struct serio_driver *drv = serio->drv;
335
336 if (!drv || !serio_raw) {
337 printk(KERN_DEBUG "serio_raw: reconnect request, but serio is disconnected, ignoring...\n");
338 return -1;
339 }
340
341 /*
342 * Nothing needs to be done here, we just need this method to
343 * keep the same device.
344 */
345 return 0;
346}
347
348static void serio_raw_disconnect(struct serio *serio)
349{
350 struct serio_raw *serio_raw;
351
352 down(&serio_raw_sem);
353
354 serio_raw = serio_get_drvdata(serio);
355
356 serio_close(serio);
357 serio_set_drvdata(serio, NULL);
358
359 serio_raw->serio = NULL;
360 if (!serio_raw_cleanup(serio_raw))
361 wake_up_interruptible(&serio_raw->wait);
362
363 up(&serio_raw_sem);
364}
365
366static struct serio_device_id serio_raw_serio_ids[] = {
367 {
368 .type = SERIO_8042,
369 .proto = SERIO_ANY,
370 .id = SERIO_ANY,
371 .extra = SERIO_ANY,
372 },
373 { 0 }
374};
375
376MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
377
378static struct serio_driver serio_raw_drv = {
379 .driver = {
380 .name = "serio_raw",
381 },
382 .description = DRIVER_DESC,
383 .id_table = serio_raw_serio_ids,
384 .interrupt = serio_raw_interrupt,
385 .connect = serio_raw_connect,
386 .reconnect = serio_raw_reconnect,
387 .disconnect = serio_raw_disconnect,
388 .manual_bind = 1,
389};
390
391static int __init serio_raw_init(void)
392{
393 serio_register_driver(&serio_raw_drv);
394 return 0;
395}
396
397static void __exit serio_raw_exit(void)
398{
399 serio_unregister_driver(&serio_raw_drv);
400}
401
402module_init(serio_raw_init);
403module_exit(serio_raw_exit);
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
new file mode 100644
index 000000000000..22f73683952b
--- /dev/null
+++ b/drivers/input/serio/serport.c
@@ -0,0 +1,226 @@
1/*
2 * Input device TTY line discipline
3 *
4 * Copyright (c) 1999-2002 Vojtech Pavlik
5 *
6 * This is a module that converts a tty line into a much simpler
7 * 'serial io port' abstraction that the input device drivers use.
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published by
13 * the Free Software Foundation.
14 */
15
16#include <asm/uaccess.h>
17#include <linux/kernel.h>
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/serio.h>
22#include <linux/tty.h>
23
24MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
25MODULE_DESCRIPTION("Input device TTY line discipline");
26MODULE_LICENSE("GPL");
27MODULE_ALIAS_LDISC(N_MOUSE);
28
29#define SERPORT_BUSY 1
30
31struct serport {
32 struct tty_struct *tty;
33 wait_queue_head_t wait;
34 struct serio *serio;
35 unsigned long flags;
36};
37
38/*
39 * Callback functions from the serio code.
40 */
41
42static int serport_serio_write(struct serio *serio, unsigned char data)
43{
44 struct serport *serport = serio->port_data;
45 return -(serport->tty->driver->write(serport->tty, &data, 1) != 1);
46}
47
48static void serport_serio_close(struct serio *serio)
49{
50 struct serport *serport = serio->port_data;
51
52 serport->serio->id.type = 0;
53 wake_up_interruptible(&serport->wait);
54}
55
56/*
57 * serport_ldisc_open() is the routine that is called upon setting our line
58 * discipline on a tty. It prepares the serio struct.
59 */
60
61static int serport_ldisc_open(struct tty_struct *tty)
62{
63 struct serport *serport;
64 struct serio *serio;
65 char name[64];
66
67 if (!capable(CAP_SYS_ADMIN))
68 return -EPERM;
69
70 serport = kmalloc(sizeof(struct serport), GFP_KERNEL);
71 serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
72 if (unlikely(!serport || !serio)) {
73 kfree(serport);
74 kfree(serio);
75 return -ENOMEM;
76 }
77
78 memset(serport, 0, sizeof(struct serport));
79 serport->serio = serio;
80 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
81 serport->tty = tty;
82 tty->disc_data = serport;
83
84 memset(serio, 0, sizeof(struct serio));
85 strlcpy(serio->name, "Serial port", sizeof(serio->name));
86 snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
87 serio->id.type = SERIO_RS232;
88 serio->write = serport_serio_write;
89 serio->close = serport_serio_close;
90 serio->port_data = serport;
91
92 init_waitqueue_head(&serport->wait);
93
94 return 0;
95}
96
97/*
98 * serport_ldisc_close() is the opposite of serport_ldisc_open()
99 */
100
101static void serport_ldisc_close(struct tty_struct *tty)
102{
103 struct serport *serport = (struct serport*) tty->disc_data;
104 kfree(serport);
105}
106
107/*
108 * serport_ldisc_receive() is called by the low level tty driver when characters
109 * are ready for us. We forward the characters, one by one to the 'interrupt'
110 * routine.
111 *
112 * FIXME: We should get pt_regs from the tty layer and forward them to
113 * serio_interrupt here.
114 */
115
116static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
117{
118 struct serport *serport = (struct serport*) tty->disc_data;
119 int i;
120 for (i = 0; i < count; i++)
121 serio_interrupt(serport->serio, cp[i], 0, NULL);
122}
123
124/*
125 * serport_ldisc_room() reports how much room we do have for receiving data.
126 * Although we in fact have infinite room, we need to specify some value
127 * here, and 256 seems to be reasonable.
128 */
129
130static int serport_ldisc_room(struct tty_struct *tty)
131{
132 return 256;
133}
134
135/*
136 * serport_ldisc_read() just waits indefinitely if everything goes well.
137 * However, when the serio driver closes the serio port, it finishes,
138 * returning 0 characters.
139 */
140
141static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, unsigned char __user * buf, size_t nr)
142{
143 struct serport *serport = (struct serport*) tty->disc_data;
144 char name[64];
145
146 if (test_and_set_bit(SERPORT_BUSY, &serport->flags))
147 return -EBUSY;
148
149 serio_register_port(serport->serio);
150 printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name));
151 wait_event_interruptible(serport->wait, !serport->serio->id.type);
152 serio_unregister_port(serport->serio);
153
154 clear_bit(SERPORT_BUSY, &serport->flags);
155
156 return 0;
157}
158
159/*
160 * serport_ldisc_ioctl() allows to set the port protocol, and device ID
161 */
162
163static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
164{
165 struct serport *serport = (struct serport*) tty->disc_data;
166 struct serio *serio = serport->serio;
167 unsigned long type;
168
169 if (cmd == SPIOCSTYPE) {
170 if (get_user(type, (unsigned long __user *) arg))
171 return -EFAULT;
172
173 serio->id.proto = type & 0x000000ff;
174 serio->id.id = (type & 0x0000ff00) >> 8;
175 serio->id.extra = (type & 0x00ff0000) >> 16;
176
177 return 0;
178 }
179
180 return -EINVAL;
181}
182
183static void serport_ldisc_write_wakeup(struct tty_struct * tty)
184{
185 struct serport *sp = (struct serport *) tty->disc_data;
186
187 serio_drv_write_wakeup(sp->serio);
188}
189
190/*
191 * The line discipline structure.
192 */
193
194static struct tty_ldisc serport_ldisc = {
195 .owner = THIS_MODULE,
196 .name = "input",
197 .open = serport_ldisc_open,
198 .close = serport_ldisc_close,
199 .read = serport_ldisc_read,
200 .ioctl = serport_ldisc_ioctl,
201 .receive_buf = serport_ldisc_receive,
202 .receive_room = serport_ldisc_room,
203 .write_wakeup = serport_ldisc_write_wakeup
204};
205
206/*
207 * The functions for insering/removing us as a module.
208 */
209
210static int __init serport_init(void)
211{
212 int retval;
213 retval = tty_register_ldisc(N_MOUSE, &serport_ldisc);
214 if (retval)
215 printk(KERN_ERR "serport.c: Error registering line discipline.\n");
216
217 return retval;
218}
219
220static void __exit serport_exit(void)
221{
222 tty_register_ldisc(N_MOUSE, NULL);
223}
224
225module_init(serport_init);
226module_exit(serport_exit);