PageRenderTime 55ms CodeModel.GetById 22ms app.highlight 19ms RepoModel.GetById 5ms app.codeStats 0ms

/drivers/staging/nvec/nvec_ps2.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 103 lines | 74 code | 23 blank | 6 comment | 8 complexity | 34a3ccd9550075b5b9725e840098e0ce MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1#include <linux/slab.h>
  2#include <linux/serio.h>
  3#include <linux/delay.h>
  4#include "nvec.h"
  5
  6#define START_STREAMING	{'\x06','\x03','\x01'}
  7#define STOP_STREAMING	{'\x06','\x04'}
  8#define SEND_COMMAND	{'\x06','\x01','\xf4','\x01'}
  9
 10struct nvec_ps2
 11{
 12	struct serio *ser_dev;
 13	struct notifier_block notifier;
 14	struct nvec_chip *nvec;
 15};
 16
 17static struct nvec_ps2 ps2_dev;
 18
 19static int ps2_startstreaming(struct serio *ser_dev)
 20{
 21	unsigned char buf[] = START_STREAMING;
 22	nvec_write_async(ps2_dev.nvec, buf, sizeof(buf));
 23	return 0;
 24}
 25
 26static void ps2_stopstreaming(struct serio *ser_dev)
 27{
 28	unsigned char buf[] = STOP_STREAMING;
 29	nvec_write_async(ps2_dev.nvec, buf, sizeof(buf));
 30}
 31
 32/* is this really needed?
 33static void nvec_resp_handler(unsigned char *data) {
 34	serio_interrupt(ser_dev, data[4], 0);
 35}
 36*/
 37
 38static int ps2_sendcommand(struct serio *ser_dev, unsigned char cmd)
 39{
 40	unsigned char buf[] = SEND_COMMAND;
 41
 42	buf[2] = cmd & 0xff;
 43
 44	dev_dbg(&ser_dev->dev, "Sending ps2 cmd %02x\n", cmd);
 45	nvec_write_async(ps2_dev.nvec, buf, sizeof(buf));
 46
 47	return 0;
 48}
 49
 50static int nvec_ps2_notifier(struct notifier_block *nb,
 51				unsigned long event_type, void *data)
 52{
 53	int i;
 54	unsigned char *msg = (unsigned char *)data;
 55
 56	switch (event_type) {
 57		case NVEC_PS2_EVT:
 58			serio_interrupt(ps2_dev.ser_dev, msg[2], 0);
 59			return NOTIFY_STOP;
 60
 61		case NVEC_PS2:
 62			if (msg[2] == 1)
 63				for(i = 0; i < (msg[1] - 2); i++)
 64					serio_interrupt(ps2_dev.ser_dev, msg[i+4], 0);
 65			else if (msg[1] != 2) /* !ack */
 66			{
 67				printk("nvec_ps2: unhandled mouse event ");
 68				for(i = 0; i <= (msg[1]+1); i++)
 69					printk("%02x ", msg[i]);
 70				printk(".\n");
 71			}
 72
 73			return NOTIFY_STOP;
 74	}
 75
 76	return NOTIFY_DONE;
 77}
 78
 79
 80int __init nvec_ps2(struct nvec_chip *nvec)
 81{
 82	struct serio *ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL);
 83
 84	ser_dev->id.type=SERIO_8042;
 85	ser_dev->write=ps2_sendcommand;
 86	ser_dev->open=ps2_startstreaming;
 87	ser_dev->close=ps2_stopstreaming;
 88
 89	strlcpy(ser_dev->name, "NVEC PS2", sizeof(ser_dev->name));
 90	strlcpy(ser_dev->phys, "NVEC I2C slave", sizeof(ser_dev->phys));
 91
 92	ps2_dev.ser_dev = ser_dev;
 93	ps2_dev.notifier.notifier_call = nvec_ps2_notifier;
 94	ps2_dev.nvec = nvec;
 95	nvec_register_notifier(nvec, &ps2_dev.notifier, 0);
 96
 97	serio_register_port(ser_dev);
 98
 99	/* mouse reset */
100	nvec_write_async(nvec, "\x06\x01\xff\x03", 4);
101
102	return 0;
103}