Commit 36ea144c authored by Vojtech Pavlik's avatar Vojtech Pavlik

input: Fix keyboard scrollwheel support, add horizontal

       wheel support, and enable both by default.
Signed-off-by: default avatarVojtech Pavlik <vojtech@suse.cz>
parent aeef0574
...@@ -54,7 +54,7 @@ static int atkbd_softraw = 1; ...@@ -54,7 +54,7 @@ static int atkbd_softraw = 1;
module_param_named(softraw, atkbd_softraw, bool, 0); module_param_named(softraw, atkbd_softraw, bool, 0);
MODULE_PARM_DESC(softraw, "Use software generated rawmode"); MODULE_PARM_DESC(softraw, "Use software generated rawmode");
static int atkbd_scroll; static int atkbd_scroll = 1;
module_param_named(scroll, atkbd_scroll, bool, 0); module_param_named(scroll, atkbd_scroll, bool, 0);
MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
...@@ -143,7 +143,6 @@ static unsigned char atkbd_unxlate_table[128] = { ...@@ -143,7 +143,6 @@ static unsigned char atkbd_unxlate_table[128] = {
#define ATKBD_CMD_EX_SETLEDS 0x20eb #define ATKBD_CMD_EX_SETLEDS 0x20eb
#define ATKBD_CMD_OK_GETID 0x02e8 #define ATKBD_CMD_OK_GETID 0x02e8
#define ATKBD_RET_ACK 0xfa #define ATKBD_RET_ACK 0xfa
#define ATKBD_RET_NAK 0xfe #define ATKBD_RET_NAK 0xfe
#define ATKBD_RET_BAT 0xaa #define ATKBD_RET_BAT 0xaa
...@@ -162,15 +161,22 @@ static unsigned char atkbd_unxlate_table[128] = { ...@@ -162,15 +161,22 @@ static unsigned char atkbd_unxlate_table[128] = {
#define ATKBD_SCR_4 252 #define ATKBD_SCR_4 252
#define ATKBD_SCR_8 251 #define ATKBD_SCR_8 251
#define ATKBD_SCR_CLICK 250 #define ATKBD_SCR_CLICK 250
#define ATKBD_SCR_LEFT 249
#define ATKBD_SPECIAL 250 #define ATKBD_SCR_RIGHT 248
static unsigned char atkbd_scroll_keys[5][2] = { #define ATKBD_SPECIAL 248
{ ATKBD_SCR_1, 0x45 },
{ ATKBD_SCR_2, 0x29 }, static struct {
{ ATKBD_SCR_4, 0x36 }, unsigned char keycode;
{ ATKBD_SCR_8, 0x27 }, unsigned char set2;
{ ATKBD_SCR_CLICK, 0x60 }, } atkbd_scroll_keys[] = {
{ ATKBD_SCR_1, 0xc5 },
{ ATKBD_SCR_2, 0xa9 },
{ ATKBD_SCR_4, 0xb6 },
{ ATKBD_SCR_8, 0xa7 },
{ ATKBD_SCR_CLICK, 0xe0 },
{ ATKBD_SCR_LEFT, 0xcb },
{ ATKBD_SCR_RIGHT, 0xd2 },
}; };
/* /*
...@@ -253,7 +259,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -253,7 +259,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
{ {
struct atkbd *atkbd = serio_get_drvdata(serio); struct atkbd *atkbd = serio_get_drvdata(serio);
unsigned int code = data; unsigned int code = data;
int scroll = 0, click = -1; int scroll = 0, hscroll = 0, click = -1;
int value; int value;
#ifdef ATKBD_DEBUG #ifdef ATKBD_DEBUG
...@@ -372,6 +378,12 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -372,6 +378,12 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
case ATKBD_SCR_CLICK: case ATKBD_SCR_CLICK:
click = !atkbd->release; click = !atkbd->release;
break; break;
case ATKBD_SCR_LEFT:
hscroll = -1;
break;
case ATKBD_SCR_RIGHT:
hscroll = 1;
break;
default: default:
value = atkbd->release ? 0 : value = atkbd->release ? 0 :
(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key))); (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
...@@ -393,10 +405,12 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -393,10 +405,12 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value); atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
} }
if (scroll || click != -1) { if (atkbd_scroll) {
input_regs(&atkbd->dev, regs); input_regs(&atkbd->dev, regs);
if (click != -1)
input_report_key(&atkbd->dev, BTN_MIDDLE, click); input_report_key(&atkbd->dev, BTN_MIDDLE, click);
input_report_rel(&atkbd->dev, REL_WHEEL, scroll); input_report_rel(&atkbd->dev, REL_WHEEL, scroll);
input_report_rel(&atkbd->dev, REL_HWHEEL, hscroll);
input_sync(&atkbd->dev); input_sync(&atkbd->dev);
} }
...@@ -405,7 +419,6 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -405,7 +419,6 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/* /*
* Event callback from the input module. Events that change the state of * Event callback from the input module. Events that change the state of
* the hardware are processed here. * the hardware are processed here.
...@@ -697,12 +710,9 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) ...@@ -697,12 +710,9 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]]; atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80]; atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
if (atkbd->scroll) if (atkbd->scroll)
for (j = 0; i < 5; i++) { for (j = 0; j < ARRAY_SIZE(atkbd_scroll_keys); j++)
if (atkbd_unxlate_table[i] == atkbd_scroll_keys[j][1]) if ((atkbd_unxlate_table[i] | 0x80) == atkbd_scroll_keys[j].set2)
atkbd->keycode[i] = atkbd_scroll_keys[j][0]; atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j].keycode;
if ((atkbd_unxlate_table[i] | 0x80) == atkbd_scroll_keys[j][1])
atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j][0];
}
} }
} else if (atkbd->set == 3) { } else if (atkbd->set == 3) {
memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode)); memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
...@@ -710,8 +720,8 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) ...@@ -710,8 +720,8 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode)); memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
if (atkbd->scroll) if (atkbd->scroll)
for (i = 0; i < 5; i++) for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++)
atkbd->keycode[atkbd_scroll_keys[i][1]] = atkbd_scroll_keys[i][0]; atkbd->keycode[atkbd_scroll_keys[i].set2] = atkbd_scroll_keys[i].keycode;
} }
} }
...@@ -757,7 +767,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) ...@@ -757,7 +767,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
if (atkbd->scroll) { if (atkbd->scroll) {
atkbd->dev.evbit[0] |= BIT(EV_REL); atkbd->dev.evbit[0] |= BIT(EV_REL);
atkbd->dev.relbit[0] = BIT(REL_WHEEL); atkbd->dev.relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
set_bit(BTN_MIDDLE, atkbd->dev.keybit); set_bit(BTN_MIDDLE, atkbd->dev.keybit);
} }
......
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