12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/module.h>
15 #include <linux/serio.h>
21 #define PS2MULT_KB_SELECTOR 0xA0
22 #define PS2MULT_MS_SELECTOR 0xA1
23 #define PS2MULT_ESCAPE 0x7D
24 #define PS2MULT_BSYNC 0x7E
25 #define PS2MULT_SESSION_START 0x55
26 #define PS2MULT_SESSION_END 0x56
34 #define PS2MULT_NUM_PORTS 2
35 #define PS2MULT_KBD_PORT 0
36 #define PS2MULT_MOUSE_PORT 1
49 static const unsigned char ps2mult_controls[] = {
71 serio_write(mx_serio, port->
sel);
76 static int ps2mult_serio_write(
struct serio *
serio,
unsigned char data)
78 struct serio *mx_port = serio->
parent;
79 struct ps2mult *
psm = serio_get_drvdata(mx_port);
87 ps2mult_select_port(psm, port);
89 need_escape =
memchr(ps2mult_controls, data,
sizeof(ps2mult_controls));
92 "write: %s%02x\n", need_escape ?
"ESC " :
"", data);
97 serio_write(mx_port, data);
99 spin_unlock_irqrestore(&psm->
lock, flags);
104 static int ps2mult_serio_start(
struct serio *serio)
112 spin_unlock_irqrestore(&psm->
lock, flags);
117 static void ps2mult_serio_stop(
struct serio *serio)
125 spin_unlock_irqrestore(&psm->
lock, flags);
128 static int ps2mult_create_port(
struct ps2mult *psm,
int i)
130 struct serio *mx_serio = psm->
mx_serio;
133 serio = kzalloc(
sizeof(
struct serio),
GFP_KERNEL);
139 "%s/port%d", mx_serio->
phys, i);
141 serio->
write = ps2mult_serio_write;
142 serio->
start = ps2mult_serio_start;
143 serio->
stop = ps2mult_serio_stop;
147 psm->
ports[
i].serio = serio;
152 static void ps2mult_reset(
struct ps2mult *psm)
163 spin_unlock_irqrestore(&psm->
lock, flags);
166 static int ps2mult_connect(
struct serio *serio,
struct serio_driver *
drv)
183 psm->
ports[
i].sel = ps2mult_controls[
i];
184 error = ps2mult_create_port(psm, i);
191 serio_set_drvdata(serio, psm);
199 struct serio *
s = psm->
ports[
i].serio;
214 static void ps2mult_disconnect(
struct serio *serio)
216 struct ps2mult *psm = serio_get_drvdata(serio);
223 serio_set_drvdata(serio,
NULL);
226 static int ps2mult_reconnect(
struct serio *serio)
228 struct ps2mult *psm = serio_get_drvdata(serio);
235 static irqreturn_t ps2mult_interrupt(
struct serio *serio,
236 unsigned char data,
unsigned int dfl)
238 struct ps2mult *psm = serio_get_drvdata(serio);
242 dev_dbg(&serio->
dev,
"Received %02x flags %02x\n", data, dfl);
291 spin_unlock_irqrestore(&psm->
lock, flags);
299 .description =
"TQC PS/2 Multiplexer driver",
300 .id_table = ps2mult_serio_ids,
301 .interrupt = ps2mult_interrupt,
302 .connect = ps2mult_connect,
303 .disconnect = ps2mult_disconnect,
304 .reconnect = ps2mult_reconnect,