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:
Linus Torvalds 2008-07-21 10:27:31 -07:00
commit 519f0141f1
100 changed files with 2282 additions and 549 deletions

View File

@ -1,5 +1,3 @@
$Id: gameport-programming.txt,v 1.3 2001/04/24 13:51:37 vojtech Exp $
Programming gameport drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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

View File

@ -5,8 +5,6 @@
7 Aug 1998
$Id: joystick-api.txt,v 1.2 2001/05/08 21:21:23 vojtech Exp $
1. Initialization
~~~~~~~~~~~~~~~~~

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
*/

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -1,6 +1,4 @@
/*
* $Id: emu10k1-gp.c,v 1.8 2002/01/22 20:40:46 vojtech Exp $
*
* Copyright (c) 2001 Vojtech Pavlik
*/

View File

@ -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.

View File

@ -1,6 +1,4 @@
/*
* $Id: lightning.c,v 1.20 2002/01/22 20:41:31 vojtech Exp $
*
* Copyright (c) 1998-2001 Vojtech Pavlik
*/

View File

@ -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
*/

View File

@ -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)

View File

@ -1,6 +1,4 @@
/*
* $Id: a3d.c,v 1.21 2002/01/22 20:11:50 vojtech Exp $
*
* Copyright (c) 1998-2001 Vojtech Pavlik
*/

View File

@ -1,6 +1,4 @@
/*
* $Id: amijoy.c,v 1.13 2002/01/22 20:26:32 vojtech Exp $
*
* Copyright (c) 1998-2001 Vojtech Pavlik
*/

View File

@ -1,6 +1,4 @@
/*
* $Id: cobra.c,v 1.19 2002/01/22 20:26:52 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/

View File

@ -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:

View File

@ -1,6 +1,4 @@
/*
* $Id: gf2k.c,v 1.19 2002/01/22 20:27:43 vojtech Exp $
*
* Copyright (c) 1998-2001 Vojtech Pavlik
*/

View File

@ -1,6 +1,4 @@
/*
* $Id: grip.c,v 1.21 2002/01/22 20:27:57 vojtech Exp $
*
* Copyright (c) 1998-2001 Vojtech Pavlik
*/

View File

@ -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.

View File

@ -1,6 +1,4 @@
/*
* $Id: guillemot.c,v 1.10 2002/01/22 20:28:12 vojtech Exp $
*
* Copyright (c) 2001 Vojtech Pavlik
*/

View File

@ -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>
*

View File

@ -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>
*

View File

@ -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>
*

View File

@ -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>
*

View File

@ -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 @@ exit:
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)

View File

@ -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>
*

View File

@ -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:

View File

@ -1,6 +1,4 @@
/*
* $Id: joydump.c,v 1.1 2002/01/23 06:56:16 jsimmons Exp $
*
* Copyright (c) 1996-2001 Vojtech Pavlik
*/

View File

@ -1,6 +1,4 @@
/*
* $Id: magellan.c,v 1.16 2002/01/22 20:28:39 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/

View File

@ -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:

View File

@ -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:

View File

@ -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
*/

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -1,6 +1,4 @@
/*
* $Id: warrior.c,v 1.14 2002/01/22 20:32:10 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/

View File

@ -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 @@ exit:
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 @@ exit:
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)

View File

@ -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:

View File

@ -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,
},
{ }
};

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -1,6 +1,4 @@
/*
* $Id: sunkbd.c,v 1.14 2001/09/25 10:12:07 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/

View File

@ -1,6 +1,4 @@
/*
* $Id: xtkbd.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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 @@ exit:
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 */

View 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);

View File

@ -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;
}

View File

@ -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 @@ send_update:
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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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[] = {

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -1,6 +1,4 @@
/*
* $Id: sermouse.c,v 1.17 2002/03/13 10:03:43 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,4 @@
/*
* $Id: ct82c710.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/

View File

@ -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);

View File

@ -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__)

View File

@ -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];

View File

@ -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 */

View File

@ -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
*/

View File

@ -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;

View File

@ -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
*/

View File

@ -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) {

View 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");

View File

@ -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;
}

View File

@ -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 @@ exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval != 0) {
err("%s - usb_submit_urb failed with result %d",
__FUNCTION__, retval);
__func__, retval);
}
}

View File

@ -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;
}

View File

@ -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[] = {

View File

@ -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];
};

View File

@ -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)

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,4 @@
/*
* $Id: gunze.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik
*/

View File

@ -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.

View 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);

View 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);

View 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);

View 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);

View File

@ -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 @@ exit:
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);

View File

@ -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.");

View File

@ -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:

View File

@ -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))

View File

@ -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 {

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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