mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 07:04:24 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (48 commits) Input: add switch for dock events Input: add microphone insert switch definition Input: i8042 - add Arima-Rioworks HDAMB board to noloop list Input: sgi_btns - add support for SGI Indy volume buttons Input: add option to disable HP SDC driver Input: serio - trivial documentation fix Input: add new serio driver for Xilinx XPS PS2 IP Input: add driver for Tabletkiosk Sahara TouchIT-213 touchscreen Input: new driver for SGI O2 volume buttons Input: yealink - reliably kill urbs Input: q40kbd - make q40kbd_lock static Input: gtco - eliminate early return Input: i8042 - add Dritek quirk for Acer Aspire 5720 Input: usbtouchscreen - ignore eGalax screens supporting HID protocol Input: i8042 - add Medion NAM 2070 to noloop blacklist Input: i8042 - add Gericom Bellagio to nomux blacklist Input: i8042 - add Acer Aspire 1360 to nomux blacklist Input: hp_sdc_mlc.c - make a struct static Input: hil_mlc.c - make code static Input: wistron - generate normal key event if bluetooth or wifi not present ...
This commit is contained in:
commit
519f0141f1
100 changed files with 2282 additions and 549 deletions
|
@ -1,5 +1,3 @@
|
|||
$Id: gameport-programming.txt,v 1.3 2001/04/24 13:51:37 vojtech Exp $
|
||||
|
||||
Programming gameport drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
Linux Input drivers v1.0
|
||||
(c) 1999-2001 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
Sponsored by SuSE
|
||||
$Id: input.txt,v 1.8 2002/05/29 03:15:01 bradleym Exp $
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
7 Aug 1998
|
||||
|
||||
$Id: joystick-api.txt,v 1.2 2001/05/08 21:21:23 vojtech Exp $
|
||||
|
||||
1. Initialization
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
(c) 1998-2000 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
(c) 1998 Andree Borrmann <a.borrmann@tu-bs.de>
|
||||
Sponsored by SuSE
|
||||
$Id: joystick-parport.txt,v 1.6 2001/09/25 09:31:32 vojtech Exp $
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
Linux Joystick driver v2.0.0
|
||||
(c) 1996-2000 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
Sponsored by SuSE
|
||||
$Id: joystick.txt,v 1.12 2002/03/03 12:13:07 jdeneux Exp $
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
|
|
|
@ -1988,6 +1988,12 @@ M: mikulas@artax.karlin.mff.cuni.cz
|
|||
W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
|
||||
S: Maintained
|
||||
|
||||
HTCPEN TOUCHSCREEN DRIVER
|
||||
P: Pau Oliva Fora
|
||||
M: pof@eslack.org
|
||||
L: linux-input@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
HUGETLB FILESYSTEM
|
||||
P: William Irwin
|
||||
M: wli@holomorphy.com
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
|
||||
extern void ctrl_alt_del(void);
|
||||
|
||||
#define to_handle_h(n) container_of(n, struct input_handle, h_node)
|
||||
|
||||
/*
|
||||
* Exported functions/variables
|
||||
*/
|
||||
|
|
|
@ -581,6 +581,8 @@ static int __init hdaps_init(void)
|
|||
/* initialize the input class */
|
||||
idev = hdaps_idev->input;
|
||||
idev->name = "hdaps";
|
||||
idev->phys = "isa1600/input0";
|
||||
idev->id.bustype = BUS_ISA;
|
||||
idev->dev.parent = &pdev->dev;
|
||||
idev->evbit[0] = BIT_MASK(EV_ABS);
|
||||
input_set_abs_params(idev, ABS_X,
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: evbug.c,v 1.10 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
@ -41,7 +39,7 @@ MODULE_LICENSE("GPL");
|
|||
static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
|
||||
handle->dev->phys, type, code, value);
|
||||
handle->dev->dev.bus_id, type, code, value);
|
||||
}
|
||||
|
||||
static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
|
||||
|
@ -66,7 +64,10 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
|
|||
if (error)
|
||||
goto err_unregister_handle;
|
||||
|
||||
printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys);
|
||||
printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n",
|
||||
dev->dev.bus_id,
|
||||
dev->name ?: "unknown",
|
||||
dev->phys ?: "unknown");
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -79,7 +80,8 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
|
|||
|
||||
static void evbug_disconnect(struct input_handle *handle)
|
||||
{
|
||||
printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys);
|
||||
printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n",
|
||||
handle->dev->dev.bus_id);
|
||||
|
||||
input_close_device(handle);
|
||||
input_unregister_handle(handle);
|
||||
|
|
|
@ -300,6 +300,35 @@ struct input_event_compat {
|
|||
__s32 value;
|
||||
};
|
||||
|
||||
struct ff_periodic_effect_compat {
|
||||
__u16 waveform;
|
||||
__u16 period;
|
||||
__s16 magnitude;
|
||||
__s16 offset;
|
||||
__u16 phase;
|
||||
|
||||
struct ff_envelope envelope;
|
||||
|
||||
__u32 custom_len;
|
||||
compat_uptr_t custom_data;
|
||||
};
|
||||
|
||||
struct ff_effect_compat {
|
||||
__u16 type;
|
||||
__s16 id;
|
||||
__u16 direction;
|
||||
struct ff_trigger trigger;
|
||||
struct ff_replay replay;
|
||||
|
||||
union {
|
||||
struct ff_constant_effect constant;
|
||||
struct ff_ramp_effect ramp;
|
||||
struct ff_periodic_effect_compat periodic;
|
||||
struct ff_condition_effect condition[2]; /* One for each axis */
|
||||
struct ff_rumble_effect rumble;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* Note to the author of this code: did it ever occur to
|
||||
you why the ifdefs are needed? Think about it again. -AK */
|
||||
#ifdef CONFIG_X86_64
|
||||
|
@ -368,6 +397,42 @@ static int evdev_event_to_user(char __user *buffer,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
if (COMPAT_TEST) {
|
||||
struct ff_effect_compat *compat_effect;
|
||||
|
||||
if (size != sizeof(struct ff_effect_compat))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* It so happens that the pointer which needs to be changed
|
||||
* is the last field in the structure, so we can copy the
|
||||
* whole thing and replace just the pointer.
|
||||
*/
|
||||
|
||||
compat_effect = (struct ff_effect_compat *)effect;
|
||||
|
||||
if (copy_from_user(compat_effect, buffer,
|
||||
sizeof(struct ff_effect_compat)))
|
||||
return -EFAULT;
|
||||
|
||||
if (compat_effect->type == FF_PERIODIC &&
|
||||
compat_effect->u.periodic.waveform == FF_CUSTOM)
|
||||
effect->u.periodic.custom_data =
|
||||
compat_ptr(compat_effect->u.periodic.custom_data);
|
||||
} else {
|
||||
if (size != sizeof(struct ff_effect))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline size_t evdev_event_size(void)
|
||||
|
@ -393,6 +458,18 @@ static int evdev_event_to_user(char __user *buffer,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
|
||||
struct ff_effect *effect)
|
||||
{
|
||||
if (size != sizeof(struct ff_effect))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
static ssize_t evdev_write(struct file *file, const char __user *buffer,
|
||||
|
@ -633,17 +710,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
|
|||
|
||||
return input_set_keycode(dev, t, v);
|
||||
|
||||
case EVIOCSFF:
|
||||
if (copy_from_user(&effect, p, sizeof(effect)))
|
||||
return -EFAULT;
|
||||
|
||||
error = input_ff_upload(dev, &effect, file);
|
||||
|
||||
if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
|
||||
return -EFAULT;
|
||||
|
||||
return error;
|
||||
|
||||
case EVIOCRMFF:
|
||||
return input_ff_erase(dev, (int)(unsigned long) p, file);
|
||||
|
||||
|
@ -733,6 +799,19 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
|
|||
|
||||
if (_IOC_DIR(cmd) == _IOC_WRITE) {
|
||||
|
||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) {
|
||||
|
||||
if (evdev_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect))
|
||||
return -EFAULT;
|
||||
|
||||
error = input_ff_upload(dev, &effect, file);
|
||||
|
||||
if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
|
||||
return -EFAULT;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
|
||||
|
||||
t = _IOC_NR(cmd) & ABS_MAX;
|
||||
|
|
|
@ -247,9 +247,9 @@ static void ml_combine_effects(struct ff_effect *effect,
|
|||
* in s8, this should be changed to something more generic
|
||||
*/
|
||||
effect->u.ramp.start_level =
|
||||
max(min(effect->u.ramp.start_level + x, 0x7f), -0x80);
|
||||
clamp_val(effect->u.ramp.start_level + x, -0x80, 0x7f);
|
||||
effect->u.ramp.end_level =
|
||||
max(min(effect->u.ramp.end_level + y, 0x7f), -0x80);
|
||||
clamp_val(effect->u.ramp.end_level + y, -0x80, 0x7f);
|
||||
break;
|
||||
|
||||
case FF_RUMBLE:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: emu10k1-gp.c,v 1.8 2002/01/22 20:40:46 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ EXPORT_SYMBOL(__gameport_register_driver);
|
|||
EXPORT_SYMBOL(gameport_unregister_driver);
|
||||
EXPORT_SYMBOL(gameport_open);
|
||||
EXPORT_SYMBOL(gameport_close);
|
||||
EXPORT_SYMBOL(gameport_rescan);
|
||||
EXPORT_SYMBOL(gameport_set_phys);
|
||||
EXPORT_SYMBOL(gameport_start_polling);
|
||||
EXPORT_SYMBOL(gameport_stop_polling);
|
||||
|
@ -230,8 +229,6 @@ static void gameport_find_driver(struct gameport *gameport)
|
|||
*/
|
||||
|
||||
enum gameport_event_type {
|
||||
GAMEPORT_RESCAN,
|
||||
GAMEPORT_RECONNECT,
|
||||
GAMEPORT_REGISTER_PORT,
|
||||
GAMEPORT_REGISTER_DRIVER,
|
||||
};
|
||||
|
@ -365,15 +362,6 @@ static void gameport_handle_event(void)
|
|||
gameport_add_port(event->object);
|
||||
break;
|
||||
|
||||
case GAMEPORT_RECONNECT:
|
||||
gameport_reconnect_port(event->object);
|
||||
break;
|
||||
|
||||
case GAMEPORT_RESCAN:
|
||||
gameport_disconnect_port(event->object);
|
||||
gameport_find_driver(event->object);
|
||||
break;
|
||||
|
||||
case GAMEPORT_REGISTER_DRIVER:
|
||||
gameport_add_driver(event->object);
|
||||
break;
|
||||
|
@ -651,16 +639,6 @@ static void gameport_disconnect_port(struct gameport *gameport)
|
|||
device_release_driver(&gameport->dev);
|
||||
}
|
||||
|
||||
void gameport_rescan(struct gameport *gameport)
|
||||
{
|
||||
gameport_queue_event(gameport, NULL, GAMEPORT_RESCAN);
|
||||
}
|
||||
|
||||
void gameport_reconnect(struct gameport *gameport)
|
||||
{
|
||||
gameport_queue_event(gameport, NULL, GAMEPORT_RECONNECT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Submits register request to kgameportd for subsequent execution.
|
||||
* Note that port registration is always asynchronous.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: lightning.c,v 1.20 2002/01/22 20:41:31 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1998-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: ns558.c,v 1.43 2002/01/24 19:23:21 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
* Copyright (c) 1999 Brian Gerst
|
||||
*/
|
||||
|
|
|
@ -242,7 +242,7 @@ static void input_handle_event(struct input_dev *dev,
|
|||
break;
|
||||
}
|
||||
|
||||
if (type != EV_SYN)
|
||||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
|
||||
dev->sync = 0;
|
||||
|
||||
if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: a3d.c,v 1.21 2002/01/22 20:11:50 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1998-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: amijoy.c,v 1.13 2002/01/22 20:26:32 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1998-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: cobra.c,v 1.19 2002/01/22 20:26:52 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: db9.c,v 1.13 2002/04/07 20:13:37 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: gf2k.c,v 1.19 2002/01/22 20:27:43 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1998-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: grip.c,v 1.21 2002/01/22 20:27:57 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1998-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: grip_mp.c,v 1.9 2002/07/20 19:28:45 bonnland Exp $
|
||||
*
|
||||
* Driver for the Gravis Grip Multiport, a gamepad "hub" that
|
||||
* connects up to four 9-pin digital gamepads/joysticks.
|
||||
* Driver tested on SMP and UP kernel versions 2.4.18-4 and 2.4.18-5.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: guillemot.c,v 1.10 2002/01/22 20:28:12 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
* Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: iforce-main.c,v 1.19 2002/07/07 10:22:50 jdeneux Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
* Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: iforce-packets.c,v 1.16 2002/07/07 10:22:50 jdeneux Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
* Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
* Copyright (c) 2001, 2007 Johann Deneux <johann.deneux@gmail.com>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: iforce-usb.c,v 1.16 2002/06/09 11:08:04 jdeneux Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
* Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
|
||||
*
|
||||
|
@ -89,10 +87,10 @@ static void iforce_usb_irq(struct urb *urb)
|
|||
case -ESHUTDOWN:
|
||||
/* this urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d",
|
||||
__FUNCTION__, urb->status);
|
||||
__func__, urb->status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - urb has status of: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - urb has status of: %d", __func__, urb->status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -103,7 +101,7 @@ static void iforce_usb_irq(struct urb *urb)
|
|||
status = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (status)
|
||||
err ("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, status);
|
||||
__func__, status);
|
||||
}
|
||||
|
||||
static void iforce_usb_out(struct urb *urb)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: iforce.h,v 1.13 2002/07/07 10:22:50 jdeneux Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
* Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: interact.c,v 1.16 2002/01/22 20:28:25 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: joydump.c,v 1.1 2002/01/23 06:56:16 jsimmons Exp $
|
||||
*
|
||||
* Copyright (c) 1996-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: magellan.c,v 1.16 2002/01/22 20:28:39 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: spaceball.c,v 1.17 2002/01/22 20:29:03 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: spaceorb.c,v 1.15 2002/01/22 20:29:19 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: stinger.c,v 1.10 2002/01/22 20:29:31 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik
|
||||
* Copyright (c) 2000 Mark Fletcher
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: tmdc.c,v 1.31 2002/01/22 20:29:52 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1998-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: turbografx.c,v 1.14 2002/01/22 20:30:39 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1998-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/*
|
||||
* $Id: twidjoy.c,v 1.5 2002/01/22 20:31:53 vojtech Exp $
|
||||
*
|
||||
* derived from CVS-ID "stinger.c,v 1.5 2001/05/29 12:57:18 vojtech Exp"
|
||||
*
|
||||
* Copyright (c) 2001 Arndt Schoenewald
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik
|
||||
* Copyright (c) 2000 Mark Fletcher
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: warrior.c,v 1.14 2002/01/22 20:32:10 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -418,11 +418,11 @@ static void xpad_irq_in(struct urb *urb)
|
|||
case -ESHUTDOWN:
|
||||
/* this urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d",
|
||||
__FUNCTION__, status);
|
||||
__func__, status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d",
|
||||
__FUNCTION__, status);
|
||||
__func__, status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -441,7 +441,7 @@ static void xpad_irq_in(struct urb *urb)
|
|||
retval = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
err ("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
static void xpad_bulk_out(struct urb *urb)
|
||||
|
@ -477,11 +477,11 @@ static void xpad_irq_out(struct urb *urb)
|
|||
case -ESHUTDOWN:
|
||||
/* this urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d",
|
||||
__FUNCTION__, status);
|
||||
__func__, status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d",
|
||||
__FUNCTION__, status);
|
||||
__func__, status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ static void xpad_irq_out(struct urb *urb)
|
|||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
err("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: amikbd.c,v 1.13 2002/02/01 16:02:24 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -68,7 +68,7 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and
|
|||
* are loadable via an userland utility.
|
||||
*/
|
||||
|
||||
static unsigned char atkbd_set2_keycode[512] = {
|
||||
static const unsigned short atkbd_set2_keycode[512] = {
|
||||
|
||||
#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
|
||||
|
||||
|
@ -99,7 +99,7 @@ static unsigned char atkbd_set2_keycode[512] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static unsigned char atkbd_set3_keycode[512] = {
|
||||
static const unsigned short atkbd_set3_keycode[512] = {
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60,
|
||||
131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62,
|
||||
|
@ -115,7 +115,7 @@ static unsigned char atkbd_set3_keycode[512] = {
|
|||
148,149,147,140
|
||||
};
|
||||
|
||||
static unsigned char atkbd_unxlate_table[128] = {
|
||||
static const unsigned short atkbd_unxlate_table[128] = {
|
||||
0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
|
||||
21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
|
||||
35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
|
||||
|
@ -161,7 +161,7 @@ static unsigned char atkbd_unxlate_table[128] = {
|
|||
#define ATKBD_SCR_LEFT 249
|
||||
#define ATKBD_SCR_RIGHT 248
|
||||
|
||||
#define ATKBD_SPECIAL 248
|
||||
#define ATKBD_SPECIAL ATKBD_SCR_RIGHT
|
||||
|
||||
#define ATKBD_LED_EVENT_BIT 0
|
||||
#define ATKBD_REP_EVENT_BIT 1
|
||||
|
@ -173,7 +173,7 @@ static unsigned char atkbd_unxlate_table[128] = {
|
|||
#define ATKBD_XL_HANGEUL 0x10
|
||||
#define ATKBD_XL_HANJA 0x20
|
||||
|
||||
static struct {
|
||||
static const struct {
|
||||
unsigned char keycode;
|
||||
unsigned char set2;
|
||||
} atkbd_scroll_keys[] = {
|
||||
|
@ -200,7 +200,7 @@ struct atkbd {
|
|||
char phys[32];
|
||||
|
||||
unsigned short id;
|
||||
unsigned char keycode[512];
|
||||
unsigned short keycode[512];
|
||||
DECLARE_BITMAP(force_release_mask, 512);
|
||||
unsigned char set;
|
||||
unsigned char translated;
|
||||
|
@ -357,7 +357,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
|
|||
unsigned int code = data;
|
||||
int scroll = 0, hscroll = 0, click = -1;
|
||||
int value;
|
||||
unsigned char keycode;
|
||||
unsigned short keycode;
|
||||
|
||||
#ifdef ATKBD_DEBUG
|
||||
printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
|
||||
|
@ -850,6 +850,23 @@ static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)
|
|||
atkbd->force_release_mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform fixup for HP system that doesn't generate release
|
||||
* for its video switch
|
||||
*/
|
||||
static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
|
||||
{
|
||||
const unsigned int forced_release_keys[] = {
|
||||
0x94,
|
||||
};
|
||||
int i;
|
||||
|
||||
if (atkbd->set == 2)
|
||||
for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
|
||||
__set_bit(forced_release_keys[i],
|
||||
atkbd->force_release_mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* atkbd_set_keycode_table() initializes keyboard's keycode table
|
||||
* according to the selected scancode set
|
||||
|
@ -961,16 +978,16 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
|
|||
input_dev->evbit[0] |= BIT_MASK(EV_REL);
|
||||
input_dev->relbit[0] = BIT_MASK(REL_WHEEL) |
|
||||
BIT_MASK(REL_HWHEEL);
|
||||
set_bit(BTN_MIDDLE, input_dev->keybit);
|
||||
__set_bit(BTN_MIDDLE, input_dev->keybit);
|
||||
}
|
||||
|
||||
input_dev->keycode = atkbd->keycode;
|
||||
input_dev->keycodesize = sizeof(unsigned char);
|
||||
input_dev->keycodesize = sizeof(unsigned short);
|
||||
input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
|
||||
|
||||
for (i = 0; i < 512; i++)
|
||||
if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
|
||||
set_bit(atkbd->keycode[i], input_dev->keybit);
|
||||
__set_bit(atkbd->keycode[i], input_dev->keybit);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1452,6 +1469,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
|
|||
.callback = atkbd_setup_fixup,
|
||||
.driver_data = atkbd_latitude_keymap_fixup,
|
||||
},
|
||||
{
|
||||
.ident = "HP 2133",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
|
||||
},
|
||||
.callback = atkbd_setup_fixup,
|
||||
.driver_data = atkbd_hp_keymap_fixup,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -26,23 +26,54 @@
|
|||
|
||||
#include <asm/gpio.h>
|
||||
|
||||
struct gpio_button_data {
|
||||
struct gpio_keys_button *button;
|
||||
struct input_dev *input;
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
struct gpio_keys_drvdata {
|
||||
struct input_dev *input;
|
||||
struct gpio_button_data data[0];
|
||||
};
|
||||
|
||||
static void gpio_keys_report_event(struct gpio_keys_button *button,
|
||||
struct input_dev *input)
|
||||
{
|
||||
unsigned int type = button->type ?: EV_KEY;
|
||||
int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
|
||||
|
||||
input_event(input, type, button->code, !!state);
|
||||
input_sync(input);
|
||||
}
|
||||
|
||||
static void gpio_check_button(unsigned long _data)
|
||||
{
|
||||
struct gpio_button_data *data = (struct gpio_button_data *)_data;
|
||||
|
||||
gpio_keys_report_event(data->button, data->input);
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
|
||||
{
|
||||
int i;
|
||||
struct platform_device *pdev = dev_id;
|
||||
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct input_dev *input = platform_get_drvdata(pdev);
|
||||
struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pdata->nbuttons; i++) {
|
||||
struct gpio_keys_button *button = &pdata->buttons[i];
|
||||
int gpio = button->gpio;
|
||||
|
||||
if (irq == gpio_to_irq(gpio)) {
|
||||
unsigned int type = button->type ?: EV_KEY;
|
||||
int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low;
|
||||
if (irq == gpio_to_irq(button->gpio)) {
|
||||
struct gpio_button_data *bdata = &ddata->data[i];
|
||||
|
||||
if (button->debounce_interval)
|
||||
mod_timer(&bdata->timer,
|
||||
jiffies +
|
||||
msecs_to_jiffies(button->debounce_interval));
|
||||
else
|
||||
gpio_keys_report_event(button, bdata->input);
|
||||
|
||||
input_event(input, type, button->code, !!state);
|
||||
input_sync(input);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
}
|
||||
|
@ -53,17 +84,21 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
|
|||
static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct gpio_keys_drvdata *ddata;
|
||||
struct input_dev *input;
|
||||
int i, error;
|
||||
int wakeup = 0;
|
||||
|
||||
ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
|
||||
pdata->nbuttons * sizeof(struct gpio_button_data),
|
||||
GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
if (!ddata || !input) {
|
||||
error = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, input);
|
||||
|
||||
input->evbit[0] = BIT_MASK(EV_KEY);
|
||||
platform_set_drvdata(pdev, ddata);
|
||||
|
||||
input->name = pdev->name;
|
||||
input->phys = "gpio-keys/input0";
|
||||
|
@ -74,16 +109,23 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
|||
input->id.product = 0x0001;
|
||||
input->id.version = 0x0100;
|
||||
|
||||
ddata->input = input;
|
||||
|
||||
for (i = 0; i < pdata->nbuttons; i++) {
|
||||
struct gpio_keys_button *button = &pdata->buttons[i];
|
||||
struct gpio_button_data *bdata = &ddata->data[i];
|
||||
int irq;
|
||||
unsigned int type = button->type ?: EV_KEY;
|
||||
|
||||
bdata->input = input;
|
||||
setup_timer(&bdata->timer,
|
||||
gpio_check_button, (unsigned long)bdata);
|
||||
|
||||
error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
|
||||
if (error < 0) {
|
||||
pr_err("gpio-keys: failed to request GPIO %d,"
|
||||
" error %d\n", button->gpio, error);
|
||||
goto fail;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
error = gpio_direction_input(button->gpio);
|
||||
|
@ -92,7 +134,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
|||
" direction for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
gpio_free(button->gpio);
|
||||
goto fail;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
irq = gpio_to_irq(button->gpio);
|
||||
|
@ -102,7 +144,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
|||
" for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
gpio_free(button->gpio);
|
||||
goto fail;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
error = request_irq(irq, gpio_keys_isr,
|
||||
|
@ -114,7 +156,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
|||
pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
|
||||
irq, error);
|
||||
gpio_free(button->gpio);
|
||||
goto fail;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
if (button->wakeup)
|
||||
|
@ -127,21 +169,25 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
|||
if (error) {
|
||||
pr_err("gpio-keys: Unable to register input device, "
|
||||
"error: %d\n", error);
|
||||
goto fail;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
device_init_wakeup(&pdev->dev, wakeup);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fail2:
|
||||
while (--i >= 0) {
|
||||
free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
|
||||
if (pdata->buttons[i].debounce_interval)
|
||||
del_timer_sync(&ddata->data[i].timer);
|
||||
gpio_free(pdata->buttons[i].gpio);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
fail1:
|
||||
input_free_device(input);
|
||||
kfree(ddata);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -149,7 +195,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
|||
static int __devexit gpio_keys_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct input_dev *input = platform_get_drvdata(pdev);
|
||||
struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
struct input_dev *input = ddata->input;
|
||||
int i;
|
||||
|
||||
device_init_wakeup(&pdev->dev, 0);
|
||||
|
@ -157,6 +204,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
|
|||
for (i = 0; i < pdata->nbuttons; i++) {
|
||||
int irq = gpio_to_irq(pdata->buttons[i].gpio);
|
||||
free_irq(irq, pdev);
|
||||
if (pdata->buttons[i].debounce_interval)
|
||||
del_timer_sync(&ddata->data[i].timer);
|
||||
gpio_free(pdata->buttons[i].gpio);
|
||||
}
|
||||
|
||||
|
|
|
@ -538,11 +538,11 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
|
|||
switch (code) {
|
||||
case SND_CLICK:
|
||||
if (value == 0) {
|
||||
DBG ("%s: Deactivating key clicks\n", __FUNCTION__);
|
||||
DBG ("%s: Deactivating key clicks\n", __func__);
|
||||
lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
|
||||
lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
|
||||
} else {
|
||||
DBG ("%s: Activating key clicks\n", __FUNCTION__);
|
||||
DBG ("%s: Activating key clicks\n", __func__);
|
||||
lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
|
||||
lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
|
||||
lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
|
||||
|
@ -560,7 +560,7 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
|
|||
|
||||
default:
|
||||
printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n",
|
||||
__FUNCTION__, type, code, value);
|
||||
__func__, type, code, value);
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
|
|
@ -105,6 +105,8 @@ struct pxa27x_keypad {
|
|||
struct input_dev *input_dev;
|
||||
void __iomem *mmio_base;
|
||||
|
||||
int irq;
|
||||
|
||||
/* matrix key code map */
|
||||
unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
|
||||
|
||||
|
@ -392,6 +394,10 @@ static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t stat
|
|||
struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable(keypad->clk);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
enable_irq_wake(keypad->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -400,6 +406,9 @@ static int pxa27x_keypad_resume(struct platform_device *pdev)
|
|||
struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
|
||||
struct input_dev *input_dev = keypad->input_dev;
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
disable_irq_wake(keypad->irq);
|
||||
|
||||
mutex_lock(&input_dev->mutex);
|
||||
|
||||
if (input_dev->users) {
|
||||
|
@ -509,6 +518,8 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
|
|||
goto failed_free_dev;
|
||||
}
|
||||
|
||||
keypad->irq = irq;
|
||||
|
||||
/* Register the input device */
|
||||
error = input_register_device(input_dev);
|
||||
if (error) {
|
||||
|
@ -516,6 +527,8 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
|
|||
goto failed_free_irq;
|
||||
}
|
||||
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
failed_free_irq:
|
||||
|
@ -539,7 +552,7 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev)
|
|||
struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
|
||||
struct resource *res;
|
||||
|
||||
free_irq(platform_get_irq(pdev, 0), pdev);
|
||||
free_irq(keypad->irq, pdev);
|
||||
|
||||
clk_disable(keypad->clk);
|
||||
clk_put(keypad->clk);
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: sunkbd.c,v 1.14 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: xtkbd.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -189,6 +189,16 @@ config INPUT_UINPUT
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called uinput.
|
||||
|
||||
config INPUT_SGI_BTNS
|
||||
tristate "SGI Indy/O2 volume button interface"
|
||||
depends on SGI_IP22 || SGI_IP32
|
||||
select INPUT_POLLDEV
|
||||
help
|
||||
Say Y here if you want to support SGI Indy/O2 volume button interface.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called sgi_btns.
|
||||
|
||||
config HP_SDC_RTC
|
||||
tristate "HP SDC Real Time Clock"
|
||||
depends on GSC || HP300
|
||||
|
|
|
@ -19,3 +19,4 @@ obj-$(CONFIG_INPUT_YEALINK) += yealink.o
|
|||
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
|
||||
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
|
||||
obj-$(CONFIG_INPUT_APANEL) += apanel.o
|
||||
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
|
||||
|
|
|
@ -330,7 +330,7 @@ static int ati_remote_open(struct input_dev *inputdev)
|
|||
ati_remote->irq_urb->dev = ati_remote->udev;
|
||||
if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) {
|
||||
dev_err(&ati_remote->interface->dev,
|
||||
"%s: usb_submit_urb failed!\n", __FUNCTION__);
|
||||
"%s: usb_submit_urb failed!\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,7 @@ static void ati_remote_irq_out(struct urb *urb)
|
|||
|
||||
if (urb->status) {
|
||||
dev_dbg(&ati_remote->interface->dev, "%s: status %d\n",
|
||||
__FUNCTION__, urb->status);
|
||||
__func__, urb->status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -601,17 +601,17 @@ static void ati_remote_irq_in(struct urb *urb)
|
|||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n",
|
||||
__FUNCTION__);
|
||||
__func__);
|
||||
return;
|
||||
default: /* error */
|
||||
dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n",
|
||||
__FUNCTION__, urb->status);
|
||||
__func__, urb->status);
|
||||
}
|
||||
|
||||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -734,7 +734,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
|
|||
int err = -ENOMEM;
|
||||
|
||||
if (iface_host->desc.bNumEndpoints != 2) {
|
||||
err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__);
|
||||
err("%s: Unexpected desc.bNumEndpoints\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -742,11 +742,11 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
|
|||
endpoint_out = &iface_host->endpoint[1].desc;
|
||||
|
||||
if (!usb_endpoint_is_int_in(endpoint_in)) {
|
||||
err("%s: Unexpected endpoint_in\n", __FUNCTION__);
|
||||
err("%s: Unexpected endpoint_in\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
|
||||
err("%s: endpoint_in message size==0? \n", __FUNCTION__);
|
||||
err("%s: endpoint_in message size==0? \n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)
|
|||
ati_remote = usb_get_intfdata(interface);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
if (!ati_remote) {
|
||||
warn("%s - null device?\n", __FUNCTION__);
|
||||
warn("%s - null device?\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,14 +137,14 @@ static int ati_remote2_open(struct input_dev *idev)
|
|||
r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
|
||||
if (r) {
|
||||
dev_err(&ar2->intf[0]->dev,
|
||||
"%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
|
||||
"%s: usb_submit_urb() = %d\n", __func__, r);
|
||||
return r;
|
||||
}
|
||||
r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
|
||||
if (r) {
|
||||
usb_kill_urb(ar2->urb[0]);
|
||||
dev_err(&ar2->intf[1]->dev,
|
||||
"%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
|
||||
"%s: usb_submit_urb() = %d\n", __func__, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -294,17 +294,17 @@ static void ati_remote2_complete_mouse(struct urb *urb)
|
|||
case -ECONNRESET:
|
||||
case -ESHUTDOWN:
|
||||
dev_dbg(&ar2->intf[0]->dev,
|
||||
"%s(): urb status = %d\n", __FUNCTION__, urb->status);
|
||||
"%s(): urb status = %d\n", __func__, urb->status);
|
||||
return;
|
||||
default:
|
||||
dev_err(&ar2->intf[0]->dev,
|
||||
"%s(): urb status = %d\n", __FUNCTION__, urb->status);
|
||||
"%s(): urb status = %d\n", __func__, urb->status);
|
||||
}
|
||||
|
||||
r = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (r)
|
||||
dev_err(&ar2->intf[0]->dev,
|
||||
"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
|
||||
"%s(): usb_submit_urb() = %d\n", __func__, r);
|
||||
}
|
||||
|
||||
static void ati_remote2_complete_key(struct urb *urb)
|
||||
|
@ -321,17 +321,17 @@ static void ati_remote2_complete_key(struct urb *urb)
|
|||
case -ECONNRESET:
|
||||
case -ESHUTDOWN:
|
||||
dev_dbg(&ar2->intf[1]->dev,
|
||||
"%s(): urb status = %d\n", __FUNCTION__, urb->status);
|
||||
"%s(): urb status = %d\n", __func__, urb->status);
|
||||
return;
|
||||
default:
|
||||
dev_err(&ar2->intf[1]->dev,
|
||||
"%s(): urb status = %d\n", __FUNCTION__, urb->status);
|
||||
"%s(): urb status = %d\n", __func__, urb->status);
|
||||
}
|
||||
|
||||
r = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (r)
|
||||
dev_err(&ar2->intf[1]->dev,
|
||||
"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
|
||||
"%s(): usb_submit_urb() = %d\n", __func__, r);
|
||||
}
|
||||
|
||||
static int ati_remote2_input_init(struct ati_remote2 *ar2)
|
||||
|
@ -438,7 +438,7 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
|
|||
channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||
if (r) {
|
||||
dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n",
|
||||
__FUNCTION__, r);
|
||||
__func__, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
|
|||
if (dev->data.pos >= dev->data.len) {
|
||||
dev_dbg(&dev->udev->dev,
|
||||
"%s - Error ran out of data. pos: %d, len: %d\n",
|
||||
__FUNCTION__, dev->data.pos, dev->data.len);
|
||||
__func__, dev->data.pos, dev->data.len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
|
|||
remote->data.tester = remote->data.tester >> 6;
|
||||
remote->data.bits_left -= 6;
|
||||
} else {
|
||||
err("%s - Unknown sequence found in system data.\n", __FUNCTION__);
|
||||
err("%s - Unknown sequence found in system data.\n", __func__);
|
||||
remote->stage = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
|
|||
remote->data.tester = remote->data.tester >> 6;
|
||||
remote->data.bits_left -= 6;
|
||||
} else {
|
||||
err("%s - Unknown sequence found in button data.\n", __FUNCTION__);
|
||||
err("%s - Unknown sequence found in button data.\n", __func__);
|
||||
remote->stage = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
|
|||
remote->data.tester = remote->data.tester >> 6;
|
||||
remote->data.bits_left -= 6;
|
||||
} else {
|
||||
err("%s - Error in message, invalid toggle.\n", __FUNCTION__);
|
||||
err("%s - Error in message, invalid toggle.\n", __func__);
|
||||
remote->stage = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
|
|||
|
||||
dev_dbg(&remote->udev->dev,
|
||||
"%s found valid message: system: %d, button: %d, toggle: %d\n",
|
||||
__FUNCTION__, message.system, message.button, message.toggle);
|
||||
__func__, message.system, message.button, message.toggle);
|
||||
|
||||
if (message.toggle != remote->toggle) {
|
||||
keyspan_report_button(remote, message.button, 1);
|
||||
|
@ -341,7 +341,7 @@ static int keyspan_setup(struct usb_device* dev)
|
|||
0x11, 0x40, 0x5601, 0x0, NULL, 0, 0);
|
||||
if (retval) {
|
||||
dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ static int keyspan_setup(struct usb_device* dev)
|
|||
0x44, 0x40, 0x0, 0x0, NULL, 0, 0);
|
||||
if (retval) {
|
||||
dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
@ -357,11 +357,11 @@ static int keyspan_setup(struct usb_device* dev)
|
|||
0x22, 0x40, 0x0, 0x0, NULL, 0, 0);
|
||||
if (retval) {
|
||||
dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__);
|
||||
dev_dbg(&dev->dev, "%s - Setup complete.\n", __func__);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ static void keyspan_irq_recv(struct urb *urb)
|
|||
resubmit:
|
||||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);
|
||||
err ("%s - usb_submit_urb failed with result: %d", __func__, retval);
|
||||
}
|
||||
|
||||
static int keyspan_open(struct input_dev *dev)
|
||||
|
|
|
@ -96,10 +96,10 @@ static void powermate_irq(struct urb *urb)
|
|||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
/* this urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - urb shutting down with status: %d", __func__, urb->status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - nonzero urb status received: %d", __func__, urb->status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ static void powermate_irq(struct urb *urb)
|
|||
retval = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
err ("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
/* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */
|
||||
|
|
178
drivers/input/misc/sgi_btns.c
Normal file
178
drivers/input/misc/sgi_btns.c
Normal file
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* SGI Volume Button interface driver
|
||||
*
|
||||
* Copyright (C) 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
*
|
||||
* 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
|
||||
* (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/input-polldev.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#ifdef CONFIG_SGI_IP22
|
||||
#include <asm/sgi/ioc.h>
|
||||
|
||||
static inline u8 button_status(void)
|
||||
{
|
||||
u8 status;
|
||||
|
||||
status = readb(&sgioc->panel) ^ 0xa0;
|
||||
return ((status & 0x80) >> 6) | ((status & 0x20) >> 5);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SGI_IP32
|
||||
#include <asm/ip32/mace.h>
|
||||
|
||||
static inline u8 button_status(void)
|
||||
{
|
||||
u64 status;
|
||||
|
||||
status = readq(&mace->perif.audio.control);
|
||||
writeq(status & ~(3U << 23), &mace->perif.audio.control);
|
||||
|
||||
return (status >> 23) & 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BUTTONS_POLL_INTERVAL 30 /* msec */
|
||||
#define BUTTONS_COUNT_THRESHOLD 3
|
||||
|
||||
static const unsigned short sgi_map[] = {
|
||||
KEY_VOLUMEDOWN,
|
||||
KEY_VOLUMEUP
|
||||
};
|
||||
|
||||
struct buttons_dev {
|
||||
struct input_polled_dev *poll_dev;
|
||||
unsigned short keymap[ARRAY_SIZE(sgi_map)];
|
||||
int count[ARRAY_SIZE(sgi_map)];
|
||||
};
|
||||
|
||||
static void handle_buttons(struct input_polled_dev *dev)
|
||||
{
|
||||
struct buttons_dev *bdev = dev->private;
|
||||
struct input_dev *input = dev->input;
|
||||
u8 status;
|
||||
int i;
|
||||
|
||||
status = button_status();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) {
|
||||
if (status & (1U << i)) {
|
||||
if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) {
|
||||
input_event(input, EV_MSC, MSC_SCAN, i);
|
||||
input_report_key(input, bdev->keymap[i], 1);
|
||||
input_sync(input);
|
||||
}
|
||||
} else {
|
||||
if (bdev->count[i] >= BUTTONS_COUNT_THRESHOLD) {
|
||||
input_event(input, EV_MSC, MSC_SCAN, i);
|
||||
input_report_key(input, bdev->keymap[i], 0);
|
||||
input_sync(input);
|
||||
}
|
||||
bdev->count[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int __devinit sgi_buttons_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct buttons_dev *bdev;
|
||||
struct input_polled_dev *poll_dev;
|
||||
struct input_dev *input;
|
||||
int error, i;
|
||||
|
||||
bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL);
|
||||
poll_dev = input_allocate_polled_device();
|
||||
if (!bdev || !poll_dev) {
|
||||
error = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
}
|
||||
|
||||
memcpy(bdev->keymap, sgi_map, sizeof(bdev->keymap));
|
||||
|
||||
poll_dev->private = bdev;
|
||||
poll_dev->poll = handle_buttons;
|
||||
poll_dev->poll_interval = BUTTONS_POLL_INTERVAL;
|
||||
|
||||
input = poll_dev->input;
|
||||
input->name = "SGI buttons";
|
||||
input->phys = "sgi/input0";
|
||||
input->id.bustype = BUS_HOST;
|
||||
input->dev.parent = &pdev->dev;
|
||||
|
||||
input->keycode = bdev->keymap;
|
||||
input->keycodemax = ARRAY_SIZE(bdev->keymap);
|
||||
input->keycodesize = sizeof(unsigned short);
|
||||
|
||||
input_set_capability(input, EV_MSC, MSC_SCAN);
|
||||
__set_bit(EV_KEY, input->evbit);
|
||||
for (i = 0; i < ARRAY_SIZE(sgi_map); i++)
|
||||
__set_bit(bdev->keymap[i], input->keybit);
|
||||
__clear_bit(KEY_RESERVED, input->keybit);
|
||||
|
||||
bdev->poll_dev = poll_dev;
|
||||
dev_set_drvdata(&pdev->dev, bdev);
|
||||
|
||||
error = input_register_polled_device(poll_dev);
|
||||
if (error)
|
||||
goto err_free_mem;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_mem:
|
||||
input_free_polled_device(poll_dev);
|
||||
kfree(bdev);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __devexit sgi_buttons_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct buttons_dev *bdev = dev_get_drvdata(dev);
|
||||
|
||||
input_unregister_polled_device(bdev->poll_dev);
|
||||
input_free_polled_device(bdev->poll_dev);
|
||||
kfree(bdev);
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver sgi_buttons_driver = {
|
||||
.probe = sgi_buttons_probe,
|
||||
.remove = __devexit_p(sgi_buttons_remove),
|
||||
.driver = {
|
||||
.name = "sgibtns",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sgi_buttons_init(void)
|
||||
{
|
||||
return platform_driver_register(&sgi_buttons_driver);
|
||||
}
|
||||
|
||||
static void __exit sgi_buttons_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sgi_buttons_driver);
|
||||
}
|
||||
|
||||
module_init(sgi_buttons_init);
|
||||
module_exit(sgi_buttons_exit);
|
|
@ -1186,7 +1186,7 @@ static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
|
|||
|
||||
static int __devinit setup_input_dev(void)
|
||||
{
|
||||
const struct key_entry *key;
|
||||
struct key_entry *key;
|
||||
struct input_dev *input_dev;
|
||||
int error;
|
||||
|
||||
|
@ -1219,6 +1219,23 @@ static int __devinit setup_input_dev(void)
|
|||
set_bit(key->sw.code, input_dev->swbit);
|
||||
break;
|
||||
|
||||
/* if wifi or bluetooth are not available, create normal keys */
|
||||
case KE_WIFI:
|
||||
if (!have_wifi) {
|
||||
key->type = KE_KEY;
|
||||
key->keycode = KEY_WLAN;
|
||||
key--;
|
||||
}
|
||||
break;
|
||||
|
||||
case KE_BLUETOOTH:
|
||||
if (!have_bluetooth) {
|
||||
key->type = KE_KEY;
|
||||
key->keycode = KEY_BLUETOOTH;
|
||||
key--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -119,6 +119,8 @@ struct yealink_dev {
|
|||
u8 lcdMap[ARRAY_SIZE(lcdMap)]; /* state of LCD, LED ... */
|
||||
int key_code; /* last reported key */
|
||||
|
||||
unsigned int shutdown:1;
|
||||
|
||||
int stat_ix;
|
||||
union {
|
||||
struct yld_status s;
|
||||
|
@ -424,10 +426,10 @@ static int yealink_do_idle_tasks(struct yealink_dev *yld)
|
|||
static void urb_irq_callback(struct urb *urb)
|
||||
{
|
||||
struct yealink_dev *yld = urb->context;
|
||||
int ret;
|
||||
int ret, status = urb->status;
|
||||
|
||||
if (urb->status)
|
||||
err("%s - urb status %d", __FUNCTION__, urb->status);
|
||||
if (status)
|
||||
err("%s - urb status %d", __func__, status);
|
||||
|
||||
switch (yld->irq_data->cmd) {
|
||||
case CMD_KEYPRESS:
|
||||
|
@ -447,33 +449,38 @@ static void urb_irq_callback(struct urb *urb)
|
|||
|
||||
yealink_do_idle_tasks(yld);
|
||||
|
||||
ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
|
||||
if (ret)
|
||||
err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
|
||||
if (!yld->shutdown) {
|
||||
ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
|
||||
if (ret && ret != -EPERM)
|
||||
err("%s - usb_submit_urb failed %d", __func__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void urb_ctl_callback(struct urb *urb)
|
||||
{
|
||||
struct yealink_dev *yld = urb->context;
|
||||
int ret;
|
||||
int ret = 0, status = urb->status;
|
||||
|
||||
if (urb->status)
|
||||
err("%s - urb status %d", __FUNCTION__, urb->status);
|
||||
if (status)
|
||||
err("%s - urb status %d", __func__, status);
|
||||
|
||||
switch (yld->ctl_data->cmd) {
|
||||
case CMD_KEYPRESS:
|
||||
case CMD_SCANCODE:
|
||||
/* ask for a response */
|
||||
ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
|
||||
if (!yld->shutdown)
|
||||
ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
|
||||
break;
|
||||
default:
|
||||
/* send new command */
|
||||
yealink_do_idle_tasks(yld);
|
||||
ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
|
||||
if (!yld->shutdown)
|
||||
ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
|
||||
if (ret && ret != -EPERM)
|
||||
err("%s - usb_submit_urb failed %d", __func__, ret);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -505,7 +512,7 @@ static int input_open(struct input_dev *dev)
|
|||
struct yealink_dev *yld = input_get_drvdata(dev);
|
||||
int i, ret;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
dbg("%s", __func__);
|
||||
|
||||
/* force updates to device */
|
||||
for (i = 0; i<sizeof(yld->master); i++)
|
||||
|
@ -521,7 +528,7 @@ static int input_open(struct input_dev *dev)
|
|||
yld->ctl_data->sum = 0x100-CMD_INIT-10;
|
||||
if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
|
||||
dbg("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, ret);
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
@ -531,8 +538,18 @@ static void input_close(struct input_dev *dev)
|
|||
{
|
||||
struct yealink_dev *yld = input_get_drvdata(dev);
|
||||
|
||||
yld->shutdown = 1;
|
||||
/*
|
||||
* Make sure the flag is seen by other CPUs before we start
|
||||
* killing URBs so new URBs won't be submitted
|
||||
*/
|
||||
smp_wmb();
|
||||
|
||||
usb_kill_urb(yld->urb_ctl);
|
||||
usb_kill_urb(yld->urb_irq);
|
||||
|
||||
yld->shutdown = 0;
|
||||
smp_wmb();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -809,9 +826,6 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
|
|||
if (yld == NULL)
|
||||
return err;
|
||||
|
||||
usb_kill_urb(yld->urb_irq); /* parameter validation in core/urb */
|
||||
usb_kill_urb(yld->urb_ctl); /* parameter validation in core/urb */
|
||||
|
||||
if (yld->idev) {
|
||||
if (err)
|
||||
input_free_device(yld->idev);
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
* Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver
|
||||
*
|
||||
* Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
|
||||
* Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
|
||||
* Copyright (C) 2005-2008 Johannes Berg (johannes@sipsolutions.net)
|
||||
* Copyright (C) 2005 Stelian Pop (stelian@popies.net)
|
||||
* Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
|
||||
* Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
|
||||
* Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
|
||||
* Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch)
|
||||
* Copyright (C) 2007-2008 Sven Anders (anders@anduras.de)
|
||||
*
|
||||
* Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
|
||||
*
|
||||
|
@ -34,77 +35,64 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/usb/input.h>
|
||||
|
||||
/* Apple has powerbooks which have the keyboard with different Product IDs */
|
||||
#define APPLE_VENDOR_ID 0x05AC
|
||||
/* Type of touchpad */
|
||||
enum atp_touchpad_type {
|
||||
ATP_FOUNTAIN,
|
||||
ATP_GEYSER1,
|
||||
ATP_GEYSER2,
|
||||
ATP_GEYSER3,
|
||||
ATP_GEYSER4
|
||||
};
|
||||
|
||||
/* These names come from Info.plist in AppleUSBTrackpad.kext */
|
||||
#define FOUNTAIN_ANSI_PRODUCT_ID 0x020E
|
||||
#define FOUNTAIN_ISO_PRODUCT_ID 0x020F
|
||||
|
||||
#define FOUNTAIN_TP_ONLY_PRODUCT_ID 0x030A
|
||||
|
||||
#define GEYSER1_TP_ONLY_PRODUCT_ID 0x030B
|
||||
|
||||
#define GEYSER_ANSI_PRODUCT_ID 0x0214
|
||||
#define GEYSER_ISO_PRODUCT_ID 0x0215
|
||||
#define GEYSER_JIS_PRODUCT_ID 0x0216
|
||||
|
||||
/* MacBook devices */
|
||||
#define GEYSER3_ANSI_PRODUCT_ID 0x0217
|
||||
#define GEYSER3_ISO_PRODUCT_ID 0x0218
|
||||
#define GEYSER3_JIS_PRODUCT_ID 0x0219
|
||||
|
||||
/*
|
||||
* Geyser IV: same as Geyser III according to Info.plist in AppleUSBTrackpad.kext
|
||||
* -> same IOClass (AppleUSBGrIIITrackpad), same acceleration tables
|
||||
*/
|
||||
#define GEYSER4_ANSI_PRODUCT_ID 0x021A
|
||||
#define GEYSER4_ISO_PRODUCT_ID 0x021B
|
||||
#define GEYSER4_JIS_PRODUCT_ID 0x021C
|
||||
|
||||
#define GEYSER4_HF_ANSI_PRODUCT_ID 0x0229
|
||||
#define GEYSER4_HF_ISO_PRODUCT_ID 0x022A
|
||||
#define GEYSER4_HF_JIS_PRODUCT_ID 0x022B
|
||||
|
||||
#define ATP_DEVICE(prod) \
|
||||
#define ATP_DEVICE(prod, type) \
|
||||
{ \
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS | \
|
||||
USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
|
||||
.idVendor = APPLE_VENDOR_ID, \
|
||||
.idVendor = 0x05ac, /* Apple */ \
|
||||
.idProduct = (prod), \
|
||||
.bInterfaceClass = 0x03, \
|
||||
.bInterfaceProtocol = 0x02
|
||||
.bInterfaceProtocol = 0x02, \
|
||||
.driver_info = ATP_ ## type, \
|
||||
}
|
||||
|
||||
/*
|
||||
* Table of devices (Product IDs) that work with this driver.
|
||||
* (The names come from Info.plist in AppleUSBTrackpad.kext,
|
||||
* According to Info.plist Geyser IV is the same as Geyser III.)
|
||||
*/
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
static struct usb_device_id atp_table [] = {
|
||||
{ ATP_DEVICE(FOUNTAIN_ANSI_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(FOUNTAIN_ISO_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(FOUNTAIN_TP_ONLY_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER1_TP_ONLY_PRODUCT_ID) },
|
||||
/* PowerBooks Feb 2005, iBooks G4 */
|
||||
ATP_DEVICE(0x020e, FOUNTAIN), /* FOUNTAIN ANSI */
|
||||
ATP_DEVICE(0x020f, FOUNTAIN), /* FOUNTAIN ISO */
|
||||
ATP_DEVICE(0x030a, FOUNTAIN), /* FOUNTAIN TP ONLY */
|
||||
ATP_DEVICE(0x030b, GEYSER1), /* GEYSER 1 TP ONLY */
|
||||
|
||||
/* PowerBooks Oct 2005 */
|
||||
{ ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
|
||||
ATP_DEVICE(0x0214, GEYSER2), /* GEYSER 2 ANSI */
|
||||
ATP_DEVICE(0x0215, GEYSER2), /* GEYSER 2 ISO */
|
||||
ATP_DEVICE(0x0216, GEYSER2), /* GEYSER 2 JIS */
|
||||
|
||||
/* Core Duo MacBook & MacBook Pro */
|
||||
{ ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
|
||||
ATP_DEVICE(0x0217, GEYSER3), /* GEYSER 3 ANSI */
|
||||
ATP_DEVICE(0x0218, GEYSER3), /* GEYSER 3 ISO */
|
||||
ATP_DEVICE(0x0219, GEYSER3), /* GEYSER 3 JIS */
|
||||
|
||||
/* Core2 Duo MacBook & MacBook Pro */
|
||||
{ ATP_DEVICE(GEYSER4_ANSI_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) },
|
||||
ATP_DEVICE(0x021a, GEYSER4), /* GEYSER 4 ANSI */
|
||||
ATP_DEVICE(0x021b, GEYSER4), /* GEYSER 4 ISO */
|
||||
ATP_DEVICE(0x021c, GEYSER4), /* GEYSER 4 JIS */
|
||||
|
||||
{ ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) },
|
||||
{ ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) },
|
||||
/* Core2 Duo MacBook3,1 */
|
||||
ATP_DEVICE(0x0229, GEYSER4), /* GEYSER 4 HF ANSI */
|
||||
ATP_DEVICE(0x022a, GEYSER4), /* GEYSER 4 HF ISO */
|
||||
ATP_DEVICE(0x022b, GEYSER4), /* GEYSER 4 HF JIS */
|
||||
|
||||
/* Terminating entry */
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE (usb, atp_table);
|
||||
MODULE_DEVICE_TABLE(usb, atp_table);
|
||||
|
||||
/*
|
||||
* number of sensors. Note that only 16 instead of 26 X (horizontal)
|
||||
|
@ -124,9 +112,13 @@ MODULE_DEVICE_TABLE (usb, atp_table);
|
|||
* We try to keep the touchpad aspect ratio while still doing only simple
|
||||
* arithmetics.
|
||||
* The factors below give coordinates like:
|
||||
* 0 <= x < 960 on 12" and 15" Powerbooks
|
||||
* 0 <= x < 1600 on 17" Powerbooks
|
||||
* 0 <= y < 646
|
||||
*
|
||||
* 0 <= x < 960 on 12" and 15" Powerbooks
|
||||
* 0 <= x < 1600 on 17" Powerbooks and 17" MacBook Pro
|
||||
* 0 <= x < 1216 on MacBooks and 15" MacBook Pro
|
||||
*
|
||||
* 0 <= y < 646 on all Powerbooks
|
||||
* 0 <= y < 774 on all MacBooks
|
||||
*/
|
||||
#define ATP_XFACT 64
|
||||
#define ATP_YFACT 43
|
||||
|
@ -147,43 +139,46 @@ MODULE_DEVICE_TABLE (usb, atp_table);
|
|||
/* Structure to hold all of our device specific stuff */
|
||||
struct atp {
|
||||
char phys[64];
|
||||
struct usb_device * udev; /* usb device */
|
||||
struct urb * urb; /* usb request block */
|
||||
signed char * data; /* transferred data */
|
||||
struct input_dev * input; /* input dev */
|
||||
unsigned char open; /* non-zero if opened */
|
||||
unsigned char valid; /* are the sensors valid ? */
|
||||
unsigned char size_detect_done;
|
||||
unsigned char overflowwarn; /* overflow warning printed? */
|
||||
struct usb_device *udev; /* usb device */
|
||||
struct urb *urb; /* usb request block */
|
||||
signed char *data; /* transferred data */
|
||||
struct input_dev *input; /* input dev */
|
||||
enum atp_touchpad_type type; /* type of touchpad */
|
||||
bool open;
|
||||
bool valid; /* are the samples valid? */
|
||||
bool size_detect_done;
|
||||
bool overflow_warned;
|
||||
int x_old; /* last reported x/y, */
|
||||
int y_old; /* used for smoothing */
|
||||
/* current value of the sensors */
|
||||
signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS];
|
||||
/* last value of the sensors */
|
||||
signed char xy_old[ATP_XSENSORS + ATP_YSENSORS];
|
||||
/* accumulated sensors */
|
||||
int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
|
||||
int datalen; /* size of an USB urb transfer */
|
||||
int idlecount; /* number of empty packets */
|
||||
struct work_struct work;
|
||||
int datalen; /* size of USB transfer */
|
||||
int idlecount; /* number of empty packets */
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
#define dbg_dump(msg, tab) \
|
||||
if (debug > 1) { \
|
||||
int i; \
|
||||
printk("appletouch: %s %lld", msg, (long long)jiffies); \
|
||||
for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \
|
||||
printk(" %02x", tab[i]); \
|
||||
int __i; \
|
||||
printk(KERN_DEBUG "appletouch: %s", msg); \
|
||||
for (__i = 0; __i < ATP_XSENSORS + ATP_YSENSORS; __i++) \
|
||||
printk(" %02x", tab[__i]); \
|
||||
printk("\n"); \
|
||||
}
|
||||
|
||||
#define dprintk(format, a...) \
|
||||
do { \
|
||||
if (debug) printk(KERN_DEBUG format, ##a); \
|
||||
if (debug) \
|
||||
printk(KERN_DEBUG format, ##a); \
|
||||
} while (0)
|
||||
|
||||
MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
|
||||
MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
|
||||
MODULE_AUTHOR("Johannes Berg");
|
||||
MODULE_AUTHOR("Stelian Pop");
|
||||
MODULE_AUTHOR("Frank Arnold");
|
||||
MODULE_AUTHOR("Michael Hanselmann");
|
||||
MODULE_AUTHOR("Sven Anders");
|
||||
MODULE_DESCRIPTION("Apple PowerBook and MacBook USB touchpad driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
|
@ -191,46 +186,14 @@ MODULE_LICENSE("GPL");
|
|||
*/
|
||||
static int threshold = ATP_THRESHOLD;
|
||||
module_param(threshold, int, 0644);
|
||||
MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value");
|
||||
MODULE_PARM_DESC(threshold, "Discard any change in data from a sensor"
|
||||
" (the trackpad has many of these sensors)"
|
||||
" less than this value.");
|
||||
|
||||
static int debug = 1;
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Activate debugging output");
|
||||
|
||||
static inline int atp_is_fountain(struct atp *dev)
|
||||
{
|
||||
u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
|
||||
|
||||
return productId == FOUNTAIN_ANSI_PRODUCT_ID ||
|
||||
productId == FOUNTAIN_ISO_PRODUCT_ID ||
|
||||
productId == FOUNTAIN_TP_ONLY_PRODUCT_ID;
|
||||
}
|
||||
|
||||
/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
|
||||
static inline int atp_is_geyser_2(struct atp *dev)
|
||||
{
|
||||
u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
|
||||
|
||||
return (productId == GEYSER_ANSI_PRODUCT_ID) ||
|
||||
(productId == GEYSER_ISO_PRODUCT_ID) ||
|
||||
(productId == GEYSER_JIS_PRODUCT_ID);
|
||||
}
|
||||
|
||||
static inline int atp_is_geyser_3(struct atp *dev)
|
||||
{
|
||||
u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
|
||||
|
||||
return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
|
||||
(productId == GEYSER3_ISO_PRODUCT_ID) ||
|
||||
(productId == GEYSER3_JIS_PRODUCT_ID) ||
|
||||
(productId == GEYSER4_ANSI_PRODUCT_ID) ||
|
||||
(productId == GEYSER4_ISO_PRODUCT_ID) ||
|
||||
(productId == GEYSER4_JIS_PRODUCT_ID) ||
|
||||
(productId == GEYSER4_HF_ANSI_PRODUCT_ID) ||
|
||||
(productId == GEYSER4_HF_ISO_PRODUCT_ID) ||
|
||||
(productId == GEYSER4_HF_JIS_PRODUCT_ID);
|
||||
}
|
||||
|
||||
/*
|
||||
* By default newer Geyser devices send standard USB HID mouse
|
||||
* packets (Report ID 2). This code changes device mode, so it
|
||||
|
@ -240,6 +203,7 @@ static int atp_geyser_init(struct usb_device *udev)
|
|||
{
|
||||
char data[8];
|
||||
int size;
|
||||
int i;
|
||||
|
||||
size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||
ATP_GEYSER_MODE_READ_REQUEST_ID,
|
||||
|
@ -248,8 +212,11 @@ static int atp_geyser_init(struct usb_device *udev)
|
|||
ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
|
||||
|
||||
if (size != 8) {
|
||||
err("Could not do mode read request from device"
|
||||
" (Geyser Raw mode)");
|
||||
dprintk("atp_geyser_init: read error\n");
|
||||
for (i = 0; i < 8; i++)
|
||||
dprintk("appletouch[%d]: %d\n", i, data[i]);
|
||||
|
||||
err("Failed to read mode from device.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -263,8 +230,11 @@ static int atp_geyser_init(struct usb_device *udev)
|
|||
ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
|
||||
|
||||
if (size != 8) {
|
||||
err("Could not do mode write request to device"
|
||||
" (Geyser Raw mode)");
|
||||
dprintk("atp_geyser_init: write error\n");
|
||||
for (i = 0; i < 8; i++)
|
||||
dprintk("appletouch[%d]: %d\n", i, data[i]);
|
||||
|
||||
err("Failed to request geyser raw mode");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
|
@ -280,15 +250,15 @@ static void atp_reinit(struct work_struct *work)
|
|||
struct usb_device *udev = dev->udev;
|
||||
int retval;
|
||||
|
||||
dprintk("appletouch: putting appletouch to sleep (reinit)\n");
|
||||
dev->idlecount = 0;
|
||||
|
||||
atp_geyser_init(udev);
|
||||
|
||||
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
|
||||
if (retval) {
|
||||
err("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
if (retval)
|
||||
err("atp_reinit: usb_submit_urb failed with error %d",
|
||||
retval);
|
||||
}
|
||||
|
||||
static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
|
||||
|
@ -323,7 +293,8 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
|
|||
*
|
||||
* - Jason Parekh <jasonparekh@gmail.com>
|
||||
*/
|
||||
if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
|
||||
if (i < 1 ||
|
||||
(!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
|
||||
(*fingers)++;
|
||||
is_increasing = 1;
|
||||
} else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) {
|
||||
|
@ -331,11 +302,11 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
|
|||
}
|
||||
|
||||
/*
|
||||
* Subtracts threshold so a high sensor that just passes the threshold
|
||||
* won't skew the calculated absolute coordinate. Fixes an issue
|
||||
* where slowly moving the mouse would occassionaly jump a number of
|
||||
* pixels (let me restate--slowly moving the mouse makes this issue
|
||||
* most apparent).
|
||||
* Subtracts threshold so a high sensor that just passes the
|
||||
* threshold won't skew the calculated absolute coordinate.
|
||||
* Fixes an issue where slowly moving the mouse would
|
||||
* occasionally jump a number of pixels (slowly moving the
|
||||
* finger makes this issue most apparent.)
|
||||
*/
|
||||
pcum += (xy_sensors[i] - threshold) * i;
|
||||
psum += (xy_sensors[i] - threshold);
|
||||
|
@ -356,7 +327,7 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
|
|||
input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
|
||||
}
|
||||
|
||||
static void atp_complete(struct urb* urb)
|
||||
static void atp_complete(struct urb *urb)
|
||||
{
|
||||
int x, y, x_z, y_z, x_f, y_f;
|
||||
int retval, i, j;
|
||||
|
@ -368,22 +339,22 @@ static void atp_complete(struct urb* urb)
|
|||
/* success */
|
||||
break;
|
||||
case -EOVERFLOW:
|
||||
if(!dev->overflowwarn) {
|
||||
if (!dev->overflow_warned) {
|
||||
printk(KERN_WARNING "appletouch: OVERFLOW with data "
|
||||
"length %d, actual length is %d\n",
|
||||
dev->datalen, dev->urb->actual_length);
|
||||
dev->overflowwarn = 1;
|
||||
dev->overflow_warned = true;
|
||||
}
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
/* This urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d",
|
||||
__FUNCTION__, urb->status);
|
||||
dbg("atp_complete: urb shutting down with status: %d",
|
||||
urb->status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d",
|
||||
__FUNCTION__, urb->status);
|
||||
dbg("atp_complete: nonzero urb status received: %d",
|
||||
urb->status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -396,7 +367,7 @@ static void atp_complete(struct urb* urb)
|
|||
}
|
||||
|
||||
/* reorder the sensors values */
|
||||
if (atp_is_geyser_3(dev)) {
|
||||
if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
|
||||
memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
|
||||
|
||||
/*
|
||||
|
@ -415,7 +386,7 @@ static void atp_complete(struct urb* urb)
|
|||
dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
|
||||
dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
|
||||
}
|
||||
} else if (atp_is_geyser_2(dev)) {
|
||||
} else if (dev->type == ATP_GEYSER2) {
|
||||
memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
|
||||
|
||||
/*
|
||||
|
@ -438,7 +409,7 @@ static void atp_complete(struct urb* urb)
|
|||
} else {
|
||||
for (i = 0; i < 8; i++) {
|
||||
/* X values */
|
||||
dev->xy_cur[i ] = dev->data[5 * i + 2];
|
||||
dev->xy_cur[i + 0] = dev->data[5 * i + 2];
|
||||
dev->xy_cur[i + 8] = dev->data[5 * i + 4];
|
||||
dev->xy_cur[i + 16] = dev->data[5 * i + 42];
|
||||
if (i < 2)
|
||||
|
@ -454,21 +425,22 @@ static void atp_complete(struct urb* urb)
|
|||
|
||||
if (!dev->valid) {
|
||||
/* first sample */
|
||||
dev->valid = 1;
|
||||
dev->valid = true;
|
||||
dev->x_old = dev->y_old = -1;
|
||||
memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
|
||||
|
||||
if (dev->size_detect_done ||
|
||||
atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */
|
||||
dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */
|
||||
goto exit;
|
||||
|
||||
/* 17" Powerbooks have extra X sensors */
|
||||
for (i = (atp_is_geyser_2(dev) ? 15 : 16); i < ATP_XSENSORS; i++) {
|
||||
for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
|
||||
i < ATP_XSENSORS; i++) {
|
||||
if (!dev->xy_cur[i])
|
||||
continue;
|
||||
|
||||
printk(KERN_INFO "appletouch: 17\" model detected.\n");
|
||||
if (atp_is_geyser_2(dev))
|
||||
if (dev->type == ATP_GEYSER2)
|
||||
input_set_abs_params(dev->input, ABS_X, 0,
|
||||
(20 - 1) *
|
||||
ATP_XFACT - 1,
|
||||
|
@ -548,11 +520,15 @@ static void atp_complete(struct urb* urb)
|
|||
* several hundred times a second. Re-initialization does not
|
||||
* work on Fountain touchpads.
|
||||
*/
|
||||
if (!atp_is_fountain(dev)) {
|
||||
if (dev->type != ATP_FOUNTAIN) {
|
||||
/*
|
||||
* Button must not be pressed when entering suspend,
|
||||
* otherwise we will never release the button.
|
||||
*/
|
||||
if (!x && !y && !key) {
|
||||
dev->idlecount++;
|
||||
if (dev->idlecount == 10) {
|
||||
dev->valid = 0;
|
||||
dev->valid = false;
|
||||
schedule_work(&dev->work);
|
||||
/* Don't resubmit urb here, wait for reinit */
|
||||
return;
|
||||
|
@ -561,12 +537,11 @@ static void atp_complete(struct urb* urb)
|
|||
dev->idlecount = 0;
|
||||
}
|
||||
|
||||
exit:
|
||||
exit:
|
||||
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
|
||||
if (retval) {
|
||||
err("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
if (retval)
|
||||
err("atp_complete: usb_submit_urb failed with result %d",
|
||||
retval);
|
||||
}
|
||||
|
||||
static int atp_open(struct input_dev *input)
|
||||
|
@ -593,7 +568,7 @@ static int atp_handle_geyser(struct atp *dev)
|
|||
{
|
||||
struct usb_device *udev = dev->udev;
|
||||
|
||||
if (!atp_is_fountain(dev)) {
|
||||
if (dev->type != ATP_FOUNTAIN) {
|
||||
/* switch to raw sensor mode */
|
||||
if (atp_geyser_init(udev))
|
||||
return -EIO;
|
||||
|
@ -604,7 +579,8 @@ static int atp_handle_geyser(struct atp *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
|
||||
static int atp_probe(struct usb_interface *iface,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct atp *dev;
|
||||
struct input_dev *input_dev;
|
||||
|
@ -640,13 +616,12 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|||
|
||||
dev->udev = udev;
|
||||
dev->input = input_dev;
|
||||
dev->overflowwarn = 0;
|
||||
if (atp_is_geyser_3(dev))
|
||||
dev->datalen = 64;
|
||||
else if (atp_is_geyser_2(dev))
|
||||
dev->datalen = 64;
|
||||
else
|
||||
dev->type = id->driver_info;
|
||||
dev->overflow_warned = false;
|
||||
if (dev->type == ATP_FOUNTAIN || dev->type == ATP_GEYSER1)
|
||||
dev->datalen = 81;
|
||||
else
|
||||
dev->datalen = 64;
|
||||
|
||||
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!dev->urb)
|
||||
|
@ -680,7 +655,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|||
|
||||
set_bit(EV_ABS, input_dev->evbit);
|
||||
|
||||
if (atp_is_geyser_3(dev)) {
|
||||
if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
|
||||
/*
|
||||
* MacBook have 20 X sensors, 10 Y sensors
|
||||
*/
|
||||
|
@ -688,7 +663,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|||
((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
|
||||
input_set_abs_params(input_dev, ABS_Y, 0,
|
||||
((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
|
||||
} else if (atp_is_geyser_2(dev)) {
|
||||
} else if (dev->type == ATP_GEYSER2) {
|
||||
/*
|
||||
* Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
|
||||
* later.
|
||||
|
@ -703,9 +678,11 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|||
* 17" models are detected later.
|
||||
*/
|
||||
input_set_abs_params(input_dev, ABS_X, 0,
|
||||
(16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
|
||||
(16 - 1) * ATP_XFACT - 1,
|
||||
ATP_FUZZ, 0);
|
||||
input_set_abs_params(input_dev, ABS_Y, 0,
|
||||
(ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
|
||||
(ATP_YSENSORS - 1) * ATP_YFACT - 1,
|
||||
ATP_FUZZ, 0);
|
||||
}
|
||||
input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
|
||||
|
||||
|
@ -774,7 +751,7 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
|
|||
struct atp *dev = usb_get_intfdata(iface);
|
||||
|
||||
usb_kill_urb(dev->urb);
|
||||
dev->valid = 0;
|
||||
dev->valid = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -57,15 +57,12 @@ MODULE_AUTHOR("Michael Schmitz <schmitz@biophys.uni-duesseldorf.de>");
|
|||
MODULE_DESCRIPTION("Atari mouse driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int mouse_threshold[2] = {2,2};
|
||||
static int mouse_threshold[2] = {2, 2};
|
||||
module_param_array(mouse_threshold, int, NULL, 0);
|
||||
|
||||
#ifdef __MODULE__
|
||||
MODULE_PARM(mouse_threshold, "2i");
|
||||
#endif
|
||||
#ifdef FIXED_ATARI_JOYSTICK
|
||||
extern int atari_mouse_buttons;
|
||||
#endif
|
||||
static int atamouse_used = 0;
|
||||
|
||||
static struct input_dev *atamouse_dev;
|
||||
|
||||
|
@ -97,9 +94,6 @@ static void atamouse_interrupt(char *buf)
|
|||
|
||||
static int atamouse_open(struct input_dev *dev)
|
||||
{
|
||||
if (atamouse_used++)
|
||||
return 0;
|
||||
|
||||
#ifdef FIXED_ATARI_JOYSTICK
|
||||
atari_mouse_buttons = 0;
|
||||
#endif
|
||||
|
@ -107,23 +101,24 @@ static int atamouse_open(struct input_dev *dev)
|
|||
ikbd_mouse_thresh(mouse_threshold[0], mouse_threshold[1]);
|
||||
ikbd_mouse_rel_pos();
|
||||
atari_input_mouse_interrupt_hook = atamouse_interrupt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void atamouse_close(struct input_dev *dev)
|
||||
{
|
||||
if (!--atamouse_used) {
|
||||
ikbd_mouse_disable();
|
||||
atari_mouse_interrupt_hook = NULL;
|
||||
}
|
||||
ikbd_mouse_disable();
|
||||
atari_mouse_interrupt_hook = NULL;
|
||||
}
|
||||
|
||||
static int __init atamouse_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP))
|
||||
return -ENODEV;
|
||||
|
||||
if (!(atari_keyb_init()))
|
||||
if (!atari_keyb_init())
|
||||
return -ENODEV;
|
||||
|
||||
atamouse_dev = input_allocate_device();
|
||||
|
@ -141,12 +136,14 @@ static int __init atamouse_init(void)
|
|||
atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
|
||||
atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
|
||||
BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
|
||||
|
||||
atamouse_dev->open = atamouse_open;
|
||||
atamouse_dev->close = atamouse_close;
|
||||
|
||||
if (input_register_device(atamouse_dev)) {
|
||||
error = input_register_device(atamouse_dev);
|
||||
if (error) {
|
||||
input_free_device(atamouse_dev);
|
||||
return -ENOMEM;
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -247,19 +247,24 @@ static void hil_ptr_disconnect(struct serio *serio)
|
|||
|
||||
static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
|
||||
{
|
||||
struct hil_ptr *ptr;
|
||||
const char *txt;
|
||||
unsigned int i, naxsets, btntype;
|
||||
uint8_t did, *idd;
|
||||
struct hil_ptr *ptr;
|
||||
const char *txt;
|
||||
unsigned int i, naxsets, btntype;
|
||||
uint8_t did, *idd;
|
||||
int error;
|
||||
|
||||
if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL)))
|
||||
ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
ptr->dev = input_allocate_device();
|
||||
if (!ptr->dev)
|
||||
if (!ptr->dev) {
|
||||
error = -ENOMEM;
|
||||
goto bail0;
|
||||
}
|
||||
|
||||
if (serio_open(serio, driver))
|
||||
error = serio_open(serio, driver);
|
||||
if (error)
|
||||
goto bail1;
|
||||
|
||||
serio_set_drvdata(serio, ptr);
|
||||
|
@ -297,6 +302,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
|
|||
did = ptr->idd[0];
|
||||
idd = ptr->idd + 1;
|
||||
txt = "unknown";
|
||||
|
||||
if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
|
||||
ptr->dev->evbit[0] = BIT_MASK(EV_REL);
|
||||
txt = "relative";
|
||||
|
@ -306,8 +312,11 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
|
|||
ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
|
||||
txt = "absolute";
|
||||
}
|
||||
if (!ptr->dev->evbit[0])
|
||||
|
||||
if (!ptr->dev->evbit[0]) {
|
||||
error = -ENODEV;
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
|
||||
if (ptr->nbtn)
|
||||
|
@ -380,13 +389,19 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
|
|||
ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */
|
||||
ptr->dev->dev.parent = &serio->dev;
|
||||
|
||||
input_register_device(ptr->dev);
|
||||
error = input_register_device(ptr->dev);
|
||||
if (error) {
|
||||
printk(KERN_INFO PREFIX "Unable to register input device\n");
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "input: %s (%s), ID: %d\n",
|
||||
ptr->dev->name,
|
||||
(btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
|
||||
did);
|
||||
|
||||
return 0;
|
||||
|
||||
bail2:
|
||||
serio_close(serio);
|
||||
bail1:
|
||||
|
@ -394,7 +409,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
|
|||
bail0:
|
||||
kfree(ptr);
|
||||
serio_set_drvdata(serio, NULL);
|
||||
return -ENODEV;
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct serio_device_id hil_ptr_ids[] = {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: inport.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: logibm.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: pc110pad.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: sermouse.c,v 1.17 2002/03/13 10:03:43 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -190,4 +190,14 @@ config SERIO_RAW
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called serio_raw.
|
||||
|
||||
config SERIO_XILINX_XPS_PS2
|
||||
tristate "Xilinx XPS PS/2 Controller Support"
|
||||
depends on PPC
|
||||
help
|
||||
This driver supports XPS PS/2 IP from the Xilinx EDK on
|
||||
PowerPC platform.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called xilinx_ps2.
|
||||
|
||||
endif
|
||||
|
|
|
@ -21,3 +21,4 @@ obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o
|
|||
obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o
|
||||
obj-$(CONFIG_SERIO_LIBPS2) += libps2.o
|
||||
obj-$(CONFIG_SERIO_RAW) += serio_raw.o
|
||||
obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: ct82c710.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ static struct timer_list hil_mlcs_kicker;
|
|||
static int hil_mlcs_probe;
|
||||
|
||||
static void hil_mlcs_process(unsigned long unused);
|
||||
DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
|
||||
static DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
|
||||
|
||||
|
||||
/* #define HIL_MLC_DEBUG */
|
||||
|
@ -459,7 +459,7 @@ static int hilse_operate(hil_mlc *mlc, int repoll)
|
|||
#define OUT_LAST(pack) \
|
||||
{ HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 },
|
||||
|
||||
const struct hilse_node hil_mlc_se[HILSEN_END] = {
|
||||
static const struct hilse_node hil_mlc_se[HILSEN_END] = {
|
||||
|
||||
/* 0 HILSEN_START */
|
||||
FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0)
|
||||
|
@ -784,7 +784,7 @@ static void hil_mlcs_process(unsigned long unused)
|
|||
|
||||
/************************* Keepalive timer task *********************/
|
||||
|
||||
void hil_mlcs_timer(unsigned long data)
|
||||
static void hil_mlcs_timer(unsigned long data)
|
||||
{
|
||||
hil_mlcs_probe = 1;
|
||||
tasklet_schedule(&hil_mlcs_tasklet);
|
||||
|
|
|
@ -105,6 +105,10 @@ EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
|
|||
EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
|
||||
EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
|
||||
|
||||
static unsigned int hp_sdc_disabled;
|
||||
module_param_named(no_hpsdc, hp_sdc_disabled, bool, 0);
|
||||
MODULE_PARM_DESC(no_hpsdc, "Do not enable HP SDC driver.");
|
||||
|
||||
static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */
|
||||
|
||||
/*************** primitives for use in any context *********************/
|
||||
|
@ -980,6 +984,11 @@ static int __init hp_sdc_register(void)
|
|||
unsigned char i;
|
||||
#endif
|
||||
|
||||
if (hp_sdc_disabled) {
|
||||
printk(KERN_WARNING PREFIX "HP SDC driver disabled by no_hpsdc=1.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
hp_sdc.dev = NULL;
|
||||
hp_sdc.dev_err = 0;
|
||||
#if defined(__hppa__)
|
||||
|
|
|
@ -50,7 +50,7 @@ MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
|
|||
MODULE_DESCRIPTION("Glue for onboard HIL MLC in HP-PARISC machines");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
struct hp_sdc_mlc_priv_s {
|
||||
static struct hp_sdc_mlc_priv_s {
|
||||
int emtestmode;
|
||||
hp_sdc_transaction trans;
|
||||
u8 tseq[16];
|
||||
|
|
|
@ -63,11 +63,20 @@ static inline void i8042_write_command(int val)
|
|||
outb(val, I8042_COMMAND_REG);
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#ifdef CONFIG_X86
|
||||
|
||||
#include <linux/dmi.h>
|
||||
|
||||
static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
|
||||
{
|
||||
/* AUX LOOP command does not raise AUX IRQ */
|
||||
.ident = "Arima-Rioworks HDAMB",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
|
||||
DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* AUX LOOP command does not raise AUX IRQ */
|
||||
.ident = "ASUS P65UP5",
|
||||
|
@ -118,6 +127,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Medion MAM 2070",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -291,17 +308,36 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Acer Aspire 1360",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Gericom Bellagio",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
|
||||
{
|
||||
.ident = "Intel MBO Desktop D845PESV",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
|
||||
#include <linux/dmi.h>
|
||||
|
||||
/*
|
||||
* Some Wistron based laptops need us to explicitly enable the 'Dritek
|
||||
* keyboard extension' to make their extra keys start generating scancodes.
|
||||
|
@ -330,6 +366,13 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Acer Aspire 5720",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Acer Aspire 9110",
|
||||
.matches = {
|
||||
|
@ -356,7 +399,6 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
|
|||
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
#include <linux/pnp.h>
|
||||
|
||||
|
@ -466,6 +508,11 @@ static int __init i8042_pnp_init(void)
|
|||
int pnp_data_busted = 0;
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
if (dmi_check_system(i8042_dmi_nopnp_table))
|
||||
i8042_nopnp = 1;
|
||||
#endif
|
||||
|
||||
if (i8042_nopnp) {
|
||||
printk(KERN_INFO "i8042: PNP detection disabled\n");
|
||||
return 0;
|
||||
|
@ -591,15 +638,13 @@ static int __init i8042_platform_init(void)
|
|||
i8042_reset = 1;
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#ifdef CONFIG_X86
|
||||
if (dmi_check_system(i8042_dmi_noloop_table))
|
||||
i8042_noloop = 1;
|
||||
|
||||
if (dmi_check_system(i8042_dmi_nomux_table))
|
||||
i8042_nomux = 1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
if (dmi_check_system(i8042_dmi_dritek_table))
|
||||
i8042_dritek = 1;
|
||||
#endif /* CONFIG_X86 */
|
||||
|
|
|
@ -26,15 +26,6 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
|
|||
MODULE_DESCRIPTION("PS/2 driver library");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* Work structure to schedule execution of a command */
|
||||
struct ps2work {
|
||||
struct work_struct work;
|
||||
struct ps2dev *ps2dev;
|
||||
int command;
|
||||
unsigned char param[0];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ps2_sendbyte() sends a byte to the device and waits for acknowledge.
|
||||
* It doesn't handle retransmission, though it could - because if there
|
||||
|
@ -245,49 +236,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
|
|||
}
|
||||
EXPORT_SYMBOL(ps2_command);
|
||||
|
||||
/*
|
||||
* ps2_execute_scheduled_command() sends a command, previously scheduled by
|
||||
* ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.)
|
||||
*/
|
||||
|
||||
static void ps2_execute_scheduled_command(struct work_struct *work)
|
||||
{
|
||||
struct ps2work *ps2work = container_of(work, struct ps2work, work);
|
||||
|
||||
ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command);
|
||||
kfree(ps2work);
|
||||
}
|
||||
|
||||
/*
|
||||
* ps2_schedule_command() allows to schedule delayed execution of a PS/2
|
||||
* command and can be used to issue a command from an interrupt or softirq
|
||||
* context.
|
||||
*/
|
||||
|
||||
int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command)
|
||||
{
|
||||
struct ps2work *ps2work;
|
||||
int send = (command >> 12) & 0xf;
|
||||
int receive = (command >> 8) & 0xf;
|
||||
|
||||
if (!(ps2work = kmalloc(sizeof(struct ps2work) + max(send, receive), GFP_ATOMIC)))
|
||||
return -1;
|
||||
|
||||
memset(ps2work, 0, sizeof(struct ps2work));
|
||||
ps2work->ps2dev = ps2dev;
|
||||
ps2work->command = command;
|
||||
memcpy(ps2work->param, param, send);
|
||||
INIT_WORK(&ps2work->work, ps2_execute_scheduled_command);
|
||||
|
||||
if (!schedule_work(&ps2work->work)) {
|
||||
kfree(ps2work);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ps2_schedule_command);
|
||||
|
||||
/*
|
||||
* ps2_init() initializes ps2dev structure
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: q40kbd.c,v 1.12 2002/02/02 22:26:44 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik
|
||||
*
|
||||
* Based on the work of:
|
||||
|
@ -49,7 +47,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
|
|||
MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
DEFINE_SPINLOCK(q40kbd_lock);
|
||||
static DEFINE_SPINLOCK(q40kbd_lock);
|
||||
static struct serio *q40kbd_port;
|
||||
static struct platform_device *q40kbd_device;
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: rpckbd.c,v 1.7 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik
|
||||
* Copyright (c) 2002 Russell King
|
||||
*/
|
||||
|
|
|
@ -331,9 +331,10 @@ static void serio_handle_event(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Remove all events that have been submitted for a given serio port.
|
||||
* Remove all events that have been submitted for a given
|
||||
* object, be it serio port or driver.
|
||||
*/
|
||||
static void serio_remove_pending_events(struct serio *serio)
|
||||
static void serio_remove_pending_events(void *object)
|
||||
{
|
||||
struct list_head *node, *next;
|
||||
struct serio_event *event;
|
||||
|
@ -343,7 +344,7 @@ static void serio_remove_pending_events(struct serio *serio)
|
|||
|
||||
list_for_each_safe(node, next, &serio_event_list) {
|
||||
event = list_entry(node, struct serio_event, node);
|
||||
if (event->object == serio) {
|
||||
if (event->object == object) {
|
||||
list_del_init(node);
|
||||
serio_free_event(event);
|
||||
}
|
||||
|
@ -837,7 +838,9 @@ void serio_unregister_driver(struct serio_driver *drv)
|
|||
struct serio *serio;
|
||||
|
||||
mutex_lock(&serio_mutex);
|
||||
|
||||
drv->manual_bind = 1; /* so serio_find_driver ignores it */
|
||||
serio_remove_pending_events(drv);
|
||||
|
||||
start_over:
|
||||
list_for_each_entry(serio, &serio_list, node) {
|
||||
|
|
380
drivers/input/serio/xilinx_ps2.c
Normal file
380
drivers/input/serio/xilinx_ps2.c
Normal file
|
@ -0,0 +1,380 @@
|
|||
/*
|
||||
* Xilinx XPS PS/2 device driver
|
||||
*
|
||||
* (c) 2005 MontaVista Software, Inc.
|
||||
* (c) 2008 Xilinx, Inc.
|
||||
*
|
||||
* 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 (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#define DRIVER_NAME "xilinx_ps2"
|
||||
|
||||
/* Register offsets for the xps2 device */
|
||||
#define XPS2_SRST_OFFSET 0x00000000 /* Software Reset register */
|
||||
#define XPS2_STATUS_OFFSET 0x00000004 /* Status register */
|
||||
#define XPS2_RX_DATA_OFFSET 0x00000008 /* Receive Data register */
|
||||
#define XPS2_TX_DATA_OFFSET 0x0000000C /* Transmit Data register */
|
||||
#define XPS2_GIER_OFFSET 0x0000002C /* Global Interrupt Enable reg */
|
||||
#define XPS2_IPISR_OFFSET 0x00000030 /* Interrupt Status register */
|
||||
#define XPS2_IPIER_OFFSET 0x00000038 /* Interrupt Enable register */
|
||||
|
||||
/* Reset Register Bit Definitions */
|
||||
#define XPS2_SRST_RESET 0x0000000A /* Software Reset */
|
||||
|
||||
/* Status Register Bit Positions */
|
||||
#define XPS2_STATUS_RX_FULL 0x00000001 /* Receive Full */
|
||||
#define XPS2_STATUS_TX_FULL 0x00000002 /* Transmit Full */
|
||||
|
||||
/* Bit definitions for ISR/IER registers. Both the registers have the same bit
|
||||
* definitions and are only defined once. */
|
||||
#define XPS2_IPIXR_WDT_TOUT 0x00000001 /* Watchdog Timeout Interrupt */
|
||||
#define XPS2_IPIXR_TX_NOACK 0x00000002 /* Transmit No ACK Interrupt */
|
||||
#define XPS2_IPIXR_TX_ACK 0x00000004 /* Transmit ACK (Data) Interrupt */
|
||||
#define XPS2_IPIXR_RX_OVF 0x00000008 /* Receive Overflow Interrupt */
|
||||
#define XPS2_IPIXR_RX_ERR 0x00000010 /* Receive Error Interrupt */
|
||||
#define XPS2_IPIXR_RX_FULL 0x00000020 /* Receive Data Interrupt */
|
||||
|
||||
/* Mask for all the Transmit Interrupts */
|
||||
#define XPS2_IPIXR_TX_ALL (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_TX_ACK)
|
||||
|
||||
/* Mask for all the Receive Interrupts */
|
||||
#define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \
|
||||
XPS2_IPIXR_RX_FULL)
|
||||
|
||||
/* Mask for all the Interrupts */
|
||||
#define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \
|
||||
XPS2_IPIXR_WDT_TOUT)
|
||||
|
||||
/* Global Interrupt Enable mask */
|
||||
#define XPS2_GIER_GIE_MASK 0x80000000
|
||||
|
||||
struct xps2data {
|
||||
int irq;
|
||||
u32 phys_addr;
|
||||
u32 remap_size;
|
||||
spinlock_t lock;
|
||||
u8 rxb; /* Rx buffer */
|
||||
void __iomem *base_address; /* virt. address of control registers */
|
||||
unsigned int dfl;
|
||||
struct serio serio; /* serio */
|
||||
};
|
||||
|
||||
/************************************/
|
||||
/* XPS PS/2 data transmission calls */
|
||||
/************************************/
|
||||
|
||||
/*
|
||||
* xps2_recv() will attempt to receive a byte of data from the PS/2 port.
|
||||
*/
|
||||
static int xps2_recv(struct xps2data *drvdata, u8 *byte)
|
||||
{
|
||||
u32 sr;
|
||||
int status = -1;
|
||||
|
||||
/* If there is data available in the PS/2 receiver, read it */
|
||||
sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
|
||||
if (sr & XPS2_STATUS_RX_FULL) {
|
||||
*byte = in_be32(drvdata->base_address + XPS2_RX_DATA_OFFSET);
|
||||
status = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*********************/
|
||||
/* Interrupt handler */
|
||||
/*********************/
|
||||
static irqreturn_t xps2_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct xps2data *drvdata = dev_id;
|
||||
u32 intr_sr;
|
||||
u8 c;
|
||||
int status;
|
||||
|
||||
/* Get the PS/2 interrupts and clear them */
|
||||
intr_sr = in_be32(drvdata->base_address + XPS2_IPISR_OFFSET);
|
||||
out_be32(drvdata->base_address + XPS2_IPISR_OFFSET, intr_sr);
|
||||
|
||||
/* Check which interrupt is active */
|
||||
if (intr_sr & XPS2_IPIXR_RX_OVF)
|
||||
printk(KERN_WARNING "%s: receive overrun error\n",
|
||||
drvdata->serio.name);
|
||||
|
||||
if (intr_sr & XPS2_IPIXR_RX_ERR)
|
||||
drvdata->dfl |= SERIO_PARITY;
|
||||
|
||||
if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
|
||||
drvdata->dfl |= SERIO_TIMEOUT;
|
||||
|
||||
if (intr_sr & XPS2_IPIXR_RX_FULL) {
|
||||
status = xps2_recv(drvdata, &drvdata->rxb);
|
||||
|
||||
/* Error, if a byte is not received */
|
||||
if (status) {
|
||||
printk(KERN_ERR
|
||||
"%s: wrong rcvd byte count (%d)\n",
|
||||
drvdata->serio.name, status);
|
||||
} else {
|
||||
c = drvdata->rxb;
|
||||
serio_interrupt(&drvdata->serio, c, drvdata->dfl);
|
||||
drvdata->dfl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (intr_sr & XPS2_IPIXR_TX_ACK)
|
||||
drvdata->dfl = 0;
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*******************/
|
||||
/* serio callbacks */
|
||||
/*******************/
|
||||
|
||||
/*
|
||||
* sxps2_write() sends a byte out through the PS/2 interface.
|
||||
*/
|
||||
static int sxps2_write(struct serio *pserio, unsigned char c)
|
||||
{
|
||||
struct xps2data *drvdata = pserio->port_data;
|
||||
unsigned long flags;
|
||||
u32 sr;
|
||||
int status = -1;
|
||||
|
||||
spin_lock_irqsave(&drvdata->lock, flags);
|
||||
|
||||
/* If the PS/2 transmitter is empty send a byte of data */
|
||||
sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
|
||||
if (!(sr & XPS2_STATUS_TX_FULL)) {
|
||||
out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c);
|
||||
status = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&drvdata->lock, flags);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* sxps2_open() is called when a port is open by the higher layer.
|
||||
*/
|
||||
static int sxps2_open(struct serio *pserio)
|
||||
{
|
||||
struct xps2data *drvdata = pserio->port_data;
|
||||
int retval;
|
||||
|
||||
retval = request_irq(drvdata->irq, &xps2_interrupt, 0,
|
||||
DRIVER_NAME, drvdata);
|
||||
if (retval) {
|
||||
printk(KERN_ERR
|
||||
"%s: Couldn't allocate interrupt %d\n",
|
||||
drvdata->serio.name, drvdata->irq);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* start reception by enabling the interrupts */
|
||||
out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK);
|
||||
out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL);
|
||||
(void)xps2_recv(drvdata, &drvdata->rxb);
|
||||
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/*
|
||||
* sxps2_close() frees the interrupt.
|
||||
*/
|
||||
static void sxps2_close(struct serio *pserio)
|
||||
{
|
||||
struct xps2data *drvdata = pserio->port_data;
|
||||
|
||||
/* Disable the PS2 interrupts */
|
||||
out_be32(drvdata->base_address + XPS2_GIER_OFFSET, 0x00);
|
||||
out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0x00);
|
||||
free_irq(drvdata->irq, drvdata);
|
||||
}
|
||||
|
||||
/*********************/
|
||||
/* Device setup code */
|
||||
/*********************/
|
||||
|
||||
static int xps2_setup(struct device *dev, struct resource *regs_res,
|
||||
struct resource *irq_res)
|
||||
{
|
||||
struct xps2data *drvdata;
|
||||
struct serio *serio;
|
||||
unsigned long remap_size;
|
||||
int retval;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
if (!regs_res || !irq_res) {
|
||||
dev_err(dev, "IO resource(s) not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
|
||||
if (!drvdata) {
|
||||
dev_err(dev, "Couldn't allocate device private record\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, drvdata);
|
||||
|
||||
spin_lock_init(&drvdata->lock);
|
||||
drvdata->irq = irq_res->start;
|
||||
|
||||
remap_size = regs_res->end - regs_res->start + 1;
|
||||
if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) {
|
||||
dev_err(dev, "Couldn't lock memory region at 0x%08X\n",
|
||||
(unsigned int)regs_res->start);
|
||||
retval = -EBUSY;
|
||||
goto failed1;
|
||||
}
|
||||
|
||||
/* Fill in configuration data and add them to the list */
|
||||
drvdata->phys_addr = regs_res->start;
|
||||
drvdata->remap_size = remap_size;
|
||||
drvdata->base_address = ioremap(regs_res->start, remap_size);
|
||||
if (drvdata->base_address == NULL) {
|
||||
dev_err(dev, "Couldn't ioremap memory at 0x%08X\n",
|
||||
(unsigned int)regs_res->start);
|
||||
retval = -EFAULT;
|
||||
goto failed2;
|
||||
}
|
||||
|
||||
/* Disable all the interrupts, just in case */
|
||||
out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);
|
||||
|
||||
/* Reset the PS2 device and abort any current transaction, to make sure
|
||||
* we have the PS2 in a good state */
|
||||
out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);
|
||||
|
||||
dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%08X, irq=%d\n",
|
||||
drvdata->phys_addr, (u32)drvdata->base_address, drvdata->irq);
|
||||
|
||||
serio = &drvdata->serio;
|
||||
serio->id.type = SERIO_8042;
|
||||
serio->write = sxps2_write;
|
||||
serio->open = sxps2_open;
|
||||
serio->close = sxps2_close;
|
||||
serio->port_data = drvdata;
|
||||
serio->dev.parent = dev;
|
||||
snprintf(serio->name, sizeof(serio->name),
|
||||
"Xilinx XPS PS/2 at %08X", drvdata->phys_addr);
|
||||
snprintf(serio->phys, sizeof(serio->phys),
|
||||
"xilinxps2/serio at %08X", drvdata->phys_addr);
|
||||
serio_register_port(serio);
|
||||
|
||||
return 0; /* success */
|
||||
|
||||
failed2:
|
||||
release_mem_region(regs_res->start, remap_size);
|
||||
failed1:
|
||||
kfree(drvdata);
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/* OF Platform Bus Support */
|
||||
/***************************/
|
||||
|
||||
static int __devinit xps2_of_probe(struct of_device *ofdev, const struct
|
||||
of_device_id * match)
|
||||
{
|
||||
struct resource r_irq; /* Interrupt resources */
|
||||
struct resource r_mem; /* IO mem resources */
|
||||
int rc = 0;
|
||||
|
||||
printk(KERN_INFO "Device Tree Probing \'%s\'\n",
|
||||
ofdev->node->name);
|
||||
|
||||
/* Get iospace for the device */
|
||||
rc = of_address_to_resource(ofdev->node, 0, &r_mem);
|
||||
if (rc) {
|
||||
dev_err(&ofdev->dev, "invalid address\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Get IRQ for the device */
|
||||
rc = of_irq_to_resource(ofdev->node, 0, &r_irq);
|
||||
if (rc == NO_IRQ) {
|
||||
dev_err(&ofdev->dev, "no IRQ found\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return xps2_setup(&ofdev->dev, &r_mem, &r_irq);
|
||||
}
|
||||
|
||||
static int __devexit xps2_of_remove(struct of_device *of_dev)
|
||||
{
|
||||
struct device *dev = &of_dev->dev;
|
||||
struct xps2data *drvdata;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
drvdata = dev_get_drvdata(dev);
|
||||
|
||||
serio_unregister_port(&drvdata->serio);
|
||||
iounmap(drvdata->base_address);
|
||||
release_mem_region(drvdata->phys_addr, drvdata->remap_size);
|
||||
kfree(drvdata);
|
||||
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/* Match table for of_platform binding */
|
||||
static struct of_device_id xps2_of_match[] __devinitdata = {
|
||||
{ .compatible = "xlnx,xps-ps2-1.00.a", },
|
||||
{ /* end of list */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, xps2_of_match);
|
||||
|
||||
static struct of_platform_driver xps2_of_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.match_table = xps2_of_match,
|
||||
.probe = xps2_of_probe,
|
||||
.remove = __devexit_p(xps2_of_remove),
|
||||
};
|
||||
|
||||
static int __init xps2_init(void)
|
||||
{
|
||||
return of_register_platform_driver(&xps2_of_driver);
|
||||
}
|
||||
|
||||
static void __exit xps2_cleanup(void)
|
||||
{
|
||||
of_unregister_platform_driver(&xps2_of_driver);
|
||||
}
|
||||
|
||||
module_init(xps2_init);
|
||||
module_exit(xps2_cleanup);
|
||||
|
||||
MODULE_AUTHOR("Xilinx, Inc.");
|
||||
MODULE_DESCRIPTION("Xilinx XPS PS/2 driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -73,10 +73,10 @@ static void usb_acecad_irq(struct urb *urb)
|
|||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
/* this urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - urb shutting down with status: %d", __func__, urb->status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - nonzero urb status received: %d", __func__, urb->status);
|
||||
goto resubmit;
|
||||
}
|
||||
|
||||
|
|
|
@ -449,12 +449,12 @@ static void aiptek_irq(struct urb *urb)
|
|||
case -ESHUTDOWN:
|
||||
/* This urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d",
|
||||
__FUNCTION__, urb->status);
|
||||
__func__, urb->status);
|
||||
return;
|
||||
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d",
|
||||
__FUNCTION__, urb->status);
|
||||
__func__, urb->status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -813,7 +813,7 @@ static void aiptek_irq(struct urb *urb)
|
|||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (retval != 0) {
|
||||
err("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -863,7 +863,7 @@ static int gtco_probe(struct usb_interface *usbinterface,
|
|||
gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!gtco->urbinfo) {
|
||||
err("Failed to allocate URB");
|
||||
return -ENOMEM;
|
||||
error = -ENOMEM;
|
||||
goto err_free_buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,10 +56,10 @@ static void kbtab_irq(struct urb *urb)
|
|||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
/* this urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - urb shutting down with status: %d", __func__, urb->status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - nonzero urb status received: %d", __func__, urb->status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ static void kbtab_irq(struct urb *urb)
|
|||
retval = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
err ("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
static struct usb_device_id kbtab_ids[] = {
|
||||
|
|
|
@ -105,7 +105,7 @@ struct wacom {
|
|||
struct urb *irq;
|
||||
struct wacom_wac * wacom_wac;
|
||||
struct mutex lock;
|
||||
int open:1;
|
||||
unsigned int open:1;
|
||||
char phys[32];
|
||||
};
|
||||
|
||||
|
|
|
@ -56,10 +56,10 @@ static void wacom_sys_irq(struct urb *urb)
|
|||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
/* this urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - urb shutting down with status: %d", __func__, urb->status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
|
||||
dbg("%s - nonzero urb status received: %d", __func__, urb->status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ static void wacom_sys_irq(struct urb *urb)
|
|||
retval = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
err ("%s - usb_submit_urb failed with result %d",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
void wacom_report_key(void *wcombo, unsigned int key_type, int key_data)
|
||||
|
|
|
@ -56,7 +56,7 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
|
||||
{
|
||||
unsigned char *data = wacom->data;
|
||||
int prox, id, pressure;
|
||||
int prox, pressure;
|
||||
|
||||
if (data[0] != 2) {
|
||||
dbg("wacom_pl_irq: received unknown report #%d", data[0]);
|
||||
|
@ -65,7 +65,7 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
|
||||
prox = data[1] & 0x40;
|
||||
|
||||
id = ERASER_DEVICE_ID;
|
||||
wacom->id[0] = ERASER_DEVICE_ID;
|
||||
if (prox) {
|
||||
|
||||
pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
|
||||
|
@ -99,10 +99,10 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
if (wacom->tool[1] != BTN_TOOL_RUBBER) {
|
||||
/* Unknown tool selected default to pen tool */
|
||||
wacom->tool[1] = BTN_TOOL_PEN;
|
||||
id = STYLUS_DEVICE_ID;
|
||||
wacom->id[0] = STYLUS_DEVICE_ID;
|
||||
}
|
||||
wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */
|
||||
wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
|
||||
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
|
||||
wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
|
||||
wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
|
||||
wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
|
||||
|
@ -127,7 +127,6 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
|
||||
{
|
||||
unsigned char *data = wacom->data;
|
||||
int id;
|
||||
|
||||
if (data[0] != 2) {
|
||||
printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
|
||||
|
@ -137,13 +136,13 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
if (data[1] & 0x04) {
|
||||
wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20);
|
||||
wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08);
|
||||
id = ERASER_DEVICE_ID;
|
||||
wacom->id[0] = ERASER_DEVICE_ID;
|
||||
} else {
|
||||
wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20);
|
||||
wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
|
||||
id = STYLUS_DEVICE_ID;
|
||||
wacom->id[0] = STYLUS_DEVICE_ID;
|
||||
}
|
||||
wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
|
||||
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
|
||||
wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
|
||||
wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
|
||||
wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
|
||||
|
@ -155,27 +154,26 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
|
||||
{
|
||||
unsigned char *data = wacom->data;
|
||||
int x, y, id, rw;
|
||||
int x, y, rw;
|
||||
|
||||
if (data[0] != 2) {
|
||||
dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
id = STYLUS_DEVICE_ID;
|
||||
if ((data[1] & 0x80) && ((data[1] & 0x07) || data[2] || data[3] || data[4]
|
||||
|| data[5] || data[6] || (data[7] & 0x07))) {
|
||||
if (data[1] & 0x80) {
|
||||
/* in prox and not a pad data */
|
||||
|
||||
switch ((data[1] >> 5) & 3) {
|
||||
|
||||
case 0: /* Pen */
|
||||
wacom->tool[0] = BTN_TOOL_PEN;
|
||||
wacom->id[0] = STYLUS_DEVICE_ID;
|
||||
break;
|
||||
|
||||
case 1: /* Rubber */
|
||||
wacom->tool[0] = BTN_TOOL_RUBBER;
|
||||
id = ERASER_DEVICE_ID;
|
||||
wacom->id[0] = ERASER_DEVICE_ID;
|
||||
break;
|
||||
|
||||
case 2: /* Mouse with wheel */
|
||||
|
@ -190,7 +188,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
|
||||
case 3: /* Mouse without wheel */
|
||||
wacom->tool[0] = BTN_TOOL_MOUSE;
|
||||
id = CURSOR_DEVICE_ID;
|
||||
wacom->id[0] = CURSOR_DEVICE_ID;
|
||||
wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
|
||||
wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
|
||||
if (wacom->features->type == WACOM_G4 ||
|
||||
|
@ -210,9 +208,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
|
||||
wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
|
||||
}
|
||||
wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
|
||||
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
|
||||
wacom_report_key(wcombo, wacom->tool[0], 1);
|
||||
} else if (!(data[1] & 0x90)) {
|
||||
} else if (wacom->id[0]) {
|
||||
wacom_report_abs(wcombo, ABS_X, 0);
|
||||
wacom_report_abs(wcombo, ABS_Y, 0);
|
||||
if (wacom->tool[0] == BTN_TOOL_MOUSE) {
|
||||
|
@ -225,6 +223,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
wacom_report_key(wcombo, BTN_STYLUS, 0);
|
||||
wacom_report_key(wcombo, BTN_STYLUS2, 0);
|
||||
}
|
||||
wacom->id[0] = 0;
|
||||
wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
|
||||
wacom_report_key(wcombo, wacom->tool[0], 0);
|
||||
}
|
||||
|
@ -234,13 +233,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
case WACOM_G4:
|
||||
if (data[7] & 0xf8) {
|
||||
wacom_input_sync(wcombo); /* sync last event */
|
||||
wacom->id[1] = 1;
|
||||
wacom->id[1] = PAD_DEVICE_ID;
|
||||
wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
|
||||
wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
|
||||
rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
|
||||
wacom_report_rel(wcombo, REL_WHEEL, rw);
|
||||
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
|
||||
wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
|
||||
wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
|
||||
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
|
||||
} else if (wacom->id[1]) {
|
||||
wacom_input_sync(wcombo); /* sync last event */
|
||||
|
@ -255,14 +254,14 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
|
|||
case WACOM_MO:
|
||||
if ((data[7] & 0xf8) || (data[8] & 0xff)) {
|
||||
wacom_input_sync(wcombo); /* sync last event */
|
||||
wacom->id[1] = 1;
|
||||
wacom->id[1] = PAD_DEVICE_ID;
|
||||
wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
|
||||
wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
|
||||
wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
|
||||
wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
|
||||
wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
|
||||
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
|
||||
wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
|
||||
wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
|
||||
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
|
||||
} else if (wacom->id[1]) {
|
||||
wacom_input_sync(wcombo); /* sync last event */
|
||||
|
|
|
@ -103,6 +103,18 @@ config TOUCHSCREEN_MTOUCH
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called mtouch.
|
||||
|
||||
config TOUCHSCREEN_INEXIO
|
||||
tristate "iNexio serial touchscreens"
|
||||
select SERIO
|
||||
help
|
||||
Say Y here if you have an iNexio serial touchscreen connected to
|
||||
your system.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called inexio.
|
||||
|
||||
config TOUCHSCREEN_MK712
|
||||
tristate "ICS MicroClock MK712 touchscreen"
|
||||
help
|
||||
|
@ -134,6 +146,18 @@ config TOUCHSCREEN_HP7XX
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called jornada720_ts.
|
||||
|
||||
config TOUCHSCREEN_HTCPEN
|
||||
tristate "HTC Shift X9500 touchscreen"
|
||||
depends on ISA
|
||||
help
|
||||
Say Y here if you have an HTC Shift UMPC also known as HTC X9500
|
||||
Clio / Shangrila and want to support the built-in touchscreen.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called htcpen.
|
||||
|
||||
config TOUCHSCREEN_PENMOUNT
|
||||
tristate "Penmount serial touchscreen"
|
||||
select SERIO
|
||||
|
@ -146,6 +170,17 @@ config TOUCHSCREEN_PENMOUNT
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called penmount.
|
||||
|
||||
config TOUCHSCREEN_MIGOR
|
||||
tristate "Renesas MIGO-R touchscreen"
|
||||
depends on SH_MIGOR && I2C
|
||||
help
|
||||
Say Y here to enable MIGO-R touchscreen support.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called migor_ts.
|
||||
|
||||
config TOUCHSCREEN_TOUCHRIGHT
|
||||
tristate "Touchright serial touchscreen"
|
||||
select SERIO
|
||||
|
@ -316,4 +351,15 @@ config TOUCHSCREEN_USB_GOTOP
|
|||
bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
|
||||
depends on TOUCHSCREEN_USB_COMPOSITE
|
||||
|
||||
config TOUCHSCREEN_TOUCHIT213
|
||||
tristate "Sahara TouchIT-213 touchscreen"
|
||||
select SERIO
|
||||
help
|
||||
Say Y here if you have a Sahara TouchIT-213 Tablet PC.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called touchit213.
|
||||
|
||||
endif
|
||||
|
|
|
@ -12,12 +12,16 @@ obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
|
|||
obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: gunze.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $
|
||||
*
|
||||
* Copyright (c) 2000-2001 Vojtech Pavlik
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $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
|
||||
*
|
||||
* Sponsored by Transvirtual Technology.
|
||||
|
|
255
drivers/input/touchscreen/htcpen.c
Normal file
255
drivers/input/touchscreen/htcpen.c
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* HTC Shift touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2008 Pau Oliva Fora <pof@eslack.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
MODULE_AUTHOR("Pau Oliva Fora <pau@eslack.org>");
|
||||
MODULE_DESCRIPTION("HTC Shift touchscreen driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define HTCPEN_PORT_IRQ_CLEAR 0x068
|
||||
#define HTCPEN_PORT_INIT 0x06c
|
||||
#define HTCPEN_PORT_INDEX 0x0250
|
||||
#define HTCPEN_PORT_DATA 0x0251
|
||||
#define HTCPEN_IRQ 3
|
||||
|
||||
#define DEVICE_ENABLE 0xa2
|
||||
#define DEVICE_DISABLE 0xa3
|
||||
|
||||
#define X_INDEX 3
|
||||
#define Y_INDEX 5
|
||||
#define TOUCH_INDEX 0xb
|
||||
#define LSB_XY_INDEX 0xc
|
||||
#define X_AXIS_MAX 2040
|
||||
#define Y_AXIS_MAX 2040
|
||||
|
||||
static int invert_x;
|
||||
module_param(invert_x, bool, 0644);
|
||||
MODULE_PARM_DESC(invert_x, "If set, X axis is inverted");
|
||||
static int invert_y;
|
||||
module_param(invert_y, bool, 0644);
|
||||
MODULE_PARM_DESC(invert_y, "If set, Y axis is inverted");
|
||||
|
||||
static struct pnp_device_id pnp_ids[] = {
|
||||
{ .id = "PNP0cc0" },
|
||||
{ .id = "" }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pnp, pnp_ids);
|
||||
|
||||
static irqreturn_t htcpen_interrupt(int irq, void *handle)
|
||||
{
|
||||
struct input_dev *htcpen_dev = handle;
|
||||
unsigned short x, y, xy;
|
||||
|
||||
/* 0 = press; 1 = release */
|
||||
outb_p(TOUCH_INDEX, HTCPEN_PORT_INDEX);
|
||||
|
||||
if (inb_p(HTCPEN_PORT_DATA)) {
|
||||
input_report_key(htcpen_dev, BTN_TOUCH, 0);
|
||||
} else {
|
||||
outb_p(X_INDEX, HTCPEN_PORT_INDEX);
|
||||
x = inb_p(HTCPEN_PORT_DATA);
|
||||
|
||||
outb_p(Y_INDEX, HTCPEN_PORT_INDEX);
|
||||
y = inb_p(HTCPEN_PORT_DATA);
|
||||
|
||||
outb_p(LSB_XY_INDEX, HTCPEN_PORT_INDEX);
|
||||
xy = inb_p(HTCPEN_PORT_DATA);
|
||||
|
||||
/* get high resolution value of X and Y using LSB */
|
||||
x = X_AXIS_MAX - ((x * 8) + ((xy >> 4) & 0xf));
|
||||
y = (y * 8) + (xy & 0xf);
|
||||
if (invert_x)
|
||||
x = X_AXIS_MAX - x;
|
||||
if (invert_y)
|
||||
y = Y_AXIS_MAX - y;
|
||||
|
||||
if (x != X_AXIS_MAX && x != 0) {
|
||||
input_report_key(htcpen_dev, BTN_TOUCH, 1);
|
||||
input_report_abs(htcpen_dev, ABS_X, x);
|
||||
input_report_abs(htcpen_dev, ABS_Y, y);
|
||||
}
|
||||
}
|
||||
|
||||
input_sync(htcpen_dev);
|
||||
|
||||
inb_p(HTCPEN_PORT_IRQ_CLEAR);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int htcpen_open(struct input_dev *dev)
|
||||
{
|
||||
outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void htcpen_close(struct input_dev *dev)
|
||||
{
|
||||
outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT);
|
||||
synchronize_irq(HTCPEN_IRQ);
|
||||
}
|
||||
|
||||
static int __devinit htcpen_isa_probe(struct device *dev, unsigned int id)
|
||||
{
|
||||
struct input_dev *htcpen_dev;
|
||||
int err = -EBUSY;
|
||||
|
||||
if (!request_region(HTCPEN_PORT_IRQ_CLEAR, 1, "htcpen")) {
|
||||
printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
|
||||
HTCPEN_PORT_IRQ_CLEAR);
|
||||
goto request_region1_failed;
|
||||
}
|
||||
|
||||
if (!request_region(HTCPEN_PORT_INIT, 1, "htcpen")) {
|
||||
printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
|
||||
HTCPEN_PORT_INIT);
|
||||
goto request_region2_failed;
|
||||
}
|
||||
|
||||
if (!request_region(HTCPEN_PORT_INDEX, 2, "htcpen")) {
|
||||
printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
|
||||
HTCPEN_PORT_INDEX);
|
||||
goto request_region3_failed;
|
||||
}
|
||||
|
||||
htcpen_dev = input_allocate_device();
|
||||
if (!htcpen_dev) {
|
||||
printk(KERN_ERR "htcpen: can't allocate device\n");
|
||||
err = -ENOMEM;
|
||||
goto input_alloc_failed;
|
||||
}
|
||||
|
||||
htcpen_dev->name = "HTC Shift EC TouchScreen";
|
||||
htcpen_dev->id.bustype = BUS_ISA;
|
||||
|
||||
htcpen_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
|
||||
htcpen_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
input_set_abs_params(htcpen_dev, ABS_X, 0, X_AXIS_MAX, 0, 0);
|
||||
input_set_abs_params(htcpen_dev, ABS_Y, 0, Y_AXIS_MAX, 0, 0);
|
||||
|
||||
htcpen_dev->open = htcpen_open;
|
||||
htcpen_dev->close = htcpen_close;
|
||||
|
||||
err = request_irq(HTCPEN_IRQ, htcpen_interrupt, 0, "htcpen",
|
||||
htcpen_dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "htcpen: irq busy\n");
|
||||
goto request_irq_failed;
|
||||
}
|
||||
|
||||
inb_p(HTCPEN_PORT_IRQ_CLEAR);
|
||||
|
||||
err = input_register_device(htcpen_dev);
|
||||
if (err)
|
||||
goto input_register_failed;
|
||||
|
||||
dev_set_drvdata(dev, htcpen_dev);
|
||||
|
||||
return 0;
|
||||
|
||||
input_register_failed:
|
||||
free_irq(HTCPEN_IRQ, htcpen_dev);
|
||||
request_irq_failed:
|
||||
input_free_device(htcpen_dev);
|
||||
input_alloc_failed:
|
||||
release_region(HTCPEN_PORT_INDEX, 2);
|
||||
request_region3_failed:
|
||||
release_region(HTCPEN_PORT_INIT, 1);
|
||||
request_region2_failed:
|
||||
release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
|
||||
request_region1_failed:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit htcpen_isa_remove(struct device *dev, unsigned int id)
|
||||
{
|
||||
struct input_dev *htcpen_dev = dev_get_drvdata(dev);
|
||||
|
||||
input_unregister_device(htcpen_dev);
|
||||
|
||||
free_irq(HTCPEN_IRQ, htcpen_dev);
|
||||
|
||||
release_region(HTCPEN_PORT_INDEX, 2);
|
||||
release_region(HTCPEN_PORT_INIT, 1);
|
||||
release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
|
||||
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int htcpen_isa_suspend(struct device *dev, unsigned int n,
|
||||
pm_message_t state)
|
||||
{
|
||||
outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int htcpen_isa_resume(struct device *dev, unsigned int n)
|
||||
{
|
||||
outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct isa_driver htcpen_isa_driver = {
|
||||
.probe = htcpen_isa_probe,
|
||||
.remove = __devexit_p(htcpen_isa_remove),
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = htcpen_isa_suspend,
|
||||
.resume = htcpen_isa_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "htcpen",
|
||||
}
|
||||
};
|
||||
|
||||
static struct dmi_system_id __initdata htcshift_dmi_table[] = {
|
||||
{
|
||||
.ident = "Shift",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "High Tech Computer Corp"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Shift"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static int __init htcpen_isa_init(void)
|
||||
{
|
||||
if (!dmi_check_system(htcshift_dmi_table))
|
||||
return -ENODEV;
|
||||
|
||||
return isa_register_driver(&htcpen_isa_driver, 1);
|
||||
}
|
||||
|
||||
static void __exit htcpen_isa_exit(void)
|
||||
{
|
||||
isa_unregister_driver(&htcpen_isa_driver);
|
||||
}
|
||||
|
||||
module_init(htcpen_isa_init);
|
||||
module_exit(htcpen_isa_exit);
|
207
drivers/input/touchscreen/inexio.c
Normal file
207
drivers/input/touchscreen/inexio.c
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* iNexio serial touchscreen driver
|
||||
*
|
||||
* Copyright (c) 2008 Richard Lemon
|
||||
* Based on the mtouch driver (c) Vojtech Pavlik and Dan Streetman
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 2008/06/19 Richard Lemon <richard@codelemon.com>
|
||||
* Copied mtouch.c and edited for iNexio protocol
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#define DRIVER_DESC "iNexio serial touchscreen driver"
|
||||
|
||||
MODULE_AUTHOR("Richard Lemon <richard@codelemon.com>");
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
* Definitions & global arrays.
|
||||
*/
|
||||
|
||||
#define INEXIO_FORMAT_TOUCH_BIT 0x01
|
||||
#define INEXIO_FORMAT_LENGTH 5
|
||||
#define INEXIO_RESPONSE_BEGIN_BYTE 0x80
|
||||
|
||||
/* todo: check specs for max length of all responses */
|
||||
#define INEXIO_MAX_LENGTH 16
|
||||
|
||||
#define INEXIO_MIN_XC 0
|
||||
#define INEXIO_MAX_XC 0x3fff
|
||||
#define INEXIO_MIN_YC 0
|
||||
#define INEXIO_MAX_YC 0x3fff
|
||||
|
||||
#define INEXIO_GET_XC(data) (((data[1])<<7) | data[2])
|
||||
#define INEXIO_GET_YC(data) (((data[3])<<7) | data[4])
|
||||
#define INEXIO_GET_TOUCHED(data) (INEXIO_FORMAT_TOUCH_BIT & data[0])
|
||||
|
||||
/*
|
||||
* Per-touchscreen data.
|
||||
*/
|
||||
|
||||
struct inexio {
|
||||
struct input_dev *dev;
|
||||
struct serio *serio;
|
||||
int idx;
|
||||
unsigned char data[INEXIO_MAX_LENGTH];
|
||||
char phys[32];
|
||||
};
|
||||
|
||||
static void inexio_process_data(struct inexio *pinexio)
|
||||
{
|
||||
struct input_dev *dev = pinexio->dev;
|
||||
|
||||
if (INEXIO_FORMAT_LENGTH == ++pinexio->idx) {
|
||||
input_report_abs(dev, ABS_X, INEXIO_GET_XC(pinexio->data));
|
||||
input_report_abs(dev, ABS_Y, INEXIO_GET_YC(pinexio->data));
|
||||
input_report_key(dev, BTN_TOUCH, INEXIO_GET_TOUCHED(pinexio->data));
|
||||
input_sync(dev);
|
||||
|
||||
pinexio->idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t inexio_interrupt(struct serio *serio,
|
||||
unsigned char data, unsigned int flags)
|
||||
{
|
||||
struct inexio* pinexio = serio_get_drvdata(serio);
|
||||
|
||||
pinexio->data[pinexio->idx] = data;
|
||||
|
||||
if (INEXIO_RESPONSE_BEGIN_BYTE&pinexio->data[0])
|
||||
inexio_process_data(pinexio);
|
||||
else
|
||||
printk(KERN_DEBUG "inexio.c: unknown/unsynchronized data from device, byte %x\n",pinexio->data[0]);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* inexio_disconnect() is the opposite of inexio_connect()
|
||||
*/
|
||||
|
||||
static void inexio_disconnect(struct serio *serio)
|
||||
{
|
||||
struct inexio* pinexio = serio_get_drvdata(serio);
|
||||
|
||||
input_get_device(pinexio->dev);
|
||||
input_unregister_device(pinexio->dev);
|
||||
serio_close(serio);
|
||||
serio_set_drvdata(serio, NULL);
|
||||
input_put_device(pinexio->dev);
|
||||
kfree(pinexio);
|
||||
}
|
||||
|
||||
/*
|
||||
* inexio_connect() is the routine that is called when someone adds a
|
||||
* new serio device that supports iNexio protocol and registers it as
|
||||
* an input device. This is usually accomplished using inputattach.
|
||||
*/
|
||||
|
||||
static int inexio_connect(struct serio *serio, struct serio_driver *drv)
|
||||
{
|
||||
struct inexio *pinexio;
|
||||
struct input_dev *input_dev;
|
||||
int err;
|
||||
|
||||
pinexio = kzalloc(sizeof(struct inexio), GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!pinexio || !input_dev) {
|
||||
err = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
pinexio->serio = serio;
|
||||
pinexio->dev = input_dev;
|
||||
snprintf(pinexio->phys, sizeof(pinexio->phys), "%s/input0", serio->phys);
|
||||
|
||||
input_dev->name = "iNexio Serial TouchScreen";
|
||||
input_dev->phys = pinexio->phys;
|
||||
input_dev->id.bustype = BUS_RS232;
|
||||
input_dev->id.vendor = SERIO_INEXIO;
|
||||
input_dev->id.product = 0;
|
||||
input_dev->id.version = 0x0001;
|
||||
input_dev->dev.parent = &serio->dev;
|
||||
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
||||
input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
input_set_abs_params(pinexio->dev, ABS_X, INEXIO_MIN_XC, INEXIO_MAX_XC, 0, 0);
|
||||
input_set_abs_params(pinexio->dev, ABS_Y, INEXIO_MIN_YC, INEXIO_MAX_YC, 0, 0);
|
||||
|
||||
serio_set_drvdata(serio, pinexio);
|
||||
|
||||
err = serio_open(serio, drv);
|
||||
if (err)
|
||||
goto fail2;
|
||||
|
||||
err = input_register_device(pinexio->dev);
|
||||
if (err)
|
||||
goto fail3;
|
||||
|
||||
return 0;
|
||||
|
||||
fail3: serio_close(serio);
|
||||
fail2: serio_set_drvdata(serio, NULL);
|
||||
fail1: input_free_device(input_dev);
|
||||
kfree(pinexio);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* The serio driver structure.
|
||||
*/
|
||||
|
||||
static struct serio_device_id inexio_serio_ids[] = {
|
||||
{
|
||||
.type = SERIO_RS232,
|
||||
.proto = SERIO_INEXIO,
|
||||
.id = SERIO_ANY,
|
||||
.extra = SERIO_ANY,
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(serio, inexio_serio_ids);
|
||||
|
||||
static struct serio_driver inexio_drv = {
|
||||
.driver = {
|
||||
.name = "inexio",
|
||||
},
|
||||
.description = DRIVER_DESC,
|
||||
.id_table = inexio_serio_ids,
|
||||
.interrupt = inexio_interrupt,
|
||||
.connect = inexio_connect,
|
||||
.disconnect = inexio_disconnect,
|
||||
};
|
||||
|
||||
/*
|
||||
* The functions for inserting/removing us as a module.
|
||||
*/
|
||||
|
||||
static int __init inexio_init(void)
|
||||
{
|
||||
return serio_register_driver(&inexio_drv);
|
||||
}
|
||||
|
||||
static void __exit inexio_exit(void)
|
||||
{
|
||||
serio_unregister_driver(&inexio_drv);
|
||||
}
|
||||
|
||||
module_init(inexio_init);
|
||||
module_exit(inexio_exit);
|
250
drivers/input/touchscreen/migor_ts.c
Normal file
250
drivers/input/touchscreen/migor_ts.c
Normal file
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* Touch Screen driver for Renesas MIGO-R Platform
|
||||
*
|
||||
* Copyright (c) 2008 Magnus Damm
|
||||
* Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>,
|
||||
* Kenati Technologies Pvt Ltd.
|
||||
*
|
||||
* This file 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 (at your option) any later version.
|
||||
*
|
||||
* This file 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 library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#define EVENT_PENDOWN 1
|
||||
#define EVENT_REPEAT 2
|
||||
#define EVENT_PENUP 3
|
||||
|
||||
struct migor_ts_priv {
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input;
|
||||
struct delayed_work work;
|
||||
int irq;
|
||||
};
|
||||
|
||||
static const u_int8_t migor_ts_ena_seq[17] = { 0x33, 0x22, 0x11,
|
||||
0x01, 0x06, 0x07, };
|
||||
static const u_int8_t migor_ts_dis_seq[17] = { };
|
||||
|
||||
static void migor_ts_poscheck(struct work_struct *work)
|
||||
{
|
||||
struct migor_ts_priv *priv = container_of(work,
|
||||
struct migor_ts_priv,
|
||||
work.work);
|
||||
unsigned short xpos, ypos;
|
||||
unsigned char event;
|
||||
u_int8_t buf[16];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
/* Set Index 0 */
|
||||
buf[0] = 0;
|
||||
if (i2c_master_send(priv->client, buf, 1) != 1) {
|
||||
dev_err(&priv->client->dev, "Unable to write i2c index\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Now do Page Read */
|
||||
if (i2c_master_recv(priv->client, buf, sizeof(buf)) != sizeof(buf)) {
|
||||
dev_err(&priv->client->dev, "Unable to read i2c page\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ypos = ((buf[9] & 0x03) << 8 | buf[8]);
|
||||
xpos = ((buf[11] & 0x03) << 8 | buf[10]);
|
||||
event = buf[12];
|
||||
|
||||
if (event == EVENT_PENDOWN || event == EVENT_REPEAT) {
|
||||
input_report_key(priv->input, BTN_TOUCH, 1);
|
||||
input_report_abs(priv->input, ABS_X, ypos); /*X-Y swap*/
|
||||
input_report_abs(priv->input, ABS_Y, xpos);
|
||||
input_sync(priv->input);
|
||||
} else if (event == EVENT_PENUP) {
|
||||
input_report_key(priv->input, BTN_TOUCH, 0);
|
||||
input_sync(priv->input);
|
||||
}
|
||||
out:
|
||||
enable_irq(priv->irq);
|
||||
}
|
||||
|
||||
static irqreturn_t migor_ts_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct migor_ts_priv *priv = dev_id;
|
||||
|
||||
/* the touch screen controller chip is hooked up to the cpu
|
||||
* using i2c and a single interrupt line. the interrupt line
|
||||
* is pulled low whenever someone taps the screen. to deassert
|
||||
* the interrupt line we need to acknowledge the interrupt by
|
||||
* communicating with the controller over the slow i2c bus.
|
||||
*
|
||||
* we can't acknowledge from interrupt context since the i2c
|
||||
* bus controller may sleep, so we just disable the interrupt
|
||||
* here and handle the acknowledge using delayed work.
|
||||
*/
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
schedule_delayed_work(&priv->work, HZ / 20);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static int migor_ts_open(struct input_dev *dev)
|
||||
{
|
||||
struct migor_ts_priv *priv = input_get_drvdata(dev);
|
||||
struct i2c_client *client = priv->client;
|
||||
int count;
|
||||
|
||||
/* enable controller */
|
||||
count = i2c_master_send(client, migor_ts_ena_seq,
|
||||
sizeof(migor_ts_ena_seq));
|
||||
if (count != sizeof(migor_ts_ena_seq)) {
|
||||
dev_err(&client->dev, "Unable to enable touchscreen.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void migor_ts_close(struct input_dev *dev)
|
||||
{
|
||||
struct migor_ts_priv *priv = input_get_drvdata(dev);
|
||||
struct i2c_client *client = priv->client;
|
||||
|
||||
disable_irq(priv->irq);
|
||||
|
||||
/* cancel pending work and wait for migor_ts_poscheck() to finish */
|
||||
if (cancel_delayed_work_sync(&priv->work)) {
|
||||
/*
|
||||
* if migor_ts_poscheck was canceled we need to enable IRQ
|
||||
* here to balance disable done in migor_ts_isr.
|
||||
*/
|
||||
enable_irq(priv->irq);
|
||||
}
|
||||
|
||||
/* disable controller */
|
||||
i2c_master_send(client, migor_ts_dis_seq, sizeof(migor_ts_dis_seq));
|
||||
|
||||
enable_irq(priv->irq);
|
||||
}
|
||||
|
||||
static int migor_ts_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *idp)
|
||||
{
|
||||
struct migor_ts_priv *priv;
|
||||
struct input_dev *input;
|
||||
int error;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
dev_err(&client->dev, "failed to allocate driver data\n");
|
||||
error = -ENOMEM;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&client->dev, priv);
|
||||
|
||||
input = input_allocate_device();
|
||||
if (!input) {
|
||||
dev_err(&client->dev, "Failed to allocate input device.\n");
|
||||
error = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
||||
input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
|
||||
input_set_abs_params(input, ABS_X, 95, 955, 0, 0);
|
||||
input_set_abs_params(input, ABS_Y, 85, 935, 0, 0);
|
||||
|
||||
input->name = client->driver_name;
|
||||
input->id.bustype = BUS_I2C;
|
||||
input->dev.parent = &client->dev;
|
||||
|
||||
input->open = migor_ts_open;
|
||||
input->close = migor_ts_close;
|
||||
|
||||
input_set_drvdata(input, priv);
|
||||
|
||||
priv->client = client;
|
||||
priv->input = input;
|
||||
INIT_DELAYED_WORK(&priv->work, migor_ts_poscheck);
|
||||
priv->irq = client->irq;
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error)
|
||||
goto err1;
|
||||
|
||||
error = request_irq(priv->irq, migor_ts_isr, IRQF_TRIGGER_LOW,
|
||||
client->driver_name, priv);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
input_unregister_device(input);
|
||||
input = NULL; /* so we dont try to free it below */
|
||||
err1:
|
||||
input_free_device(input);
|
||||
kfree(priv);
|
||||
err0:
|
||||
dev_set_drvdata(&client->dev, NULL);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int migor_ts_remove(struct i2c_client *client)
|
||||
{
|
||||
struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
|
||||
|
||||
free_irq(priv->irq, priv);
|
||||
input_unregister_device(priv->input);
|
||||
kfree(priv);
|
||||
|
||||
dev_set_drvdata(&client->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver migor_ts_driver = {
|
||||
.driver = {
|
||||
.name = "migor_ts",
|
||||
},
|
||||
.probe = migor_ts_probe,
|
||||
.remove = migor_ts_remove,
|
||||
};
|
||||
|
||||
static int __init migor_ts_init(void)
|
||||
{
|
||||
return i2c_add_driver(&migor_ts_driver);
|
||||
}
|
||||
|
||||
static void __exit migor_ts_exit(void)
|
||||
{
|
||||
i2c_del_driver(&migor_ts_driver);
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("MigoR Touchscreen driver");
|
||||
MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(migor_ts_init);
|
||||
module_exit(migor_ts_exit);
|
234
drivers/input/touchscreen/touchit213.c
Normal file
234
drivers/input/touchscreen/touchit213.c
Normal file
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* Sahara TouchIT-213 serial touchscreen driver
|
||||
*
|
||||
* Copyright (c) 2007-2008 Claudio Nieder <private@claudio.ch>
|
||||
*
|
||||
* Based on Touchright driver (drivers/input/touchscreen/touchright.c)
|
||||
* Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
|
||||
* Copyright (c) 2004 Vojtech Pavlik
|
||||
* and Dan Streetman <ddstreet@ieee.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#define DRIVER_DESC "Sahara TouchIT-213 serial touchscreen driver"
|
||||
|
||||
MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>");
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
* Definitions & global arrays.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Data is received through COM1 at 9600bit/s,8bit,no parity in packets
|
||||
* of 5 byte each.
|
||||
*
|
||||
* +--------+ +--------+ +--------+ +--------+ +--------+
|
||||
* |1000000p| |0xxxxxxx| |0xxxxxxx| |0yyyyyyy| |0yyyyyyy|
|
||||
* +--------+ +--------+ +--------+ +--------+ +--------+
|
||||
* MSB LSB MSB LSB
|
||||
*
|
||||
* The value of p is 1 as long as the screen is touched and 0 when
|
||||
* reporting the location where touching stopped, e.g. where the pen was
|
||||
* lifted from the screen.
|
||||
*
|
||||
* When holding the screen in landscape mode as the BIOS text output is
|
||||
* presented, x is the horizontal axis with values growing from left to
|
||||
* right and y is the vertical axis with values growing from top to
|
||||
* bottom.
|
||||
*
|
||||
* When holding the screen in portrait mode with the Sahara logo in its
|
||||
* correct position, x ist the vertical axis with values growing from
|
||||
* top to bottom and y is the horizontal axis with values growing from
|
||||
* right to left.
|
||||
*/
|
||||
|
||||
#define T213_FORMAT_TOUCH_BIT 0x01
|
||||
#define T213_FORMAT_STATUS_BYTE 0x80
|
||||
#define T213_FORMAT_STATUS_MASK ~T213_FORMAT_TOUCH_BIT
|
||||
|
||||
/*
|
||||
* On my Sahara Touch-IT 213 I have observed x values from 0 to 0x7f0
|
||||
* and y values from 0x1d to 0x7e9, so the actual measurement is
|
||||
* probably done with an 11 bit precision.
|
||||
*/
|
||||
#define T213_MIN_XC 0
|
||||
#define T213_MAX_XC 0x07ff
|
||||
#define T213_MIN_YC 0
|
||||
#define T213_MAX_YC 0x07ff
|
||||
|
||||
/*
|
||||
* Per-touchscreen data.
|
||||
*/
|
||||
|
||||
struct touchit213 {
|
||||
struct input_dev *dev;
|
||||
struct serio *serio;
|
||||
int idx;
|
||||
unsigned char csum;
|
||||
unsigned char data[5];
|
||||
char phys[32];
|
||||
};
|
||||
|
||||
static irqreturn_t touchit213_interrupt(struct serio *serio,
|
||||
unsigned char data, unsigned int flags)
|
||||
{
|
||||
struct touchit213 *touchit213 = serio_get_drvdata(serio);
|
||||
struct input_dev *dev = touchit213->dev;
|
||||
|
||||
touchit213->data[touchit213->idx] = data;
|
||||
|
||||
switch (touchit213->idx++) {
|
||||
case 0:
|
||||
if ((touchit213->data[0] & T213_FORMAT_STATUS_MASK) !=
|
||||
T213_FORMAT_STATUS_BYTE) {
|
||||
pr_debug("unsynchronized data: 0x%02x\n", data);
|
||||
touchit213->idx = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
touchit213->idx = 0;
|
||||
input_report_abs(dev, ABS_X,
|
||||
(touchit213->data[1] << 7) | touchit213->data[2]);
|
||||
input_report_abs(dev, ABS_Y,
|
||||
(touchit213->data[3] << 7) | touchit213->data[4]);
|
||||
input_report_key(dev, BTN_TOUCH,
|
||||
touchit213->data[0] & T213_FORMAT_TOUCH_BIT);
|
||||
input_sync(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* touchit213_disconnect() is the opposite of touchit213_connect()
|
||||
*/
|
||||
|
||||
static void touchit213_disconnect(struct serio *serio)
|
||||
{
|
||||
struct touchit213 *touchit213 = serio_get_drvdata(serio);
|
||||
|
||||
input_get_device(touchit213->dev);
|
||||
input_unregister_device(touchit213->dev);
|
||||
serio_close(serio);
|
||||
serio_set_drvdata(serio, NULL);
|
||||
input_put_device(touchit213->dev);
|
||||
kfree(touchit213);
|
||||
}
|
||||
|
||||
/*
|
||||
* touchit213_connect() is the routine that is called when someone adds a
|
||||
* new serio device that supports the Touchright protocol and registers it as
|
||||
* an input device.
|
||||
*/
|
||||
|
||||
static int touchit213_connect(struct serio *serio, struct serio_driver *drv)
|
||||
{
|
||||
struct touchit213 *touchit213;
|
||||
struct input_dev *input_dev;
|
||||
int err;
|
||||
|
||||
touchit213 = kzalloc(sizeof(struct touchit213), GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!touchit213 || !input_dev) {
|
||||
err = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
touchit213->serio = serio;
|
||||
touchit213->dev = input_dev;
|
||||
snprintf(touchit213->phys, sizeof(touchit213->phys),
|
||||
"%s/input0", serio->phys);
|
||||
|
||||
input_dev->name = "Sahara Touch-iT213 Serial TouchScreen";
|
||||
input_dev->phys = touchit213->phys;
|
||||
input_dev->id.bustype = BUS_RS232;
|
||||
input_dev->id.vendor = SERIO_TOUCHIT213;
|
||||
input_dev->id.product = 0;
|
||||
input_dev->id.version = 0x0100;
|
||||
input_dev->dev.parent = &serio->dev;
|
||||
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
||||
input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
input_set_abs_params(touchit213->dev, ABS_X,
|
||||
T213_MIN_XC, T213_MAX_XC, 0, 0);
|
||||
input_set_abs_params(touchit213->dev, ABS_Y,
|
||||
T213_MIN_YC, T213_MAX_YC, 0, 0);
|
||||
|
||||
serio_set_drvdata(serio, touchit213);
|
||||
|
||||
err = serio_open(serio, drv);
|
||||
if (err)
|
||||
goto fail2;
|
||||
|
||||
err = input_register_device(touchit213->dev);
|
||||
if (err)
|
||||
goto fail3;
|
||||
|
||||
return 0;
|
||||
|
||||
fail3: serio_close(serio);
|
||||
fail2: serio_set_drvdata(serio, NULL);
|
||||
fail1: input_free_device(input_dev);
|
||||
kfree(touchit213);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* The serio driver structure.
|
||||
*/
|
||||
|
||||
static struct serio_device_id touchit213_serio_ids[] = {
|
||||
{
|
||||
.type = SERIO_RS232,
|
||||
.proto = SERIO_TOUCHIT213,
|
||||
.id = SERIO_ANY,
|
||||
.extra = SERIO_ANY,
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(serio, touchit213_serio_ids);
|
||||
|
||||
static struct serio_driver touchit213_drv = {
|
||||
.driver = {
|
||||
.name = "touchit213",
|
||||
},
|
||||
.description = DRIVER_DESC,
|
||||
.id_table = touchit213_serio_ids,
|
||||
.interrupt = touchit213_interrupt,
|
||||
.connect = touchit213_connect,
|
||||
.disconnect = touchit213_disconnect,
|
||||
};
|
||||
|
||||
/*
|
||||
* The functions for inserting/removing us as a module.
|
||||
*/
|
||||
|
||||
static int __init touchit213_init(void)
|
||||
{
|
||||
return serio_register_driver(&touchit213_drv);
|
||||
}
|
||||
|
||||
static void __exit touchit213_exit(void)
|
||||
{
|
||||
serio_unregister_driver(&touchit213_drv);
|
||||
}
|
||||
|
||||
module_init(touchit213_init);
|
||||
module_exit(touchit213_exit);
|
|
@ -49,6 +49,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/input.h>
|
||||
#include <linux/hid.h>
|
||||
|
||||
|
||||
#define DRIVER_VERSION "v0.6"
|
||||
|
@ -101,7 +102,7 @@ struct usbtouch_usb {
|
|||
|
||||
/* device types */
|
||||
enum {
|
||||
DEVTPYE_DUMMY = -1,
|
||||
DEVTYPE_IGNORE = -1,
|
||||
DEVTYPE_EGALAX,
|
||||
DEVTYPE_PANJIT,
|
||||
DEVTYPE_3M,
|
||||
|
@ -115,8 +116,21 @@ enum {
|
|||
DEVTYPE_GOTOP,
|
||||
};
|
||||
|
||||
#define USB_DEVICE_HID_CLASS(vend, prod) \
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \
|
||||
| USB_DEVICE_ID_MATCH_DEVICE, \
|
||||
.idVendor = (vend), \
|
||||
.idProduct = (prod), \
|
||||
.bInterfaceClass = USB_INTERFACE_CLASS_HID, \
|
||||
.bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE
|
||||
|
||||
static struct usb_device_id usbtouch_devices[] = {
|
||||
#ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
|
||||
/* ignore the HID capable devices, handled by usbhid */
|
||||
{USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE},
|
||||
{USB_DEVICE_HID_CLASS(0x0eef, 0x0002), .driver_info = DEVTYPE_IGNORE},
|
||||
|
||||
/* normal device IDs */
|
||||
{USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
|
||||
{USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX},
|
||||
{USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
|
||||
|
@ -262,7 +276,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
|
|||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||
dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
|
||||
__FUNCTION__, ret);
|
||||
__func__, ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
msleep(150);
|
||||
|
@ -273,7 +287,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
|
|||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||
dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
|
||||
__FUNCTION__, ret);
|
||||
__func__, ret);
|
||||
if (ret >= 0)
|
||||
break;
|
||||
if (ret != -EPIPE)
|
||||
|
@ -793,18 +807,18 @@ static void usbtouch_irq(struct urb *urb)
|
|||
case -ETIME:
|
||||
/* this urb is timing out */
|
||||
dbg("%s - urb timed out - was the device unplugged?",
|
||||
__FUNCTION__);
|
||||
__func__);
|
||||
return;
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
/* this urb is terminated, clean up */
|
||||
dbg("%s - urb shutting down with status: %d",
|
||||
__FUNCTION__, urb->status);
|
||||
__func__, urb->status);
|
||||
return;
|
||||
default:
|
||||
dbg("%s - nonzero urb status received: %d",
|
||||
__FUNCTION__, urb->status);
|
||||
__func__, urb->status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -814,7 +828,7 @@ static void usbtouch_irq(struct urb *urb)
|
|||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (retval)
|
||||
err("%s - usb_submit_urb failed with result: %d",
|
||||
__FUNCTION__, retval);
|
||||
__func__, retval);
|
||||
}
|
||||
|
||||
static int usbtouch_open(struct input_dev *input)
|
||||
|
@ -857,6 +871,10 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|||
struct usbtouch_device_info *type;
|
||||
int err = -ENOMEM;
|
||||
|
||||
/* some devices are ignored */
|
||||
if (id->driver_info == DEVTYPE_IGNORE)
|
||||
return -ENODEV;
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
endpoint = &interface->endpoint[0].desc;
|
||||
|
||||
|
@ -883,7 +901,7 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|||
|
||||
usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!usbtouch->irq) {
|
||||
dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__);
|
||||
dbg("%s - usb_alloc_urb failed: usbtouch->irq", __func__);
|
||||
goto out_free_buffers;
|
||||
}
|
||||
|
||||
|
@ -939,14 +957,14 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|||
if (type->init) {
|
||||
err = type->init(usbtouch);
|
||||
if (err) {
|
||||
dbg("%s - type->init() failed, err: %d", __FUNCTION__, err);
|
||||
dbg("%s - type->init() failed, err: %d", __func__, err);
|
||||
goto out_free_buffers;
|
||||
}
|
||||
}
|
||||
|
||||
err = input_register_device(usbtouch->input);
|
||||
if (err) {
|
||||
dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err);
|
||||
dbg("%s - input_register_device failed, err: %d", __func__, err);
|
||||
goto out_free_buffers;
|
||||
}
|
||||
|
||||
|
@ -966,12 +984,12 @@ static void usbtouch_disconnect(struct usb_interface *intf)
|
|||
{
|
||||
struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
|
||||
|
||||
dbg("%s - called", __FUNCTION__);
|
||||
dbg("%s - called", __func__);
|
||||
|
||||
if (!usbtouch)
|
||||
return;
|
||||
|
||||
dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__);
|
||||
dbg("%s - usbtouch is initialized, cleaning up", __func__);
|
||||
usb_set_intfdata(intf, NULL);
|
||||
usb_kill_urb(usbtouch->irq);
|
||||
input_unregister_device(usbtouch->input);
|
||||
|
|
|
@ -168,6 +168,18 @@ static void wm9712_phy_init(struct wm97xx *wm)
|
|||
64000 / rpu);
|
||||
}
|
||||
|
||||
/* WM9712 five wire */
|
||||
if (five_wire) {
|
||||
dig2 |= WM9712_45W;
|
||||
dev_dbg(wm->dev, "setting 5-wire touchscreen mode.");
|
||||
|
||||
if (pil) {
|
||||
dev_warn(wm->dev, "pressure measurement is not "
|
||||
"supported in 5-wire mode\n");
|
||||
pil = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* touchpanel pressure current*/
|
||||
if (pil == 2) {
|
||||
dig2 |= WM9712_PIL;
|
||||
|
@ -179,12 +191,6 @@ static void wm9712_phy_init(struct wm97xx *wm)
|
|||
if (!pil)
|
||||
pressure = 0;
|
||||
|
||||
/* WM9712 five wire */
|
||||
if (five_wire) {
|
||||
dig2 |= WM9712_45W;
|
||||
dev_dbg(wm->dev, "setting 5-wire touchscreen mode.");
|
||||
}
|
||||
|
||||
/* polling mode sample settling delay */
|
||||
if (delay < 0 || delay > 15) {
|
||||
dev_dbg(wm->dev, "supplied delay out of range.");
|
||||
|
|
|
@ -219,11 +219,13 @@ struct adbhid {
|
|||
int flags;
|
||||
};
|
||||
|
||||
#define FLAG_FN_KEY_PRESSED 0x00000001
|
||||
#define FLAG_POWER_FROM_FN 0x00000002
|
||||
#define FLAG_EMU_FWDEL_DOWN 0x00000004
|
||||
#define FLAG_CAPSLOCK_TRANSLATE 0x00000008
|
||||
#define FLAG_CAPSLOCK_DOWN 0x00000010
|
||||
#define FLAG_FN_KEY_PRESSED 0x00000001
|
||||
#define FLAG_POWER_FROM_FN 0x00000002
|
||||
#define FLAG_EMU_FWDEL_DOWN 0x00000004
|
||||
#define FLAG_CAPSLOCK_TRANSLATE 0x00000008
|
||||
#define FLAG_CAPSLOCK_DOWN 0x00000010
|
||||
#define FLAG_CAPSLOCK_IGNORE_NEXT 0x00000020
|
||||
#define FLAG_POWER_KEY_PRESSED 0x00000040
|
||||
|
||||
static struct adbhid *adbhid[16];
|
||||
|
||||
|
@ -291,11 +293,20 @@ adbhid_input_keycode(int id, int scancode, int repeat)
|
|||
if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
|
||||
/* Key pressed, turning on the CapsLock LED.
|
||||
* The next 0xff will be interpreted as a release. */
|
||||
ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
|
||||
if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) {
|
||||
/* Throw away this key event if it happens
|
||||
* just after resume. */
|
||||
ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT;
|
||||
return;
|
||||
} else {
|
||||
ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
|
||||
| FLAG_CAPSLOCK_DOWN;
|
||||
} else if (scancode == 0xff) {
|
||||
}
|
||||
} else if (scancode == 0xff &&
|
||||
!(ahid->flags & FLAG_POWER_KEY_PRESSED)) {
|
||||
/* Scancode 0xff usually signifies that the capslock
|
||||
* key was either pressed or released. */
|
||||
* key was either pressed or released, or that the
|
||||
* power button was released. */
|
||||
if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
|
||||
keycode = ADB_KEY_CAPSLOCK;
|
||||
if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
|
||||
|
@ -309,7 +320,7 @@ adbhid_input_keycode(int id, int scancode, int repeat)
|
|||
}
|
||||
} else {
|
||||
printk(KERN_INFO "Spurious caps lock event "
|
||||
"(scancode 0xff).");
|
||||
"(scancode 0xff).\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,6 +347,12 @@ adbhid_input_keycode(int id, int scancode, int repeat)
|
|||
}
|
||||
break;
|
||||
case ADB_KEY_POWER:
|
||||
/* Keep track of the power key state */
|
||||
if (up_flag)
|
||||
ahid->flags &= ~FLAG_POWER_KEY_PRESSED;
|
||||
else
|
||||
ahid->flags |= FLAG_POWER_KEY_PRESSED;
|
||||
|
||||
/* Fn + Command will produce a bogus "power" keycode */
|
||||
if (ahid->flags & FLAG_FN_KEY_PRESSED) {
|
||||
keycode = ADB_KEY_CMD;
|
||||
|
@ -681,6 +698,21 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
adbhid_kbd_capslock_remember(void)
|
||||
{
|
||||
struct adbhid *ahid;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < 16; i++) {
|
||||
ahid = adbhid[i];
|
||||
|
||||
if (ahid && ahid->id == ADB_KEYBOARD)
|
||||
if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE)
|
||||
ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
|
||||
{
|
||||
|
@ -697,8 +729,17 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
|
|||
}
|
||||
|
||||
/* Stop pending led requests */
|
||||
while(leds_req_pending)
|
||||
while (leds_req_pending)
|
||||
adb_poll();
|
||||
|
||||
/* After resume, and if the capslock LED is on, the PMU will
|
||||
* send a "capslock down" key event. This confuses the
|
||||
* restore_capslock_events logic. Remember if the capslock
|
||||
* LED was on before suspend so the unwanted key event can
|
||||
* be ignored after resume. */
|
||||
if (restore_capslock_events)
|
||||
adbhid_kbd_capslock_remember();
|
||||
|
||||
break;
|
||||
|
||||
case ADB_MSG_POST_RESET:
|
||||
|
|
|
@ -68,7 +68,6 @@ struct gameport_driver {
|
|||
|
||||
int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode);
|
||||
void gameport_close(struct gameport *gameport);
|
||||
void gameport_rescan(struct gameport *gameport);
|
||||
|
||||
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ struct gpio_keys_button {
|
|||
char *desc;
|
||||
int type; /* input event type (EV_KEY, EV_SW) */
|
||||
int wakeup; /* configure the button as a wake-up source */
|
||||
int debounce_interval; /* debounce ticks interval in msecs */
|
||||
};
|
||||
|
||||
struct gpio_keys_platform_data {
|
||||
|
|
|
@ -373,6 +373,8 @@ struct input_absinfo {
|
|||
|
||||
#define KEY_WIMAX 246
|
||||
|
||||
/* Range 248 - 255 is reserved for special needs of AT keyboard driver */
|
||||
|
||||
#define BTN_MISC 0x100
|
||||
#define BTN_0 0x100
|
||||
#define BTN_1 0x101
|
||||
|
@ -640,6 +642,8 @@ struct input_absinfo {
|
|||
#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any"
|
||||
set = radio enabled */
|
||||
#define SW_RADIO SW_RFKILL_ALL /* deprecated */
|
||||
#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */
|
||||
#define SW_DOCK 0x05 /* set = plugged into dock */
|
||||
#define SW_MAX 0x0f
|
||||
#define SW_CNT (SW_MAX+1)
|
||||
|
||||
|
@ -1215,11 +1219,6 @@ struct input_handle {
|
|||
struct list_head h_node;
|
||||
};
|
||||
|
||||
#define to_dev(n) container_of(n, struct input_dev, node)
|
||||
#define to_handler(n) container_of(n, struct input_handler, node)
|
||||
#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)
|
||||
|
||||
struct input_dev *input_allocate_device(void);
|
||||
void input_free_device(struct input_dev *dev);
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#define _LINUX_JOYSTICK_H
|
||||
|
||||
/*
|
||||
* $Id: joystick.h,v 1.3 2000/11/30 11:07:05 vojtech Exp $
|
||||
*
|
||||
* Copyright (C) 1996-2000 Vojtech Pavlik
|
||||
*
|
||||
* Sponsored by SuSE
|
||||
|
|
|
@ -43,7 +43,6 @@ void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
|
|||
int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
|
||||
void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
|
||||
int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
|
||||
int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command);
|
||||
int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
|
||||
int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
|
||||
void ps2_cmd_aborted(struct ps2dev *ps2dev);
|
||||
|
|
|
@ -175,7 +175,7 @@ static inline void serio_unpin_driver(struct serio *serio)
|
|||
#define SERIO_8042_XL 0x06
|
||||
|
||||
/*
|
||||
* Serio types
|
||||
* Serio protocols
|
||||
*/
|
||||
#define SERIO_UNKNOWN 0x00
|
||||
#define SERIO_MSC 0x01
|
||||
|
@ -212,5 +212,7 @@ static inline void serio_unpin_driver(struct serio *serio)
|
|||
#define SERIO_TAOSEVM 0x34
|
||||
#define SERIO_FUJITSU 0x35
|
||||
#define SERIO_ZHENHUA 0x36
|
||||
#define SERIO_INEXIO 0x37
|
||||
#define SERIO_TOUCHIT213 0x37
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue