[PATCH] Input: Add a new switch event type
The corgi keyboard has need of a switch event type with slightly type to the input system as recommended by the input maintainer. Signed-off-by: Richard Purdie <rpurdie@rpsys.net> Cc: Vojtech Pavlik <vojtech@suse.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
41b1bce80b
commit
3158106685
4 changed files with 49 additions and 4 deletions
|
@ -393,6 +393,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
|
||||
case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
|
||||
case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
|
||||
case EV_SW: bits = dev->swbit; len = SW_MAX; break;
|
||||
default: return -EINVAL;
|
||||
}
|
||||
len = NBITS(len) * sizeof(long);
|
||||
|
@ -421,6 +422,13 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
|
||||
}
|
||||
|
||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) {
|
||||
int len;
|
||||
len = NBITS(SW_MAX) * sizeof(long);
|
||||
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
|
||||
return copy_to_user(p, dev->sw, len) ? -EFAULT : len;
|
||||
}
|
||||
|
||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
|
||||
int len;
|
||||
if (!dev->name) return -ENOENT;
|
||||
|
|
|
@ -89,6 +89,15 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
|
|||
|
||||
break;
|
||||
|
||||
case EV_SW:
|
||||
|
||||
if (code > SW_MAX || !test_bit(code, dev->swbit) || !!test_bit(code, dev->sw) == value)
|
||||
return;
|
||||
|
||||
change_bit(code, dev->sw);
|
||||
|
||||
break;
|
||||
|
||||
case EV_ABS:
|
||||
|
||||
if (code > ABS_MAX || !test_bit(code, dev->absbit))
|
||||
|
@ -402,6 +411,7 @@ static void input_call_hotplug(char *verb, struct input_dev *dev)
|
|||
SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED);
|
||||
SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND);
|
||||
SPRINTF_BIT_A2(ffbit, "FF=", FF_MAX, EV_FF);
|
||||
SPRINTF_BIT_A2(swbit, "SW=", SW_MAX, EV_SW);
|
||||
|
||||
envp[i++] = NULL;
|
||||
|
||||
|
@ -490,6 +500,7 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
|
|||
SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
|
||||
SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
|
||||
SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF);
|
||||
SPRINTF_BIT_B2(swbit, "SW=", SW_MAX, EV_SW);
|
||||
|
||||
len += sprintf(buf + len, "\n");
|
||||
|
||||
|
|
|
@ -249,9 +249,8 @@ static void corgikbd_hinge_timer(unsigned long data)
|
|||
if (hinge_count >= HINGE_STABLE_COUNT) {
|
||||
spin_lock_irqsave(&corgikbd_data->lock, flags);
|
||||
|
||||
input_report_key(&corgikbd_data->input, corgikbd_data->keycode[125], (sharpsl_hinge_state == 0x00));
|
||||
input_report_key(&corgikbd_data->input, corgikbd_data->keycode[126], (sharpsl_hinge_state == 0x08));
|
||||
input_report_key(&corgikbd_data->input, corgikbd_data->keycode[127], (sharpsl_hinge_state == 0x0c));
|
||||
input_report_switch(&corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
|
||||
input_report_switch(&corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
|
||||
input_sync(&corgikbd_data->input);
|
||||
|
||||
spin_unlock_irqrestore(&corgikbd_data->lock, flags);
|
||||
|
@ -321,7 +320,7 @@ static int __init corgikbd_probe(struct device *dev)
|
|||
corgikbd->input.id.vendor = 0x0001;
|
||||
corgikbd->input.id.product = 0x0001;
|
||||
corgikbd->input.id.version = 0x0100;
|
||||
corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR);
|
||||
corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
|
||||
corgikbd->input.keycode = corgikbd->keycode;
|
||||
corgikbd->input.keycodesize = sizeof(unsigned char);
|
||||
corgikbd->input.keycodemax = ARRAY_SIZE(corgikbd_keycode);
|
||||
|
@ -330,6 +329,8 @@ static int __init corgikbd_probe(struct device *dev)
|
|||
for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
|
||||
set_bit(corgikbd->keycode[i], corgikbd->input.keybit);
|
||||
clear_bit(0, corgikbd->input.keybit);
|
||||
set_bit(SW_0, corgikbd->input.swbit);
|
||||
set_bit(SW_1, corgikbd->input.swbit);
|
||||
|
||||
input_register_device(&corgikbd->input);
|
||||
mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL);
|
||||
|
|
|
@ -66,6 +66,7 @@ struct input_absinfo {
|
|||
#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global keystate */
|
||||
#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
|
||||
#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */
|
||||
#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
|
||||
|
||||
#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */
|
||||
#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo) /* get abs value/limits */
|
||||
|
@ -86,6 +87,7 @@ struct input_absinfo {
|
|||
#define EV_REL 0x02
|
||||
#define EV_ABS 0x03
|
||||
#define EV_MSC 0x04
|
||||
#define EV_SW 0x05
|
||||
#define EV_LED 0x11
|
||||
#define EV_SND 0x12
|
||||
#define EV_REP 0x14
|
||||
|
@ -550,6 +552,20 @@ struct input_absinfo {
|
|||
#define ABS_MISC 0x28
|
||||
#define ABS_MAX 0x3f
|
||||
|
||||
/*
|
||||
* Switch events
|
||||
*/
|
||||
|
||||
#define SW_0 0x00
|
||||
#define SW_1 0x01
|
||||
#define SW_2 0x02
|
||||
#define SW_3 0x03
|
||||
#define SW_4 0x04
|
||||
#define SW_5 0x05
|
||||
#define SW_6 0x06
|
||||
#define SW_7 0x07
|
||||
#define SW_MAX 0x0f
|
||||
|
||||
/*
|
||||
* Misc events
|
||||
*/
|
||||
|
@ -824,6 +840,7 @@ struct input_dev {
|
|||
unsigned long ledbit[NBITS(LED_MAX)];
|
||||
unsigned long sndbit[NBITS(SND_MAX)];
|
||||
unsigned long ffbit[NBITS(FF_MAX)];
|
||||
unsigned long swbit[NBITS(SW_MAX)];
|
||||
int ff_effects_max;
|
||||
|
||||
unsigned int keycodemax;
|
||||
|
@ -844,6 +861,7 @@ struct input_dev {
|
|||
unsigned long key[NBITS(KEY_MAX)];
|
||||
unsigned long led[NBITS(LED_MAX)];
|
||||
unsigned long snd[NBITS(SND_MAX)];
|
||||
unsigned long sw[NBITS(SW_MAX)];
|
||||
|
||||
int absmax[ABS_MAX + 1];
|
||||
int absmin[ABS_MAX + 1];
|
||||
|
@ -886,6 +904,7 @@ struct input_dev {
|
|||
#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200
|
||||
#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400
|
||||
#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800
|
||||
#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
|
||||
|
||||
#define INPUT_DEVICE_ID_MATCH_DEVICE\
|
||||
(INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
|
||||
|
@ -906,6 +925,7 @@ struct input_device_id {
|
|||
unsigned long ledbit[NBITS(LED_MAX)];
|
||||
unsigned long sndbit[NBITS(SND_MAX)];
|
||||
unsigned long ffbit[NBITS(FF_MAX)];
|
||||
unsigned long swbit[NBITS(SW_MAX)];
|
||||
|
||||
unsigned long driver_info;
|
||||
};
|
||||
|
@ -998,6 +1018,11 @@ static inline void input_report_ff_status(struct input_dev *dev, unsigned int co
|
|||
input_event(dev, EV_FF_STATUS, code, value);
|
||||
}
|
||||
|
||||
static inline void input_report_switch(struct input_dev *dev, unsigned int code, int value)
|
||||
{
|
||||
input_event(dev, EV_SW, code, !!value);
|
||||
}
|
||||
|
||||
static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
|
||||
{
|
||||
dev->regs = regs;
|
||||
|
|
Loading…
Reference in a new issue