Commit 7af32430 authored by Vojtech Pavlik's avatar Vojtech Pavlik

Merge suse.cz:/data/bk/linus into suse.cz:/data/bk/input

parents 472bca81 7c660b15
......@@ -896,8 +896,8 @@ running once the system is up.
psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports
per second.
psmouse.resetafter=
[HW,MOUSE] Try to reset Synaptics Touchpad after so many
bad packets (0 = never).
[HW,MOUSE] Try to reset the device after so many bad packets
(0 = never).
psmouse.resolution=
[HW,MOUSE] Set desired mouse resolution, in dpi.
psmouse.smartscroll=
......
......@@ -41,9 +41,16 @@ config INPUT_MOUSEDEV
module will be called mousedev.
config INPUT_MOUSEDEV_PSAUX
bool "Provide legacy /dev/psaux device" if EMBEDDED
bool "Provide legacy /dev/psaux device"
default y
depends on INPUT_MOUSEDEV
---help---
Say Y here if you want your mouse also be accessible as char device
10:1 - /dev/psaux. The data available through /dev/psaux is exactly
the same as the data from /dev/input/mice.
If unsure, say Y.
config INPUT_MOUSEDEV_SCREEN_X
int "Horizontal screen resolution"
......
......@@ -106,7 +106,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
}
break;
case EV_ABS:
if (code > ABS_MAX || !test_bit(code, dev->absbit))
......@@ -144,27 +144,27 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
if (code > MSC_MAX || !test_bit(code, dev->mscbit))
return;
if (dev->event) dev->event(dev, type, code, value);
if (dev->event) dev->event(dev, type, code, value);
break;
case EV_LED:
if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
return;
change_bit(code, dev->led);
if (dev->event) dev->event(dev, type, code, value);
if (dev->event) dev->event(dev, type, code, value);
break;
case EV_SND:
if (code > SND_MAX || !test_bit(code, dev->sndbit))
return;
if (dev->event) dev->event(dev, type, code, value);
if (dev->event) dev->event(dev, type, code, value);
break;
case EV_REP:
......@@ -181,7 +181,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
break;
}
if (type != EV_SYN)
if (type != EV_SYN)
dev->sync = 0;
if (dev->grab)
......@@ -282,11 +282,11 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
if (id->id.vendor != dev->id.vendor)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
if (id->id.product != dev->id.product)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
if (id->id.version != dev->id.version)
continue;
......@@ -351,11 +351,11 @@ static void input_call_hotplug(char *verb, struct input_dev *dev)
}
if (in_interrupt()) {
printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
return;
return;
}
if (!current->fs->root) {
printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
return;
return;
}
if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
......@@ -381,17 +381,17 @@ static void input_call_hotplug(char *verb, struct input_dev *dev)
envp[i++] = scratch;
scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
if (dev->name) {
envp[i++] = scratch;
scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
}
if (dev->phys) {
envp[i++] = scratch;
scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
}
scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
}
SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
......@@ -506,7 +506,7 @@ void input_register_handler(struct input_handler *handler)
input_table[handler->minor >> 5] = handler;
list_add_tail(&handler->node, &input_handler_list);
list_for_each_entry(dev, &input_dev_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((id = input_match_device(handler->id_table, dev)))
......
......@@ -26,7 +26,6 @@
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
......@@ -173,22 +172,24 @@ struct atkbd {
unsigned char keycode[512];
struct input_dev dev;
struct serio *serio;
struct timer_list timer;
char name[64];
char phys[32];
unsigned short id;
unsigned char set;
unsigned int translated:1;
unsigned int extra:1;
unsigned int write:1;
unsigned char cmdbuf[4];
unsigned char cmdcnt;
unsigned char set;
unsigned char extra;
unsigned char release;
int lastkey;
volatile signed char ack;
unsigned char emul;
unsigned short id;
unsigned char write;
unsigned char translated;
unsigned char resend;
unsigned char bat_xl;
unsigned int resend:1;
unsigned int release:1;
unsigned int bat_xl:1;
unsigned int enabled:1;
unsigned int last;
unsigned long time;
};
......@@ -248,6 +249,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
goto out;
}
if (!atkbd->enabled)
goto out;
if (atkbd->translated) {
if (atkbd->emul ||
......@@ -300,15 +304,20 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
case ATKBD_KEY_NULL:
break;
case ATKBD_KEY_UNKNOWN:
printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
atkbd->release ? "released" : "pressed",
atkbd->translated ? "translated" : "raw",
atkbd->set, code, serio->phys);
if (atkbd->translated && atkbd->set == 2 && code == 0x7a)
printk(KERN_WARNING "atkbd.c: This is an XFree86 bug. It shouldn't access"
" hardware directly.\n");
else
printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n", code & 0x80 ? "e0" : "", code & 0x7f);
if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
"like XFree86, might be trying access hardware directly.\n",
data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
} else {
printk(KERN_WARNING "atkbd.c: Unknown key %s "
"(%s set %d, code %#x on %s).\n",
atkbd->release ? "released" : "pressed",
atkbd->translated ? "translated" : "raw",
atkbd->set, code, serio->phys);
printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' "
"to make it known.\n",
code & 0x80 ? "e0" : "", code & 0x7f);
}
break;
case ATKBD_SCR_1:
scroll = 1 - atkbd->release * 2;
......@@ -745,6 +754,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd->id = 0xab00;
}
atkbd->enabled = 1;
if (atkbd->extra) {
atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
sprintf(atkbd->name, "AT Set 2 Extra keyboard");
......@@ -809,12 +820,12 @@ static int atkbd_reconnect(struct serio *serio)
param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
| (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0)
| (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0);
if (atkbd_probe(atkbd))
return -1;
if (atkbd->set != atkbd_set_3(atkbd))
return -1;
atkbd_enable(atkbd);
if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
......
......@@ -41,11 +41,11 @@ static int spkr98_event(struct input_dev *dev, unsigned int type, unsigned int c
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
}
}
if (value > 20 && value < 32767)
count = CLOCK_TICK_RATE / value;
spin_lock_irqsave(&i8253_beep_lock, flags);
if (count) {
......
......@@ -40,11 +40,11 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
}
}
if (value > 20 && value < 32767)
count = CLOCK_TICK_RATE / value;
spin_lock_irqsave(&i8253_beep_lock, flags);
if (count) {
......
......@@ -53,11 +53,11 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
}
}
if (value > 20 && value < 32767)
count = 1193182 / value;
spin_lock_irqsave(&beep_lock, flags);
/* EBUS speaker only has on/off state, the frequency does not
......@@ -108,11 +108,11 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
}
}
if (value > 20 && value < 32767)
count = 1193182 / value;
spin_lock_irqsave(&beep_lock, flags);
if (count) {
......
......@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
*
*
* Changes/Revisions:
* 0.1 20/06/2002
* - first public version
......@@ -68,7 +68,7 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff
static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
{
return 0;
}
}
static int uinput_create_device(struct uinput_device *udev)
{
......@@ -123,7 +123,7 @@ static int uinput_open(struct inode *inode, struct file *file)
memset(newinput, 0, sizeof(struct input_dev));
newdev->dev = newinput;
file->private_data = newdev;
return 0;
......@@ -137,16 +137,16 @@ static int uinput_validate_absbits(struct input_dev *dev)
{
unsigned int cnt;
int retval = 0;
for (cnt = 0; cnt < ABS_MAX; cnt++) {
if (!test_bit(cnt, dev->absbit))
if (!test_bit(cnt, dev->absbit))
continue;
if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
(dev->absmax[cnt] <= dev->absmin[cnt])) {
printk(KERN_DEBUG
printk(KERN_DEBUG
"%s: invalid abs[%02x] min:%d max:%d\n",
UINPUT_NAME, cnt,
UINPUT_NAME, cnt,
dev->absmin[cnt], dev->absmax[cnt]);
retval = -EINVAL;
break;
......@@ -154,7 +154,7 @@ static int uinput_validate_absbits(struct input_dev *dev)
if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
(dev->absflat[cnt] > dev->absmax[cnt])) {
printk(KERN_DEBUG
printk(KERN_DEBUG
"%s: absflat[%02x] out of range: %d "
"(min:%d/max:%d)\n",
UINPUT_NAME, cnt, dev->absflat[cnt],
......@@ -190,7 +190,7 @@ static int uinput_alloc_device(struct file *file, const char *buffer, size_t cou
goto exit;
}
if (NULL != dev->name)
if (NULL != dev->name)
kfree(dev->name);
size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
......@@ -229,7 +229,7 @@ static int uinput_alloc_device(struct file *file, const char *buffer, size_t cou
static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
{
struct uinput_device *udev = file->private_data;
if (test_bit(UIST_CREATED, &(udev->state))) {
struct input_event ev;
......@@ -247,7 +247,7 @@ static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t
{
struct uinput_device *udev = file->private_data;
int retval = 0;
if (!test_bit(UIST_CREATED, &(udev->state)))
return -ENODEV;
......@@ -255,16 +255,16 @@ static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t
return -EAGAIN;
retval = wait_event_interruptible(udev->waitq,
(udev->head != udev->tail) ||
(udev->head != udev->tail) ||
!test_bit(UIST_CREATED, &(udev->state)));
if (retval)
return retval;
if (!test_bit(UIST_CREATED, &(udev->state)))
return -ENODEV;
while ((udev->head != udev->tail) &&
while ((udev->head != udev->tail) &&
(retval + sizeof(struct input_event) <= count)) {
if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
sizeof(struct input_event))) return -EFAULT;
......@@ -284,7 +284,7 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait)
if (udev->head != udev->tail)
return POLLIN | POLLRDNORM;
return 0;
return 0;
}
static int uinput_burn_device(struct uinput_device *udev)
......@@ -318,7 +318,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
case UI_DEV_CREATE:
retval = uinput_create_device(udev);
break;
case UI_DEV_DESTROY:
retval = uinput_destroy_device(udev);
break;
......@@ -330,7 +330,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
set_bit(arg, udev->dev->evbit);
break;
case UI_SET_KEYBIT:
if (arg > KEY_MAX) {
retval = -EINVAL;
......@@ -338,7 +338,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
set_bit(arg, udev->dev->keybit);
break;
case UI_SET_RELBIT:
if (arg > REL_MAX) {
retval = -EINVAL;
......@@ -346,7 +346,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
set_bit(arg, udev->dev->relbit);
break;
case UI_SET_ABSBIT:
if (arg > ABS_MAX) {
retval = -EINVAL;
......@@ -354,7 +354,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
set_bit(arg, udev->dev->absbit);
break;
case UI_SET_MSCBIT:
if (arg > MSC_MAX) {
retval = -EINVAL;
......@@ -362,7 +362,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
set_bit(arg, udev->dev->mscbit);
break;
case UI_SET_LEDBIT:
if (arg > LED_MAX) {
retval = -EINVAL;
......@@ -370,7 +370,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
set_bit(arg, udev->dev->ledbit);
break;
case UI_SET_SNDBIT:
if (arg > SND_MAX) {
retval = -EINVAL;
......@@ -378,7 +378,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
set_bit(arg, udev->dev->sndbit);
break;
case UI_SET_FFBIT:
if (arg > FF_MAX) {
retval = -EINVAL;
......@@ -386,7 +386,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
set_bit(arg, udev->dev->ffbit);
break;
default:
retval = -EFAULT;
}
......
......@@ -63,7 +63,6 @@ void ps2pp_process_packet(struct psmouse *psmouse)
packet[0] &= 0x0f;
packet[1] = 0;
packet[2] = 0;
}
}
......@@ -76,18 +75,9 @@ void ps2pp_process_packet(struct psmouse *psmouse)
static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
{
unsigned char d;
int i;
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
if (psmouse_sliced_command(psmouse, command))
return -1;
for (i = 6; i >= 0; i -= 2) {
d = (command >> i) & 3;
if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
return -1;
}
if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
return -1;
......@@ -99,7 +89,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
* enabled if we do nothing to it. Of course I put this in because I want it
* disabled :P
* 1 - enabled (if previously disabled, also default)
* 0/2 - disabled
* 0/2 - disabled
*/
static void ps2pp_set_smartscroll(struct psmouse *psmouse)
......@@ -113,14 +103,11 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse)
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
if (psmouse_smartscroll == 1)
param[0] = 1;
else
if (psmouse_smartscroll > 2)
return;
/* else leave param[0] == 0 to disable */
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
if (psmouse_smartscroll < 2) {
/* 0 - disabled, 1 - enabled */
param[0] = psmouse_smartscroll;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
}
}
/*
......@@ -138,111 +125,128 @@ void ps2pp_set_800dpi(struct psmouse *psmouse)
psmouse_command(psmouse, &param, PSMOUSE_CMD_SETRES);
}
static int is_model_in_list(unsigned char model, int *model_list)
{
int i;
for (i = 0; model_list[i] != -1; i++)
if (model == model_list[i])
return 1;
return 0;
}
/*
* Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or
* touchpad.
* Set up input device's properties based on the detected mouse model.
*/
static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
static void ps2pp_set_properties(struct psmouse *psmouse, unsigned char protocol,
unsigned char model, unsigned char buttons)
{
int i;
static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 };
static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
76, 80, 81, 83, 88, 96, 97, 112, -1 };
static int logitech_mx[] = { 61, 112, -1 };
psmouse->vendor = "Logitech";
psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
psmouse->model = model;
if (param[1] < 3)
if (buttons < 3)
clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
if (param[1] < 2)
if (buttons < 2)
clear_bit(BTN_RIGHT, psmouse->dev.keybit);
psmouse->type = PSMOUSE_PS2;
if (protocol == PSMOUSE_PS2PP) {
for (i = 0; logitech_ps2pp[i] != -1; i++)
if (logitech_ps2pp[i] == psmouse->model)
psmouse->type = PSMOUSE_PS2PP;
if (is_model_in_list(model, logitech_4btn))
set_bit(BTN_SIDE, psmouse->dev.keybit);
if (psmouse->type == PSMOUSE_PS2PP) {
if (is_model_in_list(model, logitech_wheel)) {
set_bit(REL_WHEEL, psmouse->dev.relbit);
psmouse->name = "Wheel Mouse";
}
for (i = 0; logitech_4btn[i] != -1; i++)
if (logitech_4btn[i] == psmouse->model)
set_bit(BTN_SIDE, psmouse->dev.keybit);
if (is_model_in_list(model, logitech_mx)) {
set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(BTN_EXTRA, psmouse->dev.keybit);
set_bit(BTN_BACK, psmouse->dev.keybit);
set_bit(BTN_FORWARD, psmouse->dev.keybit);
set_bit(BTN_TASK, psmouse->dev.keybit);
psmouse->name = "MX Mouse";
}
}
for (i = 0; logitech_wheel[i] != -1; i++)
if (logitech_wheel[i] == psmouse->model) {
set_bit(REL_WHEEL, psmouse->dev.relbit);
psmouse->name = "Wheel Mouse";
}
if (protocol == PSMOUSE_PS2TPP) {
set_bit(REL_WHEEL, psmouse->dev.relbit);
set_bit(REL_HWHEEL, psmouse->dev.relbit);
psmouse->name = "TouchPad 3";
}
}
for (i = 0; logitech_mx[i] != -1; i++)
if (logitech_mx[i] == psmouse->model) {
set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(BTN_EXTRA, psmouse->dev.keybit);
set_bit(BTN_BACK, psmouse->dev.keybit);
set_bit(BTN_FORWARD, psmouse->dev.keybit);
set_bit(BTN_TASK, psmouse->dev.keybit);
psmouse->name = "MX Mouse";
}
/*
* Do Logitech PS2++ / PS2T++ magic init.
* Logitech magic init. Detect whether the mouse is a Logitech one
* and its exact model and try turning on extended protocol for ones
* that support it.
*/
if (psmouse->model == 97) { /* TouchPad 3 */
int ps2pp_init(struct psmouse *psmouse, int set_properties)
{
static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75,
76, 80, 81, 83, 88, 96, 97, 112, -1 };
unsigned char param[4];
unsigned char protocol = PSMOUSE_PS2;
unsigned char model, buttons;
param[0] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
param[1] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
set_bit(REL_WHEEL, psmouse->dev.relbit);
set_bit(REL_HWHEEL, psmouse->dev.relbit);
if (param[1] != 0) {
model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
buttons = param[1];
/*
* Do Logitech PS2++ / PS2T++ magic init.
*/
if (model == 97) { /* Touch Pad 3 */
param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */
/* Unprotect RAM */
param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
psmouse_command(psmouse, param, 0x30d1);
param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */
/* Enable features */
param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b;
psmouse_command(psmouse, param, 0x30d1);
param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */
/* Enable PS2++ */
param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3;
psmouse_command(psmouse, param, 0x30d1);
param[0] = 0;
if (!psmouse_command(psmouse, param, 0x13d1) &&
param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
psmouse->name = "TouchPad 3";
return PSMOUSE_PS2TPP;
param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
protocol = PSMOUSE_PS2TPP;
}
} else {
} else if (is_model_in_list(model, logitech_ps2pp)) {
param[0] = param[1] = param[2] = 0;
ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
ps2pp_cmd(psmouse, param, 0xDB);
if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
(param[2] & 3) == ((param[1] >> 2) & 3)) {
ps2pp_set_smartscroll(psmouse);
return PSMOUSE_PS2PP;
if ((param[0] & 0x78) == 0x48 &&
(param[1] & 0xf3) == 0xc2 &&
(param[2] & 0x03) == ((param[1] >> 2) & 3)) {
ps2pp_set_smartscroll(psmouse);
protocol = PSMOUSE_PS2PP;
}
}
}
return 0;
}
/*
* Logitech magic init.
*/
int ps2pp_detect(struct psmouse *psmouse)
{
unsigned char param[4];
param[0] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
param[1] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
if (set_properties)
ps2pp_set_properties(psmouse, protocol, model, buttons);
}
return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0;
return protocol;
}
......@@ -10,8 +10,9 @@
#ifndef _LOGIPS2PP_H
#define _LOGIPS2PP_H
struct psmouse;
void ps2pp_process_packet(struct psmouse *psmouse);
void ps2pp_set_800dpi(struct psmouse *psmouse);
int ps2pp_detect(struct psmouse *psmouse);
int ps2pp_init(struct psmouse *psmouse, int set_properties);
#endif
......@@ -43,9 +43,9 @@ int psmouse_smartscroll = 1;
module_param_named(smartscroll, psmouse_smartscroll, bool, 0);
MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
unsigned int psmouse_resetafter;
static unsigned int psmouse_resetafter;
module_param_named(resetafter, psmouse_resetafter, uint, 0);
MODULE_PARM_DESC(resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
__obsolete_setup("psmouse_noext");
__obsolete_setup("psmouse_resolution=");
......@@ -56,15 +56,22 @@ __obsolete_setup("psmouse_rate=");
static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
/*
* psmouse_process_packet() analyzes the PS/2 mouse packet contents and
* reports relevant events to the input module.
* psmouse_process_byte() analyzes the PS/2 data stream and reports
* relevant events to the input module once full packet has arrived.
*/
static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{
struct input_dev *dev = &psmouse->dev;
unsigned char *packet = psmouse->packet;
if (psmouse->pktcnt < 3 + (psmouse->type >= PSMOUSE_GENPS))
return PSMOUSE_GOOD_DATA;
/*
* Full packet accumulated, process it
*/
input_regs(dev, regs);
/*
......@@ -112,6 +119,8 @@ static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs
input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
input_sync(dev);
return PSMOUSE_FULL_PACKET;
}
/*
......@@ -123,6 +132,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
struct psmouse *psmouse = serio->private;
psmouse_ret_t rc;
if (psmouse->state == PSMOUSE_IGNORE)
goto out;
......@@ -180,7 +190,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
if (psmouse->pktcnt == 2) {
if (psmouse->packet[1] == PSMOUSE_RET_ID) {
psmouse->state = PSMOUSE_IGNORE;
serio_rescan(serio);
serio_reconnect(serio);
goto out;
}
if (psmouse->type == PSMOUSE_SYNAPTICS) {
......@@ -193,19 +203,32 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
}
}
if (psmouse->type == PSMOUSE_SYNAPTICS) {
/*
* The synaptics driver has its own resync logic,
* so it needs to receive all bytes one at a time.
*/
synaptics_process_byte(psmouse, regs);
goto out;
}
rc = psmouse->protocol_handler(psmouse, regs);
if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
psmouse_process_packet(psmouse, regs);
psmouse->pktcnt = 0;
goto out;
switch (rc) {
case PSMOUSE_BAD_DATA:
printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->pktcnt = 0;
if (++psmouse->out_of_sync == psmouse_resetafter) {
psmouse->state = PSMOUSE_IGNORE;
printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
serio_reconnect(psmouse->serio);
}
break;
case PSMOUSE_FULL_PACKET:
psmouse->pktcnt = 0;
if (psmouse->out_of_sync) {
psmouse->out_of_sync = 0;
printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
psmouse->name, psmouse->phys);
}
break;
case PSMOUSE_GOOD_DATA:
break;
}
out:
return IRQ_HANDLED;
......@@ -288,6 +311,30 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
}
/*
* psmouse_sliced_command() sends an extended PS/2 command to the mouse
* using sliced syntax, understood by advanced devices, such as Logitech
* or Synaptics touchpads. The command is encoded as:
* 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
* is the command.
*/
int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
{
int i;
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
return -1;
for (i = 6; i >= 0; i -= 2) {
unsigned char d = (command >> i) & 3;
if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
return -1;
}
return 0;
}
/*
* psmouse_reset() resets the mouse into power-on state.
*/
......@@ -363,23 +410,23 @@ static int im_explorer_detect(struct psmouse *psmouse)
* the mouse may have.
*/
static int psmouse_extensions(struct psmouse *psmouse)
static int psmouse_extensions(struct psmouse *psmouse,
unsigned int max_proto, int set_properties)
{
int synaptics_hardware = 0;
psmouse->vendor = "Generic";
psmouse->name = "Mouse";
psmouse->model = 0;
/*
* Try Synaptics TouchPad
*/
if (psmouse_max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
synaptics_hardware = 1;
psmouse->vendor = "Synaptics";
psmouse->name = "TouchPad";
if (psmouse_max_proto > PSMOUSE_IMEX) {
if (set_properties) {
psmouse->vendor = "Synaptics";
psmouse->name = "TouchPad";
}
if (max_proto > PSMOUSE_IMEX) {
if (synaptics_init(psmouse) == 0)
return PSMOUSE_SYNAPTICS;
/*
......@@ -387,7 +434,7 @@ static int psmouse_extensions(struct psmouse *psmouse)
* Unfortunately Logitech/Genius probes confuse some firmware versions so
* we'll have to skip them.
*/
psmouse_max_proto = PSMOUSE_IMEX;
max_proto = PSMOUSE_IMEX;
}
/*
* Make sure that touchpad is in relative mode, gestures (taps) are enabled
......@@ -395,35 +442,45 @@ static int psmouse_extensions(struct psmouse *psmouse)
synaptics_reset(psmouse);
}
if (psmouse_max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
set_bit(BTN_EXTRA, psmouse->dev.keybit);
set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(REL_WHEEL, psmouse->dev.relbit);
if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
if (set_properties) {
set_bit(BTN_EXTRA, psmouse->dev.keybit);
set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(REL_WHEEL, psmouse->dev.relbit);
psmouse->vendor = "Genius";
psmouse->name = "Wheel Mouse";
}
psmouse->vendor = "Genius";
psmouse->name = "Wheel Mouse";
return PSMOUSE_GENPS;
}
if (psmouse_max_proto > PSMOUSE_IMEX) {
int type = ps2pp_detect(psmouse);
if (type)
if (max_proto > PSMOUSE_IMEX) {
int type = ps2pp_init(psmouse, set_properties);
if (type > PSMOUSE_PS2)
return type;
}
if (psmouse_max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
set_bit(REL_WHEEL, psmouse->dev.relbit);
if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
if (psmouse_max_proto >= PSMOUSE_IMEX &&
im_explorer_detect(psmouse)) {
set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(BTN_EXTRA, psmouse->dev.keybit);
if (set_properties) {
set_bit(REL_WHEEL, psmouse->dev.relbit);
if (!psmouse->name)
psmouse->name = "Wheel Mouse";
}
if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) {
if (!set_properties) {
set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(BTN_EXTRA, psmouse->dev.keybit);
if (!psmouse->name)
psmouse->name = "Explorer Mouse";
}
psmouse->name = "Explorer Mouse";
return PSMOUSE_IMEX;
}
psmouse->name = "Wheel Mouse";
return PSMOUSE_IMPS;
}
......@@ -473,12 +530,7 @@ static int psmouse_probe(struct psmouse *psmouse)
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS))
printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys);
/*
* And here we try to determine if it has any extensions over the
* basic PS/2 3-button mouse.
*/
return psmouse->type = psmouse_extensions(psmouse);
return 0;
}
/*
......@@ -616,7 +668,6 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
psmouse->state = PSMOUSE_CMD_MODE;
psmouse->serio = serio;
psmouse->dev.private = psmouse;
......@@ -628,13 +679,21 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
return;
}
if (psmouse_probe(psmouse) <= 0) {
if (psmouse_probe(psmouse) < 0) {
serio_close(serio);
kfree(psmouse);
serio->private = NULL;
return;
}
psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
if (!psmouse->vendor)
psmouse->vendor = "Generic";
if (!psmouse->name)
psmouse->name = "Mouse";
if (!psmouse->protocol_handler)
psmouse->protocol_handler = psmouse_process_byte;
sprintf(psmouse->devname, "%s %s %s",
psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
sprintf(psmouse->phys, "%s/input0",
......@@ -668,27 +727,24 @@ static int psmouse_reconnect(struct serio *serio)
{
struct psmouse *psmouse = serio->private;
struct serio_dev *dev = serio->dev;
int old_type;
if (!dev || !psmouse) {
printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
return -1;
}
old_type = psmouse->type;
psmouse->state = PSMOUSE_CMD_MODE;
psmouse->type = psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = 0;
psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;
if (psmouse->reconnect) {
if (psmouse->reconnect(psmouse))
return -1;
} else if (psmouse_probe(psmouse) != old_type)
} else if (psmouse_probe(psmouse) < 0 ||
psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
return -1;
/* ok, the device type (and capabilities) match the old one,
* we can continue using it, complete intialization
*/
psmouse->type = old_type;
psmouse_initialize(psmouse);
if (psmouse->ptport) {
......
......@@ -22,6 +22,13 @@
#define PSMOUSE_ACTIVATED 1
#define PSMOUSE_IGNORE 2
/* psmouse protocol handler return codes */
typedef enum {
PSMOUSE_BAD_DATA,
PSMOUSE_GOOD_DATA,
PSMOUSE_FULL_PACKET
} psmouse_ret_t;
struct psmouse;
struct psmouse_ptport {
......@@ -45,6 +52,7 @@ struct psmouse {
unsigned char type;
unsigned char model;
unsigned long last;
unsigned long out_of_sync;
unsigned char state;
char acking;
volatile char ack;
......@@ -52,6 +60,7 @@ struct psmouse {
char devname[64];
char phys[32];
psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
int (*reconnect)(struct psmouse *psmouse);
void (*disconnect)(struct psmouse *psmouse);
};
......@@ -65,10 +74,10 @@ struct psmouse {
#define PSMOUSE_SYNAPTICS 7
int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
int psmouse_reset(struct psmouse *psmouse);
extern int psmouse_smartscroll;
extern unsigned int psmouse_rate;
extern unsigned int psmouse_resetafter;
#endif /* _PSMOUSE_H */
This diff is collapsed.
......@@ -9,7 +9,6 @@
#ifndef _SYNAPTICS_H
#define _SYNAPTICS_H
extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
extern int synaptics_detect(struct psmouse *psmouse);
extern int synaptics_init(struct psmouse *psmouse);
extern void synaptics_reset(struct psmouse *psmouse);
......@@ -44,13 +43,14 @@ extern void synaptics_reset(struct psmouse *psmouse);
/* synaptics capability bits */
#define SYN_CAP_EXTENDED(c) ((c) & (1 << 23))
#define SYN_CAP_MIDDLE_BUTTON(c) ((c) & (1 << 18))
#define SYN_CAP_PASS_THROUGH(c) ((c) & (1 << 7))
#define SYN_CAP_SLEEP(c) ((c) & (1 << 4))
#define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3))
#define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1))
#define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0))
#define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47)
#define SYN_EXT_CAP_REQUESTS(c) ((((c) & 0x700000) >> 20) == 1)
#define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20)
#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
/* synaptics modes query bits */
......@@ -86,18 +86,12 @@ struct synaptics_hw_state {
int y;
int z;
int w;
int left;
int right;
int up;
int down;
int b0;
int b1;
int b2;
int b3;
int b4;
int b5;
int b6;
int b7;
unsigned int left:1;
unsigned int right:1;
unsigned int middle:1;
unsigned int up:1;
unsigned int down:1;
unsigned char ext_buttons;
};
struct synaptics_data {
......@@ -108,7 +102,6 @@ struct synaptics_data {
unsigned long int identity; /* Identification */
/* Data for normal processing */
unsigned int out_of_sync; /* # of packets out of sync */
int old_w; /* Previous w value */
unsigned char pkt_type; /* packet type - old, new, etc */
};
......
......@@ -391,9 +391,9 @@ static ssize_t mousedev_write(struct file * file, const char * buffer, size_t co
list->impsseq = 0;
list->imexseq = 0;
list->mode = 0;
list->ps2[0] = 0xaa;
list->ps2[1] = 0x00;
list->bufsiz = 2;
list->ps2[1] = 0xaa;
list->ps2[2] = 0x00;
list->bufsiz = 3;
break;
}
......
......@@ -474,8 +474,17 @@ static int i8042_enable_mux_mode(struct i8042_values *values, unsigned char *mux
if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
return -1;
param = 0xa4;
if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b) {
/*
* Do another loop test with the 0x5a value. Doing anything else upsets
* Profusion/ServerWorks OSB4 chipsets.
*/
param = 0x5a;
i8042_command(&param, I8042_CMD_AUX_LOOP);
return -1;
}
if (mux_version)
*mux_version = ~param;
......@@ -532,8 +541,8 @@ static int __init i8042_check_mux(struct i8042_values *values)
return -1;
/* Workaround for broken chips which seem to support MUX, but in reality don't. */
/* They all report version 12.10 */
if (mux_version == 0xCA)
/* They all report version 10.12 */
if (mux_version == 0xAC)
return -1;
printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
......
......@@ -86,20 +86,9 @@ static int parkbd_write(struct serio *port, unsigned char c)
return 0;
}
static int parkbd_open(struct serio *port)
{
return 0;
}
static void parkbd_close(struct serio *port)
{
}
static struct serio parkbd_port =
{
.write = parkbd_write,
.open = parkbd_open,
.close = parkbd_close,
.name = parkbd_name,
.phys = parkbd_phys,
};
......
......@@ -47,23 +47,12 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
MODULE_LICENSE("GPL");
static int q40kbd_open(struct serio *port)
{
return 0;
}
static void q40kbd_close(struct serio *port)
{
}
static struct serio q40kbd_port =
{
.type = SERIO_8042,
.name = "Q40 kbd port",
.phys = "Q40",
.write = NULL,
.open = q40kbd_open,
.close = q40kbd_close,
};
static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
......
......@@ -11,18 +11,18 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
......@@ -108,7 +108,7 @@ void serio_handle_events(void)
struct serio_event *event;
list_for_each_safe(node, next, &serio_event_list) {
event = container_of(node, struct serio_event, node);
event = container_of(node, struct serio_event, node);
down(&serio_sem);
if (event->serio == NULL)
......@@ -152,7 +152,7 @@ static int serio_thread(void *nothing)
do {
serio_handle_events();
wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
if (current->flags & PF_FREEZE)
refrigerator(PF_FREEZE);
} while (!signal_pending(current));
......@@ -293,7 +293,7 @@ void serio_unregister_device(struct serio_dev *dev)
int serio_open(struct serio *serio, struct serio_dev *dev)
{
serio->dev = dev;
if (serio->open(serio)) {
if (serio->open && serio->open(serio)) {
serio->dev = NULL;
return -1;
}
......@@ -303,7 +303,8 @@ int serio_open(struct serio *serio, struct serio_dev *dev)
/* called from serio_dev->connect/disconnect methods under serio_sem */
void serio_close(struct serio *serio)
{
serio->close(serio);
if (serio->close)
serio->close(serio);
serio->dev = NULL;
}
......
......@@ -48,11 +48,6 @@ static int serport_serio_write(struct serio *serio, unsigned char data)
return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1);
}
static int serport_serio_open(struct serio *serio)
{
return 0;
}
static void serport_serio_close(struct serio *serio)
{
struct serport *serport = serio->driver;
......@@ -87,7 +82,6 @@ static int serport_ldisc_open(struct tty_struct *tty)
serport->serio.type = SERIO_RS232;
serport->serio.write = serport_serio_write;
serport->serio.open = serport_serio_open;
serport->serio.close = serport_serio_close;
serport->serio.driver = serport;
......@@ -135,7 +129,7 @@ static int serport_ldisc_room(struct tty_struct *tty)
}
/*
* serport_ldisc_read() just waits indefinitely if everything goes well.
* serport_ldisc_read() just waits indefinitely if everything goes well.
* However, when the serio driver closes the serio port, it finishes,
* returning 0 characters.
*/
......@@ -165,7 +159,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u
static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
{
struct serport *serport = (struct serport*) tty->disc_data;
if (cmd == SPIOCSTYPE)
return get_user(serport->serio.type, (unsigned long *) arg);
......
......@@ -124,12 +124,10 @@ static void gunze_connect(struct serio *serio, struct serio_dev *dev)
memset(gunze, 0, sizeof(struct gunze));
init_input_dev(&gunze->dev);
gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
gunze->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
gunze->dev.absmin[ABS_X] = 96; gunze->dev.absmin[ABS_Y] = 72;
gunze->dev.absmax[ABS_X] = 4000; gunze->dev.absmax[ABS_Y] = 3000;
input_set_abs_params(&gunze->dev, ABS_X, 96, 4000, 0, 0);
input_set_abs_params(&gunze->dev, ABS_Y, 72, 3000, 0, 0);
gunze->serio = serio;
serio->private = gunze;
......
/*
* $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $
*
* Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
* Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
*
* Sponsored by Transvirtual Technology.
*
* Derived from the code in h3600_ts.[ch] by Charles Flynn
* Sponsored by Transvirtual Technology.
*
* Derived from the code in h3600_ts.[ch] by Charles Flynn
*/
/*
......@@ -75,7 +75,7 @@
#define MAX_ID 14
#define H3600_MAX_LENGTH 16
#define H3600_KEY 0xf
#define H3600_KEY 0xf
#define H3600_SCANCODE_RECORD 1 /* 1 -> record button */
#define H3600_SCANCODE_CALENDAR 2 /* 2 -> calendar */
......@@ -118,13 +118,13 @@ static void npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
struct input_dev *dev = (struct input_dev *) dev_id;
/*
* This interrupt is only called when we release the key. So we have
/*
* This interrupt is only called when we release the key. So we have
* to fake a key press.
*/
*/
input_regs(dev, regs);
input_report_key(dev, KEY_SUSPEND, 1);
input_report_key(dev, KEY_SUSPEND, down);
input_report_key(dev, KEY_SUSPEND, down);
input_sync(dev);
}
......@@ -144,18 +144,18 @@ unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
unsigned char brightness = ((pwr==FLITE_PWR_OFF) ? 0:flite_brightness);
struct h3600_dev *ts = dev->private;
/* Must be in this order */
/* Must be in this order */
ts->serio->write(ts->serio, 1);
ts->serio->write(ts->serio, pwr);
ts->serio->write(ts->serio, brightness);
ts->serio->write(ts->serio, brightness);
return 0;
}
static int suspended = 0;
static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
void *data)
{
struct input_dev *dev = (struct input_dev *) data;
struct input_dev *dev = (struct input_dev *) data;
switch (req) {
case PM_SUSPEND: /* enter D1-D3 */
......@@ -183,7 +183,7 @@ static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
/*
* This function translates the native event packets to linux input event
* packets. Some packets coming from serial are not touchscreen related. In
* this case we send them off to be processed elsewhere.
* this case we send them off to be processed elsewhere.
*/
static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
{
......@@ -206,7 +206,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
Note: This is true for non interrupt generated key events.
*/
case KEYBD_ID:
down = (ts->buf[0] & 0x80) ? 0 : 1;
down = (ts->buf[0] & 0x80) ? 0 : 1;
switch (ts->buf[0] & 0x7f) {
case H3600_SCANCODE_RECORD:
......@@ -218,7 +218,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
case H3600_SCANCODE_CONTACTS:
key = KEY_PROG2;
break;
case H3600_SCANCODE_Q:
case H3600_SCANCODE_Q:
key = KEY_Q;
break;
case H3600_SCANCODE_START:
......@@ -237,9 +237,9 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
key = KEY_DOWN;
break;
default:
key = 0;
}
if (key)
key = 0;
}
if (key)
input_report_key(dev, key, down);
break;
/*
......@@ -251,13 +251,13 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
* byte 0 1 2 3
*/
case TOUCHS_ID:
if (!touched) {
if (!touched) {
input_report_key(dev, BTN_TOUCH, 1);
touched = 1;
}
}
if (ts->len) {
unsigned short x, y;
unsigned short x, y;
x = ts->buf[0]; x <<= 8; x += ts->buf[1];
y = ts->buf[2]; y <<= 8; y += ts->buf[3];
......@@ -267,7 +267,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
} else {
input_report_key(dev, BTN_TOUCH, 0);
touched = 0;
}
}
break;
default:
/* Send a non input event elsewhere */
......@@ -280,7 +280,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
/*
* h3600ts_event() handles events from the input module.
*/
static int h3600ts_event(struct input_dev *dev, unsigned int type,
static int h3600ts_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
struct h3600_dev *ts = dev->private;
......@@ -290,7 +290,7 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type,
// ts->serio->write(ts->serio, SOME_CMD);
return 0;
}
}
}
return -1;
}
......@@ -323,12 +323,12 @@ static void h3600ts_interrupt(struct serio *serio, unsigned char data,
struct h3600_dev *ts = serio->private;
/*
* We have a new frame coming in.
* We have a new frame coming in.
*/
switch (state) {
case STATE_SOF:
if (data == CHAR_SOF)
state = STATE_ID;
state = STATE_ID;
return;
case STATE_ID:
ts->event = (data & 0xf0) >> 4;
......@@ -344,7 +344,7 @@ static void h3600ts_interrupt(struct serio *serio, unsigned char data,
case STATE_DATA:
ts->chksum += data;
ts->buf[ts->idx]= data;
if(++ts->idx == ts->len)
if(++ts->idx == ts->len)
state = STATE_EOF;
break;
case STATE_EOF:
......@@ -382,7 +382,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
set_GPIO_IRQ_edge( GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE );
if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
"h3600_action", &ts->dev)) {
printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
kfree(ts);
......@@ -390,24 +390,19 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
}
if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
"h3600_suspend", &ts->dev)) {
free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
kfree(ts);
return;
}
/* Now we have things going we setup our input device */
ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
ts->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
ts->dev.ledbit[0] = BIT(LED_SLEEP);
ts->dev.absmin[ABS_X] = 60; ts->dev.absmin[ABS_Y] = 35;
ts->dev.absmax[ABS_X] = 985; ts->dev.absmax[ABS_Y] = 1024;
ts->dev.absfuzz[ABS_X] = 0; ts->dev.absfuzz[ABS_Y] = 0;
ts->serio = serio;
serio->private = ts;
ts->dev.ledbit[0] = BIT(LED_SLEEP);
input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0);
input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0);
set_bit(KEY_RECORD, ts->dev.keybit);
set_bit(KEY_Q, ts->dev.keybit);
......@@ -422,6 +417,9 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
ts->serio = serio;
serio->private = ts;
sprintf(ts->phys, "%s/input0", serio->phys);
ts->dev.event = h3600ts_event;
......@@ -442,7 +440,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
//h3600_flite_control(1, 25); /* default brightness */
#ifdef CONFIG_PM
ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
h3600ts_pm_callback);
printk("registered pm callback\n");
#endif
......@@ -458,7 +456,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
static void h3600ts_disconnect(struct serio *serio)
{
struct h3600_dev *ts = serio->private;
free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
input_unregister_device(&ts->dev);
......
......@@ -655,7 +655,7 @@ struct ff_periodic_effect {
struct ff_envelope envelope;
/* Only used if waveform == FF_CUSTOM */
__u32 custom_len; /* Number of samples */
__u32 custom_len; /* Number of samples */
__s16 *custom_data; /* Buffer of samples */
/* Note: the data pointed by custom_data is copied by the driver. You can
* therefore dispose of the memory after the upload/update */
......@@ -749,8 +749,6 @@ struct ff_effect {
#define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
#define init_input_dev(dev) do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
#define SET_INPUT_KEYCODE(dev, scancode, val) \
({ unsigned __old; \
switch (dev->keycodesize) { \
......@@ -915,6 +913,12 @@ struct input_handle {
#define to_handle(n) container_of(n,struct input_handle,d_node)
#define to_handle_h(n) container_of(n,struct input_handle,h_node)
static inline void init_input_dev(struct input_dev *dev)
{
INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node);
}
void input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *);
......@@ -932,14 +936,51 @@ int input_flush_device(struct input_handle* handle, struct file* file);
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
#define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c))
#define input_report_rel(a,b,c) input_event(a, EV_REL, b, c)
#define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c)
#define input_report_ff(a,b,c) input_event(a, EV_FF, b, c)
#define input_report_ff_status(a,b,c) input_event(a, EV_FF_STATUS, b, c)
#define input_regs(a,b) do { (a)->regs = (b); } while (0)
#define input_sync(a) do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0)
static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_KEY, code, !!value);
}
static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_REL, code, value);
}
static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_ABS, code, value);
}
static inline void input_report_ff(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_FF, code, value);
}
static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_FF_STATUS, code, value);
}
static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
{
dev->regs = regs;
}
static inline void input_sync(struct input_dev *dev)
{
input_event(dev, EV_SYN, SYN_REPORT, 0);
dev->regs = NULL;
}
static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
{
dev->absmin[axis] = min;
dev->absmax[axis] = max;
dev->absfuzz[axis] = fuzz;
dev->absflat[axis] = flat;
dev->absbit[LONG(axis)] |= BIT(axis);
}
extern struct class_simple *input_class;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment