Commit 6a5ed193 authored by Vojtech Pavlik's avatar Vojtech Pavlik

Merge bkbits:input into suse.cz:/home/vojtech/bk/input

parents 34a39d46 2f3617d6
......@@ -942,6 +942,8 @@ void kbd_refresh_leds(struct input_handle *handle)
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SH_MPC1211)
#define HW_RAW(dev) (((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
static unsigned short x86_keycodes[256] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
......@@ -1008,6 +1010,8 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
#else
#define HW_RAW(dev) 0
#warning "Cannot generate rawmode keyboard for your architecture yet."
static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
......@@ -1020,7 +1024,15 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char u
}
#endif
void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
void kbd_rawcode(unsigned char data)
{
struct vc_data *vc = vc_cons[fg_console].d;
kbd = kbd_table + fg_console;
if (kbd->kbdmode == VC_RAW)
put_queue(vc, data);
}
void kbd_keycode(unsigned int keycode, int down, int hw_raw, struct pt_regs *regs)
{
struct vc_data *vc = vc_cons[fg_console].d;
unsigned short keysym, *key_map;
......@@ -1054,7 +1066,7 @@ void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
return;
#endif /* CONFIG_MAC_EMUMOUSEBTN */
if ((raw_mode = (kbd->kbdmode == VC_RAW)))
if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
if (emulate_raw(vc, keycode, !down << 7))
if (keycode < BTN_MISC)
printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
......@@ -1149,11 +1161,12 @@ void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
}
static void kbd_event(struct input_handle *handle, unsigned int event_type,
unsigned int keycode, int down)
unsigned int event_code, int value)
{
if (event_type != EV_KEY)
return;
kbd_keycode(keycode, down, handle->dev->regs);
if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
kbd_rawcode(value);
if (event_type == EV_KEY)
kbd_keycode(event_code, value, HW_RAW(handle->dev), handle->dev->regs);
tasklet_schedule(&keyboard_tasklet);
do_poke_blanked_console = 1;
schedule_console_callback();
......
......@@ -280,6 +280,8 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
if (!test_bit(ATKBD_FLAG_ENABLED, &atkbd->flags))
goto out;
input_event(&atkbd->dev, EV_MSC, MSC_RAW, code);
if (atkbd->translated) {
if (atkbd->emul ||
......@@ -435,7 +437,7 @@ static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command)
atkbd->cmdcnt = receive;
if (command == ATKBD_CMD_RESET_BAT)
timeout = 2000000; /* 2 sec */
timeout = 4000000; /* 4 sec */
if (receive && param)
for (i = 0; i < receive; i++)
......@@ -753,9 +755,10 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
}
if (atkbd->write) {
atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP) | BIT(EV_MSC);
atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
} else atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
} else atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
atkbd->dev.mscbit[0] = BIT(MSC_RAW);
if (!atkbd_softrepeat) {
atkbd->dev.rep[REP_DELAY] = 250;
......@@ -796,7 +799,6 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd->id = 0xab00;
}
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");
......
......@@ -142,34 +142,45 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
flags & SERIO_TIMEOUT ? " timeout" : "",
flags & SERIO_PARITY ? " bad parity" : "");
if (psmouse->acking) {
psmouse->ack = -1;
psmouse->acking = 0;
}
psmouse->pktcnt = 0;
psmouse->nak = 1;
clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
goto out;
}
if (psmouse->acking) {
if (test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags))
switch (data) {
case PSMOUSE_RET_ACK:
psmouse->ack = 1;
psmouse->nak = 0;
clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
goto out;
break;
case PSMOUSE_RET_NAK:
psmouse->ack = -1;
break;
psmouse->nak = 1;
clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
goto out;
default:
psmouse->ack = 1; /* Workaround for mice which don't ACK the Get ID command */
if (psmouse->cmdcnt)
psmouse->cmdbuf[--psmouse->cmdcnt] = data;
break;
psmouse->nak = 0; /* Workaround for mice which don't ACK the Get ID command */
clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
if (!test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags))
goto out;
}
psmouse->acking = 0;
goto out;
}
if (psmouse->cmdcnt) {
psmouse->cmdbuf[--psmouse->cmdcnt] = data;
if (test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags)) {
psmouse->cmdcnt--;
psmouse->cmdbuf[psmouse->cmdcnt] = data;
if (psmouse->cmdcnt == 1) {
if (data != 0xab && data != 0xac)
clear_bit(PSMOUSE_FLAG_ID, &psmouse->flags);
clear_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags);
}
if (!psmouse->cmdcnt)
clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
goto out;
}
......@@ -242,18 +253,15 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
static int psmouse_sendbyte(struct psmouse *psmouse, unsigned char byte)
{
int timeout = 10000; /* 100 msec */
psmouse->ack = 0;
psmouse->acking = 1;
int timeout = 200000; /* 200 msec */
if (serio_write(psmouse->serio, byte)) {
psmouse->acking = 0;
set_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
if (serio_write(psmouse->serio, byte))
return -1;
}
while (!psmouse->ack && timeout--) udelay(10);
while (test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags) && timeout--) udelay(1);
clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
return -(psmouse->ack <= 0);
return -psmouse->nak;
}
/*
......@@ -271,46 +279,62 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
psmouse->cmdcnt = receive;
if (command == PSMOUSE_CMD_RESET_BAT)
timeout = 4000000; /* 4 sec */
timeout = 4000000; /* 4 sec */
/* initialize cmdbuf with preset values from param */
if (receive)
for (i = 0; i < receive; i++)
psmouse->cmdbuf[(receive - 1) - i] = param[i];
if (receive && param)
for (i = 0; i < receive; i++)
psmouse->cmdbuf[(receive - 1) - i] = param[i];
if (receive) {
set_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
set_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags);
set_bit(PSMOUSE_FLAG_ID, &psmouse->flags);
}
if (command & 0xff)
if (psmouse_sendbyte(psmouse, command & 0xff))
return (psmouse->cmdcnt = 0) - 1;
if (psmouse_sendbyte(psmouse, command & 0xff)) {
clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
return -1;
}
for (i = 0; i < send; i++)
if (psmouse_sendbyte(psmouse, param[i]))
return (psmouse->cmdcnt = 0) - 1;
if (psmouse_sendbyte(psmouse, param[i])) {
clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
return -1;
}
while (psmouse->cmdcnt && timeout--) {
while (test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags) && timeout--) {
if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_RESET_BAT &&
timeout > 100000) /* do not run in a endless loop */
timeout = 100000; /* 1 sec */
if (!test_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags)) {
if (command == PSMOUSE_CMD_RESET_BAT && timeout > 100000)
timeout = 100000;
if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_GETID &&
psmouse->cmdbuf[1] != 0xab && psmouse->cmdbuf[1] != 0xac) {
psmouse->cmdcnt = 0;
break;
if (command == PSMOUSE_CMD_GETID && !test_bit(PSMOUSE_FLAG_ID, &psmouse->flags)) {
clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
psmouse->cmdcnt = 0;
break;
}
}
udelay(1);
}
for (i = 0; i < receive; i++)
param[i] = psmouse->cmdbuf[(receive - 1) - i];
clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
if (param)
for (i = 0; i < receive; i++)
param[i] = psmouse->cmdbuf[(receive - 1) - i];
if (command == PSMOUSE_CMD_RESET_BAT && psmouse->cmdcnt == 1)
return 0;
if (psmouse->cmdcnt)
return (psmouse->cmdcnt = 0) - 1;
return -1;
return 0;
}
/*
* psmouse_sliced_command() sends an extended PS/2 command to the mouse
* using sliced syntax, understood by advanced devices, such as Logitech
......@@ -735,7 +759,12 @@ static int psmouse_reconnect(struct serio *serio)
}
psmouse->state = PSMOUSE_CMD_MODE;
psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;
clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
psmouse->pktcnt = psmouse->out_of_sync = 0;
if (psmouse->reconnect) {
if (psmouse->reconnect(psmouse))
return -1;
......
......@@ -22,6 +22,11 @@
#define PSMOUSE_ACTIVATED 1
#define PSMOUSE_IGNORE 2
#define PSMOUSE_FLAG_ACK 0 /* Waiting for ACK/NAK */
#define PSMOUSE_FLAG_CMD 1 /* Waiting for command to finish */
#define PSMOUSE_FLAG_CMD1 2 /* First byte of command response */
#define PSMOUSE_FLAG_ID 3 /* First byte is not keyboard ID */
/* psmouse protocol handler return codes */
typedef enum {
PSMOUSE_BAD_DATA,
......@@ -54,11 +59,11 @@ struct psmouse {
unsigned long last;
unsigned long out_of_sync;
unsigned char state;
char acking;
volatile char ack;
unsigned char nak;
char error;
char devname[64];
char phys[32];
unsigned long flags;
psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
int (*reconnect)(struct psmouse *psmouse);
......
......@@ -527,6 +527,7 @@ struct input_absinfo {
#define MSC_SERIAL 0x00
#define MSC_PULSELED 0x01
#define MSC_GESTURE 0x02
#define MSC_RAW 0x03
#define MSC_MAX 0x07
/*
......
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