2 * nvec_ps2: mouse driver for a NVIDIA compliant embedded controller
4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.launchpad.net>
6 * Authors: Pierre-Hugues Husson <phhusson@free.fr>
7 * Ilya Petrov <ilya.muromec@gmail.com>
8 * Marc Dietrich <marvin24@gmx.de>
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
16 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include <linux/serio.h>
19 #include <linux/delay.h>
20 #include <linux/platform_device.h>
24 #define START_STREAMING {'\x06', '\x03', '\x04'}
25 #define STOP_STREAMING {'\x06', '\x04'}
26 #define SEND_COMMAND {'\x06', '\x01', '\xf4', '\x01'}
28 static const unsigned char MOUSE_RESET
[] = {'\x06', '\x01', '\xff', '\x03'};
31 struct serio
*ser_dev
;
32 struct notifier_block notifier
;
33 struct nvec_chip
*nvec
;
36 static struct nvec_ps2 ps2_dev
;
38 static int ps2_startstreaming(struct serio
*ser_dev
)
40 unsigned char buf
[] = START_STREAMING
;
41 return nvec_write_async(ps2_dev
.nvec
, buf
, sizeof(buf
));
44 static void ps2_stopstreaming(struct serio
*ser_dev
)
46 unsigned char buf
[] = STOP_STREAMING
;
47 nvec_write_async(ps2_dev
.nvec
, buf
, sizeof(buf
));
50 static int ps2_sendcommand(struct serio
*ser_dev
, unsigned char cmd
)
52 unsigned char buf
[] = SEND_COMMAND
;
56 dev_dbg(&ser_dev
->dev
, "Sending ps2 cmd %02x\n", cmd
);
57 return nvec_write_async(ps2_dev
.nvec
, buf
, sizeof(buf
));
60 static int nvec_ps2_notifier(struct notifier_block
*nb
,
61 unsigned long event_type
, void *data
)
64 unsigned char *msg
= (unsigned char *)data
;
68 for (i
= 0; i
< msg
[1]; i
++)
69 serio_interrupt(ps2_dev
.ser_dev
, msg
[2 + i
], 0);
74 for (i
= 0; i
< (msg
[1] - 2); i
++)
75 serio_interrupt(ps2_dev
.ser_dev
, msg
[i
+ 4], 0);
76 else if (msg
[1] != 2) { /* !ack */
77 print_hex_dump(KERN_WARNING
, "unhandled mouse event: ",
78 DUMP_PREFIX_NONE
, 16, 1,
79 msg
, msg
[1] + 2, true);
88 static int __devinit
nvec_mouse_probe(struct platform_device
*pdev
)
90 struct nvec_chip
*nvec
= dev_get_drvdata(pdev
->dev
.parent
);
91 struct serio
*ser_dev
= kzalloc(sizeof(struct serio
), GFP_KERNEL
);
93 ser_dev
->id
.type
= SERIO_8042
;
94 ser_dev
->write
= ps2_sendcommand
;
95 ser_dev
->open
= ps2_startstreaming
;
96 ser_dev
->close
= ps2_stopstreaming
;
98 strlcpy(ser_dev
->name
, "nvec mouse", sizeof(ser_dev
->name
));
99 strlcpy(ser_dev
->phys
, "nvec", sizeof(ser_dev
->phys
));
101 ps2_dev
.ser_dev
= ser_dev
;
102 ps2_dev
.notifier
.notifier_call
= nvec_ps2_notifier
;
104 nvec_register_notifier(nvec
, &ps2_dev
.notifier
, 0);
106 serio_register_port(ser_dev
);
109 nvec_write_async(nvec
, MOUSE_RESET
, 4);
114 static struct platform_driver nvec_mouse_driver
= {
115 .probe
= nvec_mouse_probe
,
117 .name
= "nvec-mouse",
118 .owner
= THIS_MODULE
,
122 static int __init
nvec_mouse_init(void)
124 return platform_driver_register(&nvec_mouse_driver
);
127 module_init(nvec_mouse_init
);
129 MODULE_DESCRIPTION("NVEC mouse driver");
130 MODULE_AUTHOR("Marc Dietrich <marvin24@gmx.de>");
131 MODULE_LICENSE("GPL");