You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge commit 'v2.6.30-rc5' into next
This commit is contained in:
@@ -143,7 +143,7 @@ config INPUT_APMPOWER
|
||||
---help---
|
||||
Say Y here if you want suspend key events to trigger a user
|
||||
requested suspend through APM. This is useful on embedded
|
||||
systems where such behviour is desired without userspace
|
||||
systems where such behaviour is desired without userspace
|
||||
interaction. If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
|
||||
@@ -94,11 +94,8 @@ static void evdev_event(struct input_handle *handle,
|
||||
static int evdev_fasync(int fd, struct file *file, int on)
|
||||
{
|
||||
struct evdev_client *client = file->private_data;
|
||||
int retval;
|
||||
|
||||
retval = fasync_helper(fd, file, on, &client->fasync);
|
||||
|
||||
return retval < 0 ? retval : 0;
|
||||
return fasync_helper(fd, file, on, &client->fasync);
|
||||
}
|
||||
|
||||
static int evdev_flush(struct file *file, fl_owner_t id)
|
||||
|
||||
+36
-2
@@ -29,6 +29,23 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
#define INPUT_DEVICES 256
|
||||
|
||||
/*
|
||||
* EV_ABS events which should not be cached are listed here.
|
||||
*/
|
||||
static unsigned int input_abs_bypass_init_data[] __initdata = {
|
||||
ABS_MT_TOUCH_MAJOR,
|
||||
ABS_MT_TOUCH_MINOR,
|
||||
ABS_MT_WIDTH_MAJOR,
|
||||
ABS_MT_WIDTH_MINOR,
|
||||
ABS_MT_ORIENTATION,
|
||||
ABS_MT_POSITION_X,
|
||||
ABS_MT_POSITION_Y,
|
||||
ABS_MT_TOOL_TYPE,
|
||||
ABS_MT_BLOB_ID,
|
||||
0
|
||||
};
|
||||
static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
|
||||
|
||||
static LIST_HEAD(input_dev_list);
|
||||
static LIST_HEAD(input_handler_list);
|
||||
|
||||
@@ -161,6 +178,10 @@ static void input_handle_event(struct input_dev *dev,
|
||||
disposition = INPUT_PASS_TO_HANDLERS;
|
||||
}
|
||||
break;
|
||||
case SYN_MT_REPORT:
|
||||
dev->sync = 0;
|
||||
disposition = INPUT_PASS_TO_HANDLERS;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -192,6 +213,11 @@ static void input_handle_event(struct input_dev *dev,
|
||||
case EV_ABS:
|
||||
if (is_event_supported(code, dev->absbit, ABS_MAX)) {
|
||||
|
||||
if (test_bit(code, input_abs_bypass)) {
|
||||
disposition = INPUT_PASS_TO_HANDLERS;
|
||||
break;
|
||||
}
|
||||
|
||||
value = input_defuzz_abs_event(value,
|
||||
dev->abs[code], dev->absfuzz[code]);
|
||||
|
||||
@@ -910,8 +936,6 @@ static int __init input_proc_init(void)
|
||||
if (!proc_bus_input_dir)
|
||||
return -ENOMEM;
|
||||
|
||||
proc_bus_input_dir->owner = THIS_MODULE;
|
||||
|
||||
entry = proc_create("devices", 0, proc_bus_input_dir,
|
||||
&input_devices_fileops);
|
||||
if (!entry)
|
||||
@@ -1636,10 +1660,20 @@ static const struct file_operations input_fops = {
|
||||
.open = input_open_file,
|
||||
};
|
||||
|
||||
static void __init input_init_abs_bypass(void)
|
||||
{
|
||||
const unsigned int *p;
|
||||
|
||||
for (p = input_abs_bypass_init_data; *p; p++)
|
||||
input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p);
|
||||
}
|
||||
|
||||
static int __init input_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
input_init_abs_bypass();
|
||||
|
||||
err = class_register(&input_class);
|
||||
if (err) {
|
||||
printk(KERN_ERR "input: unable to register input_dev class\n");
|
||||
|
||||
@@ -159,12 +159,9 @@ static void joydev_event(struct input_handle *handle,
|
||||
|
||||
static int joydev_fasync(int fd, struct file *file, int on)
|
||||
{
|
||||
int retval;
|
||||
struct joydev_client *client = file->private_data;
|
||||
|
||||
retval = fasync_helper(fd, file, on, &client->fasync);
|
||||
|
||||
return retval < 0 ? retval : 0;
|
||||
return fasync_helper(fd, file, on, &client->fasync);
|
||||
}
|
||||
|
||||
static void joydev_free(struct device *dev)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Based on drivers/usb/iforce.c
|
||||
*
|
||||
* Copyright Yaegashi Takeshi, 2001
|
||||
* Adrian McMenamin, 2008
|
||||
* Adrian McMenamin, 2008 - 2009
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -29,7 +29,7 @@ static void dc_pad_callback(struct mapleq *mq)
|
||||
struct maple_device *mapledev = mq->dev;
|
||||
struct dc_pad *pad = maple_get_drvdata(mapledev);
|
||||
struct input_dev *dev = pad->dev;
|
||||
unsigned char *res = mq->recvbuf;
|
||||
unsigned char *res = mq->recvbuf->buf;
|
||||
|
||||
buttons = ~le16_to_cpup((__le16 *)(res + 8));
|
||||
|
||||
|
||||
@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD
|
||||
if INPUT_KEYBOARD
|
||||
|
||||
config KEYBOARD_ATKBD
|
||||
tristate "AT keyboard" if EMBEDDED || !X86_PC
|
||||
tristate "AT keyboard" if EMBEDDED || !X86
|
||||
default y
|
||||
select SERIO
|
||||
select SERIO_LIBPS2
|
||||
select SERIO_I8042 if X86_PC
|
||||
select SERIO_I8042 if X86
|
||||
select SERIO_GSCPS2 if GSC
|
||||
help
|
||||
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <mach/corgi.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
#include <mach/pxa2xx-gpio.h>
|
||||
#include <asm/hardware/scoop.h>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* SEGA Dreamcast keyboard driver
|
||||
* Based on drivers/usb/usbkbd.c
|
||||
* Copyright YAEGASHI Takeshi, 2001
|
||||
* Porting to 2.6 Copyright Adrian McMenamin, 2007, 2008
|
||||
* Copyright (c) YAEGASHI Takeshi, 2001
|
||||
* Porting to 2.6 Copyright (c) Adrian McMenamin, 2007 - 2009
|
||||
*
|
||||
* 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
|
||||
@@ -33,7 +33,7 @@ static DEFINE_MUTEX(maple_keyb_mutex);
|
||||
|
||||
#define NR_SCANCODES 256
|
||||
|
||||
MODULE_AUTHOR("YAEGASHI Takeshi, Adrian McMenamin");
|
||||
MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk");
|
||||
MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -115,7 +115,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd)
|
||||
input_event(dev, EV_MSC, MSC_SCAN, code);
|
||||
input_report_key(dev, keycode, 0);
|
||||
} else
|
||||
printk(KERN_DEBUG "maple_keyb: "
|
||||
dev_dbg(&dev->dev,
|
||||
"Unknown key (scancode %#x) released.",
|
||||
code);
|
||||
}
|
||||
@@ -127,7 +127,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd)
|
||||
input_event(dev, EV_MSC, MSC_SCAN, code);
|
||||
input_report_key(dev, keycode, 1);
|
||||
} else
|
||||
printk(KERN_DEBUG "maple_keyb: "
|
||||
dev_dbg(&dev->dev,
|
||||
"Unknown key (scancode %#x) pressed.",
|
||||
code);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ static void dc_kbd_callback(struct mapleq *mq)
|
||||
{
|
||||
struct maple_device *mapledev = mq->dev;
|
||||
struct dc_kbd *kbd = maple_get_drvdata(mapledev);
|
||||
unsigned long *buf = mq->recvbuf;
|
||||
unsigned long *buf = (unsigned long *)(mq->recvbuf->buf);
|
||||
|
||||
/*
|
||||
* We should always get the lock because the only
|
||||
@@ -159,22 +159,27 @@ static void dc_kbd_callback(struct mapleq *mq)
|
||||
|
||||
static int probe_maple_kbd(struct device *dev)
|
||||
{
|
||||
struct maple_device *mdev = to_maple_dev(dev);
|
||||
struct maple_driver *mdrv = to_maple_driver(dev->driver);
|
||||
struct maple_device *mdev;
|
||||
struct maple_driver *mdrv;
|
||||
int i, error;
|
||||
struct dc_kbd *kbd;
|
||||
struct input_dev *idev;
|
||||
|
||||
if (!(mdev->function & MAPLE_FUNC_KEYBOARD))
|
||||
return -EINVAL;
|
||||
mdev = to_maple_dev(dev);
|
||||
mdrv = to_maple_driver(dev->driver);
|
||||
|
||||
kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
|
||||
idev = input_allocate_device();
|
||||
if (!kbd || !idev) {
|
||||
if (!kbd) {
|
||||
error = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
idev = input_allocate_device();
|
||||
if (!idev) {
|
||||
error = -ENOMEM;
|
||||
goto fail_idev_alloc;
|
||||
}
|
||||
|
||||
kbd->dev = idev;
|
||||
memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode));
|
||||
|
||||
@@ -195,7 +200,7 @@ static int probe_maple_kbd(struct device *dev)
|
||||
|
||||
error = input_register_device(idev);
|
||||
if (error)
|
||||
goto fail;
|
||||
goto fail_register;
|
||||
|
||||
/* Maple polling is locked to VBLANK - which may be just 50/s */
|
||||
maple_getcond_callback(mdev, dc_kbd_callback, HZ/50,
|
||||
@@ -207,10 +212,12 @@ static int probe_maple_kbd(struct device *dev)
|
||||
|
||||
return error;
|
||||
|
||||
fail:
|
||||
input_free_device(idev);
|
||||
kfree(kbd);
|
||||
fail_register:
|
||||
maple_set_drvdata(mdev, NULL);
|
||||
input_free_device(idev);
|
||||
fail_idev_alloc:
|
||||
kfree(kbd);
|
||||
fail:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,8 +100,20 @@ static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
|
||||
/* disable keyboard interrupt and schedule for handling */
|
||||
if (cpu_is_omap24xx()) {
|
||||
int i;
|
||||
for (i = 0; i < omap_kp->rows; i++)
|
||||
disable_irq(gpio_to_irq(row_gpios[i]));
|
||||
|
||||
for (i = 0; i < omap_kp->rows; i++) {
|
||||
int gpio_irq = gpio_to_irq(row_gpios[i]);
|
||||
/*
|
||||
* The interrupt which we're currently handling should
|
||||
* be disabled _nosync() to avoid deadlocks waiting
|
||||
* for this handler to complete. All others should
|
||||
* be disabled the regular way for SMP safety.
|
||||
*/
|
||||
if (gpio_irq == irq)
|
||||
disable_irq_nosync(gpio_irq);
|
||||
else
|
||||
disable_irq(gpio_irq);
|
||||
}
|
||||
} else
|
||||
/* disable keyboard interrupt and schedule for handling */
|
||||
omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
|
||||
|
||||
@@ -219,6 +219,8 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
|
||||
pdata->scan_timing, priv->iomem_base + KYCR1_OFFS);
|
||||
iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
|
||||
iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
|
||||
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
return 0;
|
||||
err5:
|
||||
free_irq(irq, pdev);
|
||||
@@ -253,17 +255,48 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_keysc_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
unsigned short value;
|
||||
|
||||
#define sh_keysc_suspend NULL
|
||||
#define sh_keysc_resume NULL
|
||||
value = ioread16(priv->iomem_base + KYCR1_OFFS);
|
||||
|
||||
if (device_may_wakeup(dev)) {
|
||||
value |= 0x80;
|
||||
enable_irq_wake(irq);
|
||||
}
|
||||
else
|
||||
value &= ~0x80;
|
||||
|
||||
iowrite16(value, priv->iomem_base + KYCR1_OFFS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_keysc_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dev_pm_ops sh_keysc_dev_pm_ops = {
|
||||
.suspend = sh_keysc_suspend,
|
||||
.resume = sh_keysc_resume,
|
||||
};
|
||||
|
||||
struct platform_driver sh_keysc_device_driver = {
|
||||
.probe = sh_keysc_probe,
|
||||
.remove = __devexit_p(sh_keysc_remove),
|
||||
.suspend = sh_keysc_suspend,
|
||||
.resume = sh_keysc_resume,
|
||||
.driver = {
|
||||
.name = "sh_keysc",
|
||||
.pm = &sh_keysc_dev_pm_ops,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <mach/spitz.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/pxa-regs.h>
|
||||
#include <mach/pxa2xx-gpio.h>
|
||||
|
||||
#define KB_ROWS 7
|
||||
|
||||
@@ -17,7 +17,7 @@ config MOUSE_PS2
|
||||
default y
|
||||
select SERIO
|
||||
select SERIO_LIBPS2
|
||||
select SERIO_I8042 if X86_PC
|
||||
select SERIO_I8042 if X86
|
||||
select SERIO_GSCPS2 if GSC
|
||||
help
|
||||
Say Y here if you have a PS/2 mouse connected to your system. This
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define ALPS_FW_BK_2 0x40
|
||||
|
||||
static const struct alps_model_info alps_model_data[] = {
|
||||
{ { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
|
||||
{ { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */
|
||||
{ { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
|
||||
{ { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
|
||||
|
||||
@@ -255,15 +255,22 @@ MODULE_PARM_DESC(debug, "Activate debugging output");
|
||||
*/
|
||||
static int atp_geyser_init(struct usb_device *udev)
|
||||
{
|
||||
char data[8];
|
||||
char *data;
|
||||
int size;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
data = kmalloc(8, GFP_KERNEL);
|
||||
if (!data) {
|
||||
err("Out of memory");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||
ATP_GEYSER_MODE_READ_REQUEST_ID,
|
||||
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
||||
ATP_GEYSER_MODE_REQUEST_VALUE,
|
||||
ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
|
||||
ATP_GEYSER_MODE_REQUEST_INDEX, data, 8, 5000);
|
||||
|
||||
if (size != 8) {
|
||||
dprintk("atp_geyser_init: read error\n");
|
||||
@@ -271,7 +278,8 @@ static int atp_geyser_init(struct usb_device *udev)
|
||||
dprintk("appletouch[%d]: %d\n", i, data[i]);
|
||||
|
||||
err("Failed to read mode from device.");
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* Apply the mode switch */
|
||||
@@ -281,7 +289,7 @@ static int atp_geyser_init(struct usb_device *udev)
|
||||
ATP_GEYSER_MODE_WRITE_REQUEST_ID,
|
||||
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
||||
ATP_GEYSER_MODE_REQUEST_VALUE,
|
||||
ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
|
||||
ATP_GEYSER_MODE_REQUEST_INDEX, data, 8, 5000);
|
||||
|
||||
if (size != 8) {
|
||||
dprintk("atp_geyser_init: write error\n");
|
||||
@@ -289,9 +297,13 @@ static int atp_geyser_init(struct usb_device *udev)
|
||||
dprintk("appletouch[%d]: %d\n", i, data[i]);
|
||||
|
||||
err("Failed to request geyser raw mode");
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto out_free;
|
||||
}
|
||||
return 0;
|
||||
ret = 0;
|
||||
out_free:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -51,6 +51,10 @@
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
|
||||
/* Macbook5,1 (unibody), aka wellspring3 */
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
|
||||
|
||||
#define BCM5974_DEVICE(prod) { \
|
||||
.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
|
||||
@@ -72,6 +76,10 @@ static const struct usb_device_id bcm5974_table[] = {
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
|
||||
/* Macbook5,1 */
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
|
||||
BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
|
||||
/* Terminating entry */
|
||||
{}
|
||||
};
|
||||
@@ -96,14 +104,23 @@ struct bt_data {
|
||||
u8 rel_y; /* relative y coordinate */
|
||||
};
|
||||
|
||||
/* trackpad header structure */
|
||||
struct tp_header {
|
||||
u8 unknown1[16]; /* constants, timers, etc */
|
||||
u8 fingers; /* number of fingers on trackpad */
|
||||
u8 unknown2[9]; /* constants, timers, etc */
|
||||
/* trackpad header types */
|
||||
enum tp_type {
|
||||
TYPE1, /* plain trackpad */
|
||||
TYPE2 /* button integrated in trackpad */
|
||||
};
|
||||
|
||||
/* trackpad finger structure */
|
||||
/* trackpad finger data offsets, le16-aligned */
|
||||
#define FINGER_TYPE1 (13 * sizeof(__le16))
|
||||
#define FINGER_TYPE2 (15 * sizeof(__le16))
|
||||
|
||||
/* trackpad button data offsets */
|
||||
#define BUTTON_TYPE2 15
|
||||
|
||||
/* list of device capability bits */
|
||||
#define HAS_INTEGRATED_BUTTON 1
|
||||
|
||||
/* trackpad finger structure, le16-aligned */
|
||||
struct tp_finger {
|
||||
__le16 origin; /* zero when switching track finger */
|
||||
__le16 abs_x; /* absolute x coodinate */
|
||||
@@ -117,13 +134,11 @@ struct tp_finger {
|
||||
__le16 force_minor; /* trackpad force, minor axis? */
|
||||
__le16 unused[3]; /* zeros */
|
||||
__le16 multi; /* one finger: varies, more fingers: constant */
|
||||
};
|
||||
} __attribute__((packed,aligned(2)));
|
||||
|
||||
/* trackpad data structure, empirically at least ten fingers */
|
||||
struct tp_data {
|
||||
struct tp_header header;
|
||||
struct tp_finger finger[16];
|
||||
};
|
||||
/* trackpad finger data size, empirically at least ten fingers */
|
||||
#define SIZEOF_FINGER sizeof(struct tp_finger)
|
||||
#define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER)
|
||||
|
||||
/* device-specific parameters */
|
||||
struct bcm5974_param {
|
||||
@@ -136,9 +151,12 @@ struct bcm5974_param {
|
||||
/* device-specific configuration */
|
||||
struct bcm5974_config {
|
||||
int ansi, iso, jis; /* the product id of this device */
|
||||
int caps; /* device capability bitmask */
|
||||
int bt_ep; /* the endpoint of the button interface */
|
||||
int bt_datalen; /* data length of the button interface */
|
||||
int tp_ep; /* the endpoint of the trackpad interface */
|
||||
enum tp_type tp_type; /* type of trackpad interface */
|
||||
int tp_offset; /* offset to trackpad finger data */
|
||||
int tp_datalen; /* data length of the trackpad interface */
|
||||
struct bcm5974_param p; /* finger pressure limits */
|
||||
struct bcm5974_param w; /* finger width limits */
|
||||
@@ -158,7 +176,7 @@ struct bcm5974 {
|
||||
struct urb *bt_urb; /* button usb request block */
|
||||
struct bt_data *bt_data; /* button transferred data */
|
||||
struct urb *tp_urb; /* trackpad usb request block */
|
||||
struct tp_data *tp_data; /* trackpad transferred data */
|
||||
u8 *tp_data; /* trackpad transferred data */
|
||||
int fingers; /* number of fingers on trackpad */
|
||||
};
|
||||
|
||||
@@ -183,8 +201,9 @@ static const struct bcm5974_config bcm5974_config_table[] = {
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
|
||||
0,
|
||||
0x84, sizeof(struct bt_data),
|
||||
0x81, sizeof(struct tp_data),
|
||||
0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
|
||||
{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
|
||||
{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
|
||||
{ DIM_X, DIM_X / SN_COORD, -4824, 5342 },
|
||||
@@ -194,13 +213,26 @@ static const struct bcm5974_config bcm5974_config_table[] = {
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
|
||||
0,
|
||||
0x84, sizeof(struct bt_data),
|
||||
0x81, sizeof(struct tp_data),
|
||||
0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
|
||||
{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
|
||||
{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
|
||||
{ DIM_X, DIM_X / SN_COORD, -4824, 4824 },
|
||||
{ DIM_Y, DIM_Y / SN_COORD, -172, 4290 }
|
||||
},
|
||||
{
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING3_ISO,
|
||||
USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,
|
||||
HAS_INTEGRATED_BUTTON,
|
||||
0x84, sizeof(struct bt_data),
|
||||
0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
|
||||
{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
|
||||
{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
|
||||
{ DIM_X, DIM_X / SN_COORD, -4460, 5166 },
|
||||
{ DIM_Y, DIM_Y / SN_COORD, -75, 6700 }
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -257,6 +289,7 @@ static void setup_events_to_report(struct input_dev *input_dev,
|
||||
__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
|
||||
__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
|
||||
__set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
|
||||
__set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
|
||||
__set_bit(BTN_LEFT, input_dev->keybit);
|
||||
}
|
||||
|
||||
@@ -266,6 +299,11 @@ static int report_bt_state(struct bcm5974 *dev, int size)
|
||||
if (size != sizeof(struct bt_data))
|
||||
return -EIO;
|
||||
|
||||
dprintk(7,
|
||||
"bcm5974: button data: %x %x %x %x\n",
|
||||
dev->bt_data->unknown1, dev->bt_data->button,
|
||||
dev->bt_data->rel_x, dev->bt_data->rel_y);
|
||||
|
||||
input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
|
||||
input_sync(dev->input);
|
||||
|
||||
@@ -276,29 +314,37 @@ static int report_bt_state(struct bcm5974 *dev, int size)
|
||||
static int report_tp_state(struct bcm5974 *dev, int size)
|
||||
{
|
||||
const struct bcm5974_config *c = &dev->cfg;
|
||||
const struct tp_finger *f = dev->tp_data->finger;
|
||||
const struct tp_finger *f;
|
||||
struct input_dev *input = dev->input;
|
||||
const int fingers = (size - 26) / 28;
|
||||
int raw_p, raw_w, raw_x, raw_y;
|
||||
int ptest = 0, origin = 0, nmin = 0, nmax = 0;
|
||||
int raw_p, raw_w, raw_x, raw_y, raw_n;
|
||||
int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0;
|
||||
int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
|
||||
|
||||
if (size < 26 || (size - 26) % 28 != 0)
|
||||
if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
|
||||
return -EIO;
|
||||
|
||||
/* finger data, le16-aligned */
|
||||
f = (const struct tp_finger *)(dev->tp_data + c->tp_offset);
|
||||
raw_n = (size - c->tp_offset) / SIZEOF_FINGER;
|
||||
|
||||
/* always track the first finger; when detached, start over */
|
||||
if (fingers) {
|
||||
if (raw_n) {
|
||||
raw_p = raw2int(f->force_major);
|
||||
raw_w = raw2int(f->size_major);
|
||||
raw_x = raw2int(f->abs_x);
|
||||
raw_y = raw2int(f->abs_y);
|
||||
|
||||
dprintk(9,
|
||||
"bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n",
|
||||
raw_p, raw_w, raw_x, raw_y);
|
||||
"bcm5974: "
|
||||
"raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
|
||||
raw_p, raw_w, raw_x, raw_y, raw_n);
|
||||
|
||||
ptest = int2bound(&c->p, raw_p);
|
||||
origin = raw2int(f->origin);
|
||||
|
||||
/* set the integrated button if applicable */
|
||||
if (c->tp_type == TYPE2)
|
||||
ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
|
||||
}
|
||||
|
||||
/* while tracking finger still valid, count all fingers */
|
||||
@@ -307,12 +353,13 @@ static int report_tp_state(struct bcm5974 *dev, int size)
|
||||
abs_w = int2bound(&c->w, raw_w);
|
||||
abs_x = int2bound(&c->x, raw_x - c->x.devmin);
|
||||
abs_y = int2bound(&c->y, c->y.devmax - raw_y);
|
||||
for (; f != dev->tp_data->finger + fingers; f++) {
|
||||
while (raw_n--) {
|
||||
ptest = int2bound(&c->p, raw2int(f->force_major));
|
||||
if (ptest > PRESSURE_LOW)
|
||||
nmax++;
|
||||
if (ptest > PRESSURE_HIGH)
|
||||
nmin++;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,7 +371,8 @@ static int report_tp_state(struct bcm5974 *dev, int size)
|
||||
input_report_key(input, BTN_TOUCH, dev->fingers > 0);
|
||||
input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1);
|
||||
input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2);
|
||||
input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers > 2);
|
||||
input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3);
|
||||
input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3);
|
||||
|
||||
input_report_abs(input, ABS_PRESSURE, abs_p);
|
||||
input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
|
||||
@@ -335,11 +383,15 @@ static int report_tp_state(struct bcm5974 *dev, int size)
|
||||
|
||||
dprintk(8,
|
||||
"bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
|
||||
"nmin: %d nmax: %d n: %d\n",
|
||||
abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers);
|
||||
"nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w,
|
||||
abs_x, abs_y, nmin, nmax, dev->fingers, ibt);
|
||||
|
||||
}
|
||||
|
||||
/* type 2 reports button events via ibt only */
|
||||
if (c->tp_type == TYPE2)
|
||||
input_report_key(input, BTN_LEFT, ibt);
|
||||
|
||||
input_sync(input);
|
||||
|
||||
return 0;
|
||||
@@ -649,6 +701,8 @@ static int bcm5974_probe(struct usb_interface *iface,
|
||||
input_dev->name = "bcm5974";
|
||||
input_dev->phys = dev->phys;
|
||||
usb_to_input_id(dev->udev, &input_dev->id);
|
||||
/* report driver capabilities via the version field */
|
||||
input_dev->id.version = cfg->caps;
|
||||
input_dev->dev.parent = &iface->dev;
|
||||
|
||||
input_set_drvdata(input_dev, dev);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Elantech Touchpad driver (v5)
|
||||
* Elantech Touchpad driver (v6)
|
||||
*
|
||||
* Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net>
|
||||
* Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net>
|
||||
*
|
||||
* 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
|
||||
@@ -178,6 +178,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
|
||||
struct elantech_data *etd = psmouse->private;
|
||||
unsigned char *packet = psmouse->packet;
|
||||
int fingers;
|
||||
static int old_fingers;
|
||||
|
||||
if (etd->fw_version_maj == 0x01) {
|
||||
/* byte 0: D U p1 p2 1 p3 R L
|
||||
@@ -190,6 +191,14 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
|
||||
fingers = (packet[0] & 0xc0) >> 6;
|
||||
}
|
||||
|
||||
if (etd->jumpy_cursor) {
|
||||
/* Discard packets that are likely to have bogus coordinates */
|
||||
if (fingers > old_fingers) {
|
||||
elantech_debug("elantech.c: discarding packet\n");
|
||||
goto discard_packet_v1;
|
||||
}
|
||||
}
|
||||
|
||||
input_report_key(dev, BTN_TOUCH, fingers != 0);
|
||||
|
||||
/* byte 2: x7 x6 x5 x4 x3 x2 x1 x0
|
||||
@@ -216,6 +225,9 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
|
||||
}
|
||||
|
||||
input_sync(dev);
|
||||
|
||||
discard_packet_v1:
|
||||
old_fingers = fingers;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -363,9 +375,14 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
/*
|
||||
* Read back reg 0x10. The touchpad is probably initalising
|
||||
* and not ready until we read back the value we just wrote.
|
||||
* Read back reg 0x10. For hardware version 1 we must make
|
||||
* sure the absolute mode bit is set. For hardware version 2
|
||||
* the touchpad is probably initalising and not ready until
|
||||
* we read back the value we just wrote.
|
||||
*/
|
||||
do {
|
||||
rc = elantech_read_reg(psmouse, 0x10, &val);
|
||||
@@ -373,12 +390,18 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
|
||||
break;
|
||||
tries--;
|
||||
elantech_debug("elantech.c: retrying read (%d).\n",
|
||||
tries);
|
||||
tries);
|
||||
msleep(ETP_READ_BACK_DELAY);
|
||||
} while (tries > 0);
|
||||
if (rc)
|
||||
|
||||
if (rc) {
|
||||
pr_err("elantech.c: failed to read back register 0x10.\n");
|
||||
break;
|
||||
} else if (etd->hw_version == 1 &&
|
||||
!(val & ETP_R10_ABSOLUTE_MODE)) {
|
||||
pr_err("elantech.c: touchpad refuses "
|
||||
"to switch to absolute mode.\n");
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc)
|
||||
@@ -662,6 +685,17 @@ int elantech_init(struct psmouse *psmouse)
|
||||
param[0], param[1], param[2]);
|
||||
etd->capabilities = param[0];
|
||||
|
||||
/*
|
||||
* This firmware seems to suffer from misreporting coordinates when
|
||||
* a touch action starts causing the mouse cursor or scrolled page
|
||||
* to jump. Enable a workaround.
|
||||
*/
|
||||
if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) {
|
||||
pr_info("elantech.c: firmware version 2.34 detected, "
|
||||
"enabling jumpy cursor workaround\n");
|
||||
etd->jumpy_cursor = 1;
|
||||
}
|
||||
|
||||
if (elantech_set_absolute_mode(psmouse)) {
|
||||
pr_err("elantech.c: failed to put touchpad into absolute mode.\n");
|
||||
goto init_fail;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Elantech Touchpad driver (v5)
|
||||
* Elantech Touchpad driver (v6)
|
||||
*
|
||||
* Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net>
|
||||
* Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net>
|
||||
*
|
||||
* 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
|
||||
@@ -104,6 +104,7 @@ struct elantech_data {
|
||||
unsigned char fw_version_min;
|
||||
unsigned char hw_version;
|
||||
unsigned char paritycheck;
|
||||
unsigned char jumpy_cursor;
|
||||
unsigned char parity[256];
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
/*
|
||||
* Timer function which is run every scan_ms ms when the device is opened.
|
||||
* The dev input varaible is set to the the input_dev pointer.
|
||||
* The dev input variable is set to the the input_dev pointer.
|
||||
*/
|
||||
static void gpio_mouse_scan(struct input_polled_dev *dev)
|
||||
{
|
||||
|
||||
@@ -381,7 +381,7 @@ static void hgpk_disconnect(struct psmouse *psmouse)
|
||||
|
||||
static void hgpk_recalib_work(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *w = container_of(work, struct delayed_work, work);
|
||||
struct delayed_work *w = to_delayed_work(work);
|
||||
struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
|
||||
struct psmouse *psmouse = priv->psmouse;
|
||||
|
||||
|
||||
@@ -60,6 +60,12 @@ static const struct dmi_system_id lifebook_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Lifebook B-2130",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Lifebook B213x/B2150",
|
||||
.matches = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user