Merge tag 'v3.7-rc3' into next to sync up with recent USB and MFD changes

This commit is contained in:
Dmitry Torokhov
2012-10-30 00:20:56 -07:00
13700 changed files with 705938 additions and 383988 deletions

View File

@@ -292,7 +292,6 @@ static int evdev_release(struct inode *inode, struct file *file)
kfree(client);
evdev_close_device(evdev);
put_device(&evdev->dev);
return 0;
}
@@ -331,7 +330,6 @@ static int evdev_open(struct inode *inode, struct file *file)
file->private_data = client;
nonseekable_open(inode, file);
get_device(&evdev->dev);
return 0;
err_free_client:
@@ -1001,6 +999,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
goto err_free_evdev;
cdev_init(&evdev->cdev, &evdev_fops);
evdev->cdev.kobj.parent = &evdev->dev.kobj;
error = cdev_add(&evdev->cdev, evdev->dev.devt, 1);
if (error)
goto err_unregister_handle;

View File

@@ -243,7 +243,6 @@ static int joydev_release(struct inode *inode, struct file *file)
kfree(client);
joydev_close_device(joydev);
put_device(&joydev->dev);
return 0;
}
@@ -270,7 +269,6 @@ static int joydev_open(struct inode *inode, struct file *file)
file->private_data = client;
nonseekable_open(inode, file);
get_device(&joydev->dev);
return 0;
err_free_client:
@@ -858,6 +856,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
goto err_free_joydev;
cdev_init(&joydev->cdev, &joydev_fops);
joydev->cdev.kobj.parent = &joydev->dev.kobj;
error = cdev_add(&joydev->cdev, joydev->dev.devt, 1);
if (error)
goto err_unregister_handle;

View File

@@ -533,7 +533,7 @@ config KEYBOARD_DAVINCI
config KEYBOARD_OMAP
tristate "TI OMAP keypad support"
depends on (ARCH_OMAP1 || ARCH_OMAP2)
depends on ARCH_OMAP1
select INPUT_MATRIXKMAP
help
Say Y here if you want to use the OMAP keypad.

View File

@@ -36,7 +36,7 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/keyscan.h>
#include <linux/platform_data/keyscan-davinci.h>
/* Key scan registers */
#define DAVINCI_KEYSCAN_KEYCTRL 0x0000

View File

@@ -29,7 +29,7 @@
#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/ep93xx_keypad.h>
#include <linux/platform_data/keypad-ep93xx.h>
/*
* Keypad Interface Register offsets

View File

@@ -358,6 +358,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad)
/* Inhibit KDI and KRI interrupts. */
reg_val = readw(keypad->mmio_base + KPSR);
reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE);
reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
writew(reg_val, keypad->mmio_base + KPSR);
/* Colums as open drain and disable all rows */
@@ -515,7 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev)
input_set_drvdata(input_dev, keypad);
/* Ensure that the keypad will stay dormant until opened */
clk_prepare_enable(keypad->clk);
imx_keypad_inhibit(keypad);
clk_disable_unprepare(keypad->clk);
error = request_irq(irq, imx_keypad_irq_handler, 0,
pdev->name, keypad);

View File

@@ -20,7 +20,7 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <plat/ske.h>
#include <linux/platform_data/keypad-nomadik-ske.h>
/* SKE_CR bits */
#define SKE_KPMLT (0x1 << 6)

View File

@@ -35,13 +35,9 @@
#include <linux/mutex.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <asm/gpio.h>
#include <plat/keypad.h>
#include <plat/menelaus.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <asm/io.h>
#include <plat/mux.h>
#include <linux/gpio.h>
#include <linux/platform_data/gpio-omap.h>
#include <linux/platform_data/keypad-omap.h>
#undef NEW_BOARD_LEARNING_MODE
@@ -96,28 +92,8 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp)
static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
{
struct omap_kp *omap_kp = dev_id;
/* disable keyboard interrupt and schedule for handling */
if (cpu_is_omap24xx()) {
int 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, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
tasklet_schedule(&kp_tasklet);
@@ -133,33 +109,22 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state)
{
int col = 0;
/* disable keyboard interrupt and schedule for handling */
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
/* read the keypad status */
if (cpu_is_omap24xx()) {
/* read the keypad status */
for (col = 0; col < omap_kp->cols; col++) {
set_col_gpio_val(omap_kp, ~(1 << col));
state[col] = ~(get_row_gpio_val(omap_kp)) & 0xff;
}
set_col_gpio_val(omap_kp, 0);
omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
for (col = 0; col < omap_kp->cols; col++) {
omap_writew(~(1 << col) & 0xff,
OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
} else {
/* disable keyboard interrupt and schedule for handling */
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
udelay(omap_kp->delay);
/* read the keypad status */
omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
for (col = 0; col < omap_kp->cols; col++) {
omap_writew(~(1 << col) & 0xff,
OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
udelay(omap_kp->delay);
state[col] = ~omap_readw(OMAP1_MPUIO_BASE +
OMAP_MPUIO_KBR_LATCH) & 0xff;
}
omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
udelay(2);
state[col] = ~omap_readw(OMAP1_MPUIO_BASE +
OMAP_MPUIO_KBR_LATCH) & 0xff;
}
omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
udelay(2);
}
static void omap_kp_tasklet(unsigned long data)
@@ -222,14 +187,8 @@ static void omap_kp_tasklet(unsigned long data)
mod_timer(&omap_kp_data->timer, jiffies + delay);
} else {
/* enable interrupts */
if (cpu_is_omap24xx()) {
int i;
for (i = 0; i < omap_kp_data->rows; i++)
enable_irq(gpio_to_irq(row_gpios[i]));
} else {
omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
kp_cur_group = -1;
}
omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
kp_cur_group = -1;
}
}
@@ -242,6 +201,7 @@ static ssize_t omap_kp_enable_show(struct device *dev,
static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct omap_kp *omap_kp = dev_get_drvdata(dev);
int state;
if (sscanf(buf, "%u", &state) != 1)
@@ -253,9 +213,9 @@ static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute
mutex_lock(&kp_enable_mutex);
if (state != kp_enable) {
if (state)
enable_irq(INT_KEYBOARD);
enable_irq(omap_kp->irq);
else
disable_irq(INT_KEYBOARD);
disable_irq(omap_kp->irq);
kp_enable = state;
}
mutex_unlock(&kp_enable_mutex);
@@ -289,7 +249,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
struct omap_kp *omap_kp;
struct input_dev *input_dev;
struct omap_kp_platform_data *pdata = pdev->dev.platform_data;
int i, col_idx, row_idx, irq_idx, ret;
int i, col_idx, row_idx, ret;
unsigned int row_shift, keycodemax;
if (!pdata->rows || !pdata->cols || !pdata->keymap_data) {
@@ -314,8 +274,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
omap_kp->input = input_dev;
/* Disable the interrupt for the MPUIO keyboard */
if (!cpu_is_omap24xx())
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
if (pdata->delay)
omap_kp->delay = pdata->delay;
@@ -328,31 +287,8 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
omap_kp->rows = pdata->rows;
omap_kp->cols = pdata->cols;
if (cpu_is_omap24xx()) {
/* Cols: outputs */
for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) {
if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) {
printk(KERN_ERR "Failed to request"
"GPIO%d for keypad\n",
col_gpios[col_idx]);
goto err1;
}
gpio_direction_output(col_gpios[col_idx], 0);
}
/* Rows: inputs */
for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) {
if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) {
printk(KERN_ERR "Failed to request"
"GPIO%d for keypad\n",
row_gpios[row_idx]);
goto err2;
}
gpio_direction_input(row_gpios[row_idx]);
}
} else {
col_idx = 0;
row_idx = 0;
}
col_idx = 0;
row_idx = 0;
setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp);
@@ -394,27 +330,16 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
/* scan current status and enable interrupt */
omap_kp_scan_keypad(omap_kp, keypad_state);
if (!cpu_is_omap24xx()) {
omap_kp->irq = platform_get_irq(pdev, 0);
if (omap_kp->irq >= 0) {
if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
"omap-keypad", omap_kp) < 0)
goto err4;
}
omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
} else {
for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) {
if (request_irq(gpio_to_irq(row_gpios[irq_idx]),
omap_kp_interrupt,
IRQF_TRIGGER_FALLING,
"omap-keypad", omap_kp) < 0)
goto err5;
}
omap_kp->irq = platform_get_irq(pdev, 0);
if (omap_kp->irq >= 0) {
if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
"omap-keypad", omap_kp) < 0)
goto err4;
}
omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
return 0;
err5:
for (i = irq_idx - 1; i >= 0; i--)
free_irq(row_gpios[i], omap_kp);
err4:
input_unregister_device(omap_kp->input);
input_dev = NULL;
@@ -423,7 +348,6 @@ err3:
err2:
for (i = row_idx - 1; i >= 0; i--)
gpio_free(row_gpios[i]);
err1:
for (i = col_idx - 1; i >= 0; i--)
gpio_free(col_gpios[i]);
@@ -439,18 +363,8 @@ static int __devexit omap_kp_remove(struct platform_device *pdev)
/* disable keypad interrupt handling */
tasklet_disable(&kp_tasklet);
if (cpu_is_omap24xx()) {
int i;
for (i = 0; i < omap_kp->cols; i++)
gpio_free(col_gpios[i]);
for (i = 0; i < omap_kp->rows; i++) {
gpio_free(row_gpios[i]);
free_irq(gpio_to_irq(row_gpios[i]), omap_kp);
}
} else {
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
free_irq(omap_kp->irq, omap_kp);
}
omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
free_irq(omap_kp->irq, omap_kp);
del_timer_sync(&omap_kp->timer);
tasklet_kill(&kp_tasklet);

View File

@@ -32,7 +32,7 @@
#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <plat/pxa27x_keypad.h>
#include <linux/platform_data/keypad-pxa27x.h>
/*
* Keypad Controller registers
*/

View File

@@ -15,7 +15,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <mach/pxa930_rotary.h>
#include <linux/platform_data/keyboard-pxa930_rotary.h>
#define SBCR (0x04)
#define ERCR (0x0c)

View File

@@ -156,8 +156,7 @@ static irqreturn_t qt2160_irq(int irq, void *_qt2160)
spin_lock_irqsave(&qt2160->lock, flags);
__cancel_delayed_work(&qt2160->dwork);
schedule_delayed_work(&qt2160->dwork, 0);
mod_delayed_work(system_wq, &qt2160->dwork, 0);
spin_unlock_irqrestore(&qt2160->lock, flags);

View File

@@ -24,7 +24,7 @@
#include <linux/pm_wakeup.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <plat/keyboard.h>
#include <linux/platform_data/keyboard-spear.h>
/* Keyboard Registers */
#define MODE_CTL_REG 0x00

View File

@@ -21,7 +21,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <mach/w90p910_keypad.h>
#include <linux/platform_data/keypad-w90p910.h>
/* Keypad Interface Control Registers */
#define KPI_CONF 0x00

View File

@@ -74,8 +74,8 @@ static int __devinit ab8500_ponkey_probe(struct platform_device *pdev)
ponkey->idev = input;
ponkey->ab8500 = ab8500;
ponkey->irq_dbf = ab8500_irq_get_virq(ab8500, irq_dbf);
ponkey->irq_dbr = ab8500_irq_get_virq(ab8500, irq_dbr);
ponkey->irq_dbf = irq_dbf;
ponkey->irq_dbr = irq_dbr;
input->name = "AB8500 POn(PowerOn) Key";
input->dev.parent = &pdev->dev;

View File

@@ -151,22 +151,7 @@ static struct acpi_driver atlas_acpi_driver = {
.remove = atlas_acpi_button_remove,
},
};
static int __init atlas_acpi_init(void)
{
if (acpi_disabled)
return -ENODEV;
return acpi_bus_register_driver(&atlas_acpi_driver);
}
static void __exit atlas_acpi_exit(void)
{
acpi_bus_unregister_driver(&atlas_acpi_driver);
}
module_init(atlas_acpi_init);
module_exit(atlas_acpi_exit);
module_acpi_driver(atlas_acpi_driver);
MODULE_AUTHOR("Jaya Kumar");
MODULE_LICENSE("GPL");

View File

@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/workqueue.h>
#include <linux/i2c/twl.h>
#include <linux/mfd/twl4030-audio.h>
@@ -194,13 +195,26 @@ static int twl4030_vibra_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
twl4030_vibra_suspend, twl4030_vibra_resume);
static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
struct device_node *node)
{
if (pdata && pdata->coexist)
return true;
if (of_find_node_by_name(node, "codec"))
return true;
return false;
}
static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
{
struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
struct device_node *twl4030_core_node = pdev->dev.parent->of_node;
struct vibra_info *info;
int ret;
if (!pdata) {
if (!pdata && !twl4030_core_node) {
dev_dbg(&pdev->dev, "platform_data not available\n");
return -EINVAL;
}
@@ -210,7 +224,7 @@ static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
return -ENOMEM;
info->dev = &pdev->dev;
info->coexist = pdata->coexist;
info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node);
INIT_WORK(&info->play_work, vibra_play_work);
info->input_dev = input_allocate_device();

View File

@@ -20,7 +20,7 @@
#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/pxa930_trkball.h>
#include <linux/platform_data/mouse-pxa930_trkball.h>
/* Trackball Controller Register Definitions */
#define TBCR (0x000C)

View File

@@ -42,7 +42,7 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id)
x = (short) iomd_readl(IOMD_MOUSEX);
y = (short) iomd_readl(IOMD_MOUSEY);
b = (short) (__raw_readl(0xe0310000) ^ 0x70);
b = (short) (__raw_readl(IOMEM(0xe0310000)) ^ 0x70);
dx = x - rpcmouse_lastx;
dy = y - rpcmouse_lasty;

View File

@@ -721,6 +721,17 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
case FSP_PKT_TYPE_ABS:
if ((packet[0] == 0x48 || packet[0] == 0x49) &&
packet[1] == 0 && packet[2] == 0) {
/*
* Ignore coordinate noise when finger leaving the
* surface, otherwise cursor may jump to upper-left
* corner.
*/
packet[3] &= 0xf0;
}
abs_x = GET_ABS_X(packet);
abs_y = GET_ABS_Y(packet);

View File

@@ -53,14 +53,19 @@
#define ABS_POS_BITS 13
/*
* Any position values from the hardware above the following limits are
* treated as "wrapped around negative" values that have been truncated to
* the 13-bit reporting range of the hardware. These are just reasonable
* guesses and can be adjusted if hardware is found that operates outside
* of these parameters.
* These values should represent the absolute maximum value that will
* be reported for a positive position value. Some Synaptics firmware
* uses this value to indicate a finger near the edge of the touchpad
* whose precise position cannot be determined.
*
* At least one touchpad is known to report positions in excess of this
* value which are actually negative values truncated to the 13-bit
* reporting range. These values have never been observed to be lower
* than 8184 (i.e. -8), so we treat all values greater than 8176 as
* negative and any other value as positive.
*/
#define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2)
#define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2)
#define X_MAX_POSITIVE 8176
#define Y_MAX_POSITIVE 8176
/*****************************************************************************
* Stuff we need even when we do not want native Synaptics support
@@ -604,11 +609,21 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
hw->right = (buf[0] & 0x02) ? 1 : 0;
}
/* Convert wrap-around values to negative */
/*
* Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE
* is used by some firmware to indicate a finger at the edge of
* the touchpad whose precise position cannot be determined, so
* convert these values to the maximum axis value.
*/
if (hw->x > X_MAX_POSITIVE)
hw->x -= 1 << ABS_POS_BITS;
else if (hw->x == X_MAX_POSITIVE)
hw->x = XMAX;
if (hw->y > Y_MAX_POSITIVE)
hw->y -= 1 << ABS_POS_BITS;
else if (hw->y == Y_MAX_POSITIVE)
hw->y = YMAX;
return 0;
}

View File

@@ -376,12 +376,7 @@ static void synaptics_i2c_reschedule_work(struct synaptics_i2c *touch,
spin_lock_irqsave(&touch->lock, flags);
/*
* If work is already scheduled then subsequent schedules will not
* change the scheduled time that's why we have to cancel it first.
*/
__cancel_delayed_work(&touch->dwork);
schedule_delayed_work(&touch->dwork, delay);
mod_delayed_work(system_wq, &touch->dwork, delay);
spin_unlock_irqrestore(&touch->lock, flags);
}

View File

@@ -523,7 +523,6 @@ static int mousedev_release(struct inode *inode, struct file *file)
kfree(client);
mousedev_close_device(mousedev);
put_device(&mousedev->dev);
return 0;
}
@@ -558,7 +557,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
file->private_data = client;
nonseekable_open(inode, file);
get_device(&mousedev->dev);
return 0;
err_free_client:
@@ -892,6 +890,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
}
cdev_init(&mousedev->cdev, &mousedev_fops);
mousedev->cdev.kobj.parent = &mousedev->dev.kobj;
error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1);
if (error)
goto err_unregister_handle;

View File

@@ -72,7 +72,7 @@ static int amba_kmi_open(struct serio *io)
unsigned int divisor;
int ret;
ret = clk_enable(kmi->clk);
ret = clk_prepare_enable(kmi->clk);
if (ret)
goto out;
@@ -92,7 +92,7 @@ static int amba_kmi_open(struct serio *io)
return 0;
clk_disable:
clk_disable(kmi->clk);
clk_disable_unprepare(kmi->clk);
out:
return ret;
}
@@ -104,7 +104,7 @@ static void amba_kmi_close(struct serio *io)
writeb(0, KMICR);
free_irq(kmi->irq, kmi);
clk_disable(kmi->clk);
clk_disable_unprepare(kmi->clk);
}
static int __devinit amba_kmi_probe(struct amba_device *dev,

View File

@@ -27,7 +27,7 @@
#include <linux/module.h>
#include <asm/mach-types.h>
#include <plat/board-ams-delta.h>
#include <mach/board-ams-delta.h>
#include <mach/ams-delta-fiq.h>

View File

@@ -176,6 +176,20 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"),
},
},
{
/* Gigabyte T1005 - defines wrong chassis type ("Other") */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
DMI_MATCH(DMI_PRODUCT_NAME, "T1005"),
},
},
{
/* Gigabyte T1005M/P - defines wrong chassis type ("Other") */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
@@ -319,6 +333,12 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),

View File

@@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
features->pktlen = WACOM_PKGLEN_TPC2FG;
}
if (features->type == MTSCREEN)
if (features->type == MTSCREEN || WACOM_24HDT)
features->pktlen = WACOM_PKGLEN_MTOUCH;
if (features->type == BAMBOO_PT) {
@@ -402,6 +402,14 @@ static int wacom_parse_hid(struct usb_interface *intf,
features->x_max =
get_unaligned_le16(&report[i + 8]);
i += 15;
} else if (features->type == WACOM_24HDT) {
features->x_max =
get_unaligned_le16(&report[i + 3]);
features->x_phy =
get_unaligned_le16(&report[i + 8]);
features->unit = report[i - 1];
features->unitExpo = report[i - 3];
i += 12;
} else {
features->x_max =
get_unaligned_le16(&report[i + 3]);
@@ -434,6 +442,12 @@ static int wacom_parse_hid(struct usb_interface *intf,
features->y_phy =
get_unaligned_le16(&report[i + 6]);
i += 7;
} else if (type == WACOM_24HDT) {
features->y_max =
get_unaligned_le16(&report[i + 3]);
features->y_phy =
get_unaligned_le16(&report[i - 2]);
i += 7;
} else if (type == BAMBOO_PT) {
features->y_phy =
get_unaligned_le16(&report[i + 3]);
@@ -541,6 +555,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
/* MT Tablet PC touch */
return wacom_set_device_mode(intf, 3, 4, 4);
}
else if (features->type == WACOM_24HDT) {
return wacom_set_device_mode(intf, 18, 3, 2);
}
} else if (features->device_type == BTN_TOOL_PEN) {
if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
return wacom_set_device_mode(intf, 2, 2, 2);
@@ -613,6 +630,30 @@ struct wacom_usbdev_data {
static LIST_HEAD(wacom_udev_list);
static DEFINE_MUTEX(wacom_udev_list_lock);
static struct usb_device *wacom_get_sibling(struct usb_device *dev, int vendor, int product)
{
int port1;
struct usb_device *sibling;
if (vendor == 0 && product == 0)
return dev;
if (dev->parent == NULL)
return NULL;
usb_hub_for_each_child(dev->parent, port1, sibling) {
struct usb_device_descriptor *d;
if (sibling == NULL)
continue;
d = &sibling->descriptor;
if (d->idVendor == vendor && d->idProduct == product)
return sibling;
}
return NULL;
}
static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
{
struct wacom_usbdev_data *data;
@@ -1257,13 +1298,19 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
struct usb_device *other_dev;
/* Append the device type to the name */
strlcat(wacom_wac->name,
features->device_type == BTN_TOOL_PEN ?
" Pen" : " Finger",
sizeof(wacom_wac->name));
error = wacom_add_shared_data(wacom_wac, dev);
other_dev = wacom_get_sibling(dev, features->oVid, features->oPid);
if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL)
other_dev = dev;
error = wacom_add_shared_data(wacom_wac, other_dev);
if (error)
goto fail3;
}

View File

@@ -611,7 +611,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
input_report_abs(input, ABS_WHEEL, 0);
}
if (data[2] | (data[3] & 0x01) | data[4]) {
if (data[2] | (data[3] & 0x01) | data[4] | data[5]) {
input_report_key(input, wacom->tool[1], 1);
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
@@ -806,6 +806,70 @@ static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid)
return -1;
}
static int int_dist(int x1, int y1, int x2, int y2)
{
int x = x2 - x1;
int y = y2 - y1;
return int_sqrt(x*x + y*y);
}
static int wacom_24hdt_irq(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
char *data = wacom->data;
int i;
int current_num_contacts = data[61];
int contacts_to_send = 0;
/*
* First packet resets the counter since only the first
* packet in series will have non-zero current_num_contacts.
*/
if (current_num_contacts)
wacom->num_contacts_left = current_num_contacts;
/* There are at most 4 contacts per packet */
contacts_to_send = min(4, wacom->num_contacts_left);
for (i = 0; i < contacts_to_send; i++) {
int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1;
bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity;
int id = data[offset + 1];
int slot = find_slot_from_contactid(wacom, id);
if (slot < 0)
continue;
input_mt_slot(input, slot);
input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
if (touch) {
int t_x = le16_to_cpup((__le16 *)&data[offset + 2]);
int c_x = le16_to_cpup((__le16 *)&data[offset + 4]);
int t_y = le16_to_cpup((__le16 *)&data[offset + 6]);
int c_y = le16_to_cpup((__le16 *)&data[offset + 8]);
int w = le16_to_cpup((__le16 *)&data[offset + 10]);
int h = le16_to_cpup((__le16 *)&data[offset + 12]);
input_report_abs(input, ABS_MT_POSITION_X, t_x);
input_report_abs(input, ABS_MT_POSITION_Y, t_y);
input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y));
input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
input_report_abs(input, ABS_MT_ORIENTATION, w > h);
}
wacom->slots[slot] = touch ? id : -1;
}
input_mt_report_pointer_emulation(input, true);
wacom->num_contacts_left -= contacts_to_send;
if (wacom->num_contacts_left <= 0)
wacom->num_contacts_left = 0;
return 1;
}
static int wacom_mt_touch(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
@@ -1255,6 +1319,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
sync = wacom_intuos_irq(wacom_wac);
break;
case WACOM_24HDT:
sync = wacom_24hdt_irq(wacom_wac);
break;
case INTUOS5S:
case INTUOS5:
case INTUOS5L:
@@ -1340,7 +1408,8 @@ void wacom_setup_device_quirks(struct wacom_features *features)
/* these device have multiple inputs */
if (features->type >= WIRELESS ||
(features->type >= INTUOS5S && features->type <= INTUOS5L))
(features->type >= INTUOS5S && features->type <= INTUOS5L) ||
(features->oVid && features->oPid))
features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */
@@ -1575,6 +1644,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
break;
case WACOM_24HDT:
if (features->device_type == BTN_TOOL_FINGER) {
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0);
input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0);
input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
}
/* fall through */
case MTSCREEN:
if (features->device_type == BTN_TOOL_FINGER) {
wacom_wac->slots = kmalloc(features->touch_max *
@@ -1869,8 +1947,11 @@ static const struct wacom_features wacom_features_0xF4 =
{ "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047,
63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
static const struct wacom_features wacom_features_0xF8 =
{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047,
63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */
63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
static const struct wacom_features wacom_features_0xF6 =
{ "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 };
static const struct wacom_features wacom_features_0x3F =
{ "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023,
63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
@@ -2113,6 +2194,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x47) },
{ USB_DEVICE_WACOM(0xF4) },
{ USB_DEVICE_WACOM(0xF8) },
{ USB_DEVICE_WACOM(0xF6) },
{ USB_DEVICE_WACOM(0xFA) },
{ USB_DEVICE_LENOVO(0x6004) },
{ }

View File

@@ -29,6 +29,7 @@
/* wacom data size per MT contact */
#define WACOM_BYTES_PER_MT_PACKET 11
#define WACOM_BYTES_PER_24HDT_PACKET 14
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
@@ -49,6 +50,7 @@
#define WACOM_REPORT_TPCHID 15
#define WACOM_REPORT_TPCST 16
#define WACOM_REPORT_TPC1FGE 18
#define WACOM_REPORT_24HDT 1
/* device quirks */
#define WACOM_QUIRK_MULTI_INPUT 0x0001
@@ -81,6 +83,7 @@ enum {
WACOM_MO,
WIRELESS,
BAMBOO_PT,
WACOM_24HDT,
TABLETPC, /* add new TPC below */
TABLETPCE,
TABLETPC2FG,
@@ -109,6 +112,8 @@ struct wacom_features {
int distance_fuzz;
unsigned quirks;
unsigned touch_max;
int oVid;
int oPid;
};
struct wacom_shared {

View File

@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/input.h>
@@ -113,14 +114,69 @@ static void pm860x_touch_close(struct input_dev *dev)
pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
}
#ifdef CONFIG_OF
static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
struct pm860x_chip *chip,
int *res_x)
{
struct device_node *np = pdev->dev.parent->of_node;
struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
: chip->companion;
int data, n, ret;
if (!np)
return -ENODEV;
np = of_find_node_by_name(np, "touch");
if (!np) {
dev_err(&pdev->dev, "Can't find touch node\n");
return -EINVAL;
}
/* set GPADC MISC1 register */
data = 0;
if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-prebias", &n))
data |= (n << 1) & PM8607_GPADC_PREBIAS_MASK;
if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-slot-cycle", &n))
data |= (n << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-off-scale", &n))
data |= (n << 5) & PM8607_GPADC_OFF_SCALE_MASK;
if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-sw-cal", &n))
data |= (n << 7) & PM8607_GPADC_SW_CAL_MASK;
if (data) {
ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
if (ret < 0)
return -EINVAL;
}
/* set tsi prebias time */
if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
if (ret < 0)
return -EINVAL;
}
/* set prebias & prechg time of pen detect */
data = 0;
if (!of_property_read_u32(np, "marvell,88pm860x-pen-prebias", &n))
data |= n & PM8607_PD_PREBIAS_MASK;
if (!of_property_read_u32(np, "marvell,88pm860x-pen-prechg", &n))
data |= n & PM8607_PD_PRECHG_MASK;
if (data) {
ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
if (ret < 0)
return -EINVAL;
}
of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
return 0;
}
#else
#define pm860x_touch_dt_init(x, y, z) (-1)
#endif
static int __devinit pm860x_touch_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm860x_platform_data *pm860x_pdata = \
pdev->dev.parent->platform_data;
struct pm860x_touch_pdata *pdata = NULL;
struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
struct pm860x_touch *touch;
int irq, ret;
struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
: chip->companion;
int irq, ret, res_x = 0, data = 0;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -128,16 +184,55 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
return -EINVAL;
}
if (!pm860x_pdata) {
dev_err(&pdev->dev, "platform data is missing\n");
return -EINVAL;
}
pdata = pm860x_pdata->touch;
if (!pdata) {
dev_err(&pdev->dev, "touchscreen data is missing\n");
return -EINVAL;
if (pm860x_touch_dt_init(pdev, chip, &res_x)) {
if (pdata) {
/* set GPADC MISC1 register */
data = 0;
data |= (pdata->gpadc_prebias << 1)
& PM8607_GPADC_PREBIAS_MASK;
data |= (pdata->slot_cycle << 3)
& PM8607_GPADC_SLOT_CYCLE_MASK;
data |= (pdata->off_scale << 5)
& PM8607_GPADC_OFF_SCALE_MASK;
data |= (pdata->sw_cal << 7)
& PM8607_GPADC_SW_CAL_MASK;
if (data) {
ret = pm860x_reg_write(i2c,
PM8607_GPADC_MISC1, data);
if (ret < 0)
return -EINVAL;
}
/* set tsi prebias time */
if (pdata->tsi_prebias) {
data = pdata->tsi_prebias;
ret = pm860x_reg_write(i2c,
PM8607_TSI_PREBIAS, data);
if (ret < 0)
return -EINVAL;
}
/* set prebias & prechg time of pen detect */
data = 0;
data |= pdata->pen_prebias
& PM8607_PD_PREBIAS_MASK;
data |= (pdata->pen_prechg << 5)
& PM8607_PD_PRECHG_MASK;
if (data) {
ret = pm860x_reg_write(i2c,
PM8607_PD_PREBIAS, data);
if (ret < 0)
return -EINVAL;
}
res_x = pdata->res_x;
} else {
dev_err(&pdev->dev, "failed to get platform data\n");
return -EINVAL;
}
}
/* enable GPADC */
ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, PM8607_GPADC_EN,
PM8607_GPADC_EN);
if (ret)
return ret;
touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
if (touch == NULL)
@@ -158,9 +253,9 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
touch->idev->open = pm860x_touch_open;
touch->idev->close = pm860x_touch_close;
touch->chip = chip;
touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
touch->irq = irq + chip->irq_base;
touch->res_x = pdata->res_x;
touch->i2c = i2c;
touch->irq = irq;
touch->res_x = res_x;
input_set_drvdata(touch->idev, touch);
ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,

View File

@@ -558,9 +558,12 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
}
read = min_t(size_t, count, tsdata->raw_bufsize - *off);
error = copy_to_user(buf, tsdata->raw_buffer + *off, read);
if (!error)
*off += read;
if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) {
error = -EFAULT;
goto out;
}
*off += read;
out:
mutex_unlock(&tsdata->mutex);
return error ?: read;
@@ -594,6 +597,7 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
{
if (tsdata->debug_dir)
debugfs_remove_recursive(tsdata->debug_dir);
kfree(tsdata->raw_buffer);
}
#else
@@ -835,7 +839,6 @@ static int __devexit edt_ft5x06_ts_remove(struct i2c_client *client)
if (gpio_is_valid(pdata->reset_pin))
gpio_free(pdata->reset_pin);
kfree(tsdata->raw_buffer);
kfree(tsdata);
return 0;

View File

@@ -37,7 +37,7 @@
#include <plat/adc.h>
#include <plat/regs-adc.h>
#include <plat/ts.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
#define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))

View File

@@ -304,6 +304,45 @@ static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
#define EGALAX_PKT_TYPE_REPT 0x80
#define EGALAX_PKT_TYPE_DIAG 0x0A
static int egalax_init(struct usbtouch_usb *usbtouch)
{
int ret, i;
unsigned char *buf;
struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
/*
* An eGalax diagnostic packet kicks the device into using the right
* protocol. We send a "check active" packet. The response will be
* read later and ignored.
*/
buf = kmalloc(3, GFP_KERNEL);
if (!buf)
return -ENOMEM;
buf[0] = EGALAX_PKT_TYPE_DIAG;
buf[1] = 1; /* length */
buf[2] = 'A'; /* command - check active */
for (i = 0; i < 3; i++) {
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, 0, buf, 3,
USB_CTRL_SET_TIMEOUT);
if (ret >= 0) {
ret = 0;
break;
}
if (ret != -EPIPE)
break;
}
kfree(buf);
return ret;
}
static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
{
if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
@@ -1056,6 +1095,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
.process_pkt = usbtouch_process_multi,
.get_pkt_len = egalax_get_pkt_len,
.read_data = egalax_read_data,
.init = egalax_init,
},
#endif

View File

@@ -221,7 +221,7 @@ static void wm831x_ts_input_close(struct input_dev *idev)
synchronize_irq(wm831x_ts->pd_irq);
/* Make sure the IRQ completion work is quiesced */
flush_work_sync(&wm831x_ts->pd_data_work);
flush_work(&wm831x_ts->pd_data_work);
/* If we ended up with the pen down then make sure we revert back
* to pen detection state for the next time we start up.