Commit d16eea2f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input fixes from Dmitry Torokhov:
 "Just a few random driver fixups"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: synaptics - add a second working PNP_ID for Lenovo T470s
  Input: applespi - replace zero-length array with flexible-array
  Input: axp20x-pek - always register interrupt handlers
  Input: lm8333 - update contact email
  Input: synaptics-rmi4 - fix error return code in rmi_driver_probe()
  Input: synaptics-rmi4 - really fix attn_data use-after-free
  Input: i8042 - add ThinkPad S230u to i8042 reset list
  Revert "Input: i8042 - add ThinkPad S230u to i8042 nomux list"
  Input: dlink-dir685-touchkeys - fix a typo in driver name
  Input: xpad - add custom init packet for Xbox One S controllers
  Input: evdev - call input_flush_device() on release(), not flush()
  Input: i8042 - add ThinkPad S230u to i8042 nomux list
  Input: usbtouchscreen - add support for BonXeon TP
  Input: cros_ec_keyb - use cros_ec_cmd_xfer_status helper
  Input: mms114 - fix handling of mms345l
  Input: elants_i2c - support palm detection
parents 6b5f2590 642aa86e
...@@ -326,20 +326,6 @@ static int evdev_fasync(int fd, struct file *file, int on) ...@@ -326,20 +326,6 @@ static int evdev_fasync(int fd, struct file *file, int on)
return fasync_helper(fd, file, on, &client->fasync); return fasync_helper(fd, file, on, &client->fasync);
} }
static int evdev_flush(struct file *file, fl_owner_t id)
{
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
mutex_lock(&evdev->mutex);
if (evdev->exist && !client->revoked)
input_flush_device(&evdev->handle, file);
mutex_unlock(&evdev->mutex);
return 0;
}
static void evdev_free(struct device *dev) static void evdev_free(struct device *dev)
{ {
struct evdev *evdev = container_of(dev, struct evdev, dev); struct evdev *evdev = container_of(dev, struct evdev, dev);
...@@ -453,6 +439,10 @@ static int evdev_release(struct inode *inode, struct file *file) ...@@ -453,6 +439,10 @@ static int evdev_release(struct inode *inode, struct file *file)
unsigned int i; unsigned int i;
mutex_lock(&evdev->mutex); mutex_lock(&evdev->mutex);
if (evdev->exist && !client->revoked)
input_flush_device(&evdev->handle, file);
evdev_ungrab(evdev, client); evdev_ungrab(evdev, client);
mutex_unlock(&evdev->mutex); mutex_unlock(&evdev->mutex);
...@@ -1310,7 +1300,6 @@ static const struct file_operations evdev_fops = { ...@@ -1310,7 +1300,6 @@ static const struct file_operations evdev_fops = {
.compat_ioctl = evdev_ioctl_compat, .compat_ioctl = evdev_ioctl_compat,
#endif #endif
.fasync = evdev_fasync, .fasync = evdev_fasync,
.flush = evdev_flush,
.llseek = no_llseek, .llseek = no_llseek,
}; };
......
...@@ -458,6 +458,16 @@ static const u8 xboxone_fw2015_init[] = { ...@@ -458,6 +458,16 @@ static const u8 xboxone_fw2015_init[] = {
0x05, 0x20, 0x00, 0x01, 0x00 0x05, 0x20, 0x00, 0x01, 0x00
}; };
/*
* This packet is required for Xbox One S (0x045e:0x02ea)
* and Xbox One Elite Series 2 (0x045e:0x0b00) pads to
* initialize the controller that was previously used in
* Bluetooth mode.
*/
static const u8 xboxone_s_init[] = {
0x05, 0x20, 0x00, 0x0f, 0x06
};
/* /*
* This packet is required for the Titanfall 2 Xbox One pads * This packet is required for the Titanfall 2 Xbox One pads
* (0x0e6f:0x0165) to finish initialization and for Hori pads * (0x0e6f:0x0165) to finish initialization and for Hori pads
...@@ -516,6 +526,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { ...@@ -516,6 +526,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = {
XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init),
XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init),
XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1), XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1),
XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2), XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2),
XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
......
...@@ -186,7 +186,7 @@ struct touchpad_protocol { ...@@ -186,7 +186,7 @@ struct touchpad_protocol {
u8 number_of_fingers; u8 number_of_fingers;
u8 clicked2; u8 clicked2;
u8 unknown3[16]; u8 unknown3[16];
struct tp_finger fingers[0]; struct tp_finger fingers[];
}; };
/** /**
......
...@@ -347,18 +347,14 @@ static int cros_ec_keyb_info(struct cros_ec_device *ec_dev, ...@@ -347,18 +347,14 @@ static int cros_ec_keyb_info(struct cros_ec_device *ec_dev,
params->info_type = info_type; params->info_type = info_type;
params->event_type = event_type; params->event_type = event_type;
ret = cros_ec_cmd_xfer(ec_dev, msg); ret = cros_ec_cmd_xfer_status(ec_dev, msg);
if (ret < 0) { if (ret == -ENOTSUPP) {
dev_warn(ec_dev->dev, "Transfer error %d/%d: %d\n",
(int)info_type, (int)event_type, ret);
} else if (msg->result == EC_RES_INVALID_VERSION) {
/* With older ECs we just return 0 for everything */ /* With older ECs we just return 0 for everything */
memset(result, 0, result_size); memset(result, 0, result_size);
ret = 0; ret = 0;
} else if (msg->result != EC_RES_SUCCESS) { } else if (ret < 0) {
dev_warn(ec_dev->dev, "Error getting info %d/%d: %d\n", dev_warn(ec_dev->dev, "Transfer error %d/%d: %d\n",
(int)info_type, (int)event_type, msg->result); (int)info_type, (int)event_type, ret);
ret = -EPROTO;
} else if (ret != result_size) { } else if (ret != result_size) {
dev_warn(ec_dev->dev, "Wrong size %d/%d: %d != %zu\n", dev_warn(ec_dev->dev, "Wrong size %d/%d: %d != %zu\n",
(int)info_type, (int)event_type, (int)info_type, (int)event_type,
......
...@@ -143,7 +143,7 @@ MODULE_DEVICE_TABLE(of, dir685_tk_of_match); ...@@ -143,7 +143,7 @@ MODULE_DEVICE_TABLE(of, dir685_tk_of_match);
static struct i2c_driver dir685_tk_i2c_driver = { static struct i2c_driver dir685_tk_i2c_driver = {
.driver = { .driver = {
.name = "dlin-dir685-touchkeys", .name = "dlink-dir685-touchkeys",
.of_match_table = of_match_ptr(dir685_tk_of_match), .of_match_table = of_match_ptr(dir685_tk_of_match),
}, },
.probe = dir685_tk_probe, .probe = dir685_tk_probe,
......
...@@ -205,8 +205,11 @@ ATTRIBUTE_GROUPS(axp20x); ...@@ -205,8 +205,11 @@ ATTRIBUTE_GROUPS(axp20x);
static irqreturn_t axp20x_pek_irq(int irq, void *pwr) static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
{ {
struct input_dev *idev = pwr; struct axp20x_pek *axp20x_pek = pwr;
struct axp20x_pek *axp20x_pek = input_get_drvdata(idev); struct input_dev *idev = axp20x_pek->input;
if (!idev)
return IRQ_HANDLED;
/* /*
* The power-button is connected to ground so a falling edge (dbf) * The power-button is connected to ground so a falling edge (dbf)
...@@ -225,22 +228,9 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr) ...@@ -225,22 +228,9 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek, static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
struct platform_device *pdev) struct platform_device *pdev)
{ {
struct axp20x_dev *axp20x = axp20x_pek->axp20x;
struct input_dev *idev; struct input_dev *idev;
int error; int error;
axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
if (axp20x_pek->irq_dbr < 0)
return axp20x_pek->irq_dbr;
axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
axp20x_pek->irq_dbr);
axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
if (axp20x_pek->irq_dbf < 0)
return axp20x_pek->irq_dbf;
axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
axp20x_pek->irq_dbf);
axp20x_pek->input = devm_input_allocate_device(&pdev->dev); axp20x_pek->input = devm_input_allocate_device(&pdev->dev);
if (!axp20x_pek->input) if (!axp20x_pek->input)
return -ENOMEM; return -ENOMEM;
...@@ -255,24 +245,6 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek, ...@@ -255,24 +245,6 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
input_set_drvdata(idev, axp20x_pek); input_set_drvdata(idev, axp20x_pek);
error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr,
axp20x_pek_irq, 0,
"axp20x-pek-dbr", idev);
if (error < 0) {
dev_err(&pdev->dev, "Failed to request dbr IRQ#%d: %d\n",
axp20x_pek->irq_dbr, error);
return error;
}
error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbf,
axp20x_pek_irq, 0,
"axp20x-pek-dbf", idev);
if (error < 0) {
dev_err(&pdev->dev, "Failed to request dbf IRQ#%d: %d\n",
axp20x_pek->irq_dbf, error);
return error;
}
error = input_register_device(idev); error = input_register_device(idev);
if (error) { if (error) {
dev_err(&pdev->dev, "Can't register input device: %d\n", dev_err(&pdev->dev, "Can't register input device: %d\n",
...@@ -280,8 +252,6 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek, ...@@ -280,8 +252,6 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
return error; return error;
} }
device_init_wakeup(&pdev->dev, true);
return 0; return 0;
} }
...@@ -339,6 +309,18 @@ static int axp20x_pek_probe(struct platform_device *pdev) ...@@ -339,6 +309,18 @@ static int axp20x_pek_probe(struct platform_device *pdev)
axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent); axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
if (axp20x_pek->irq_dbr < 0)
return axp20x_pek->irq_dbr;
axp20x_pek->irq_dbr = regmap_irq_get_virq(
axp20x_pek->axp20x->regmap_irqc, axp20x_pek->irq_dbr);
axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
if (axp20x_pek->irq_dbf < 0)
return axp20x_pek->irq_dbf;
axp20x_pek->irq_dbf = regmap_irq_get_virq(
axp20x_pek->axp20x->regmap_irqc, axp20x_pek->irq_dbf);
if (axp20x_pek_should_register_input(axp20x_pek, pdev)) { if (axp20x_pek_should_register_input(axp20x_pek, pdev)) {
error = axp20x_pek_probe_input_device(axp20x_pek, pdev); error = axp20x_pek_probe_input_device(axp20x_pek, pdev);
if (error) if (error)
...@@ -347,6 +329,26 @@ static int axp20x_pek_probe(struct platform_device *pdev) ...@@ -347,6 +329,26 @@ static int axp20x_pek_probe(struct platform_device *pdev)
axp20x_pek->info = (struct axp20x_info *)match->driver_data; axp20x_pek->info = (struct axp20x_info *)match->driver_data;
error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr,
axp20x_pek_irq, 0,
"axp20x-pek-dbr", axp20x_pek);
if (error < 0) {
dev_err(&pdev->dev, "Failed to request dbr IRQ#%d: %d\n",
axp20x_pek->irq_dbr, error);
return error;
}
error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbf,
axp20x_pek_irq, 0,
"axp20x-pek-dbf", axp20x_pek);
if (error < 0) {
dev_err(&pdev->dev, "Failed to request dbf IRQ#%d: %d\n",
axp20x_pek->irq_dbf, error);
return error;
}
device_init_wakeup(&pdev->dev, true);
platform_set_drvdata(pdev, axp20x_pek); platform_set_drvdata(pdev, axp20x_pek);
return 0; return 0;
......
...@@ -170,6 +170,7 @@ static const char * const smbus_pnp_ids[] = { ...@@ -170,6 +170,7 @@ static const char * const smbus_pnp_ids[] = {
"LEN005b", /* P50 */ "LEN005b", /* P50 */
"LEN005e", /* T560 */ "LEN005e", /* T560 */
"LEN006c", /* T470s */ "LEN006c", /* T470s */
"LEN007a", /* T470s */
"LEN0071", /* T480 */ "LEN0071", /* T480 */
"LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */ "LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */
"LEN0073", /* X1 Carbon G5 (Elantech) */ "LEN0073", /* X1 Carbon G5 (Elantech) */
......
...@@ -205,7 +205,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id) ...@@ -205,7 +205,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
if (count) { if (count) {
kfree(attn_data.data); kfree(attn_data.data);
attn_data.data = NULL; drvdata->attn_data.data = NULL;
} }
if (!kfifo_is_empty(&drvdata->attn_fifo)) if (!kfifo_is_empty(&drvdata->attn_fifo))
...@@ -1210,7 +1210,8 @@ static int rmi_driver_probe(struct device *dev) ...@@ -1210,7 +1210,8 @@ static int rmi_driver_probe(struct device *dev)
if (data->input) { if (data->input) {
rmi_driver_set_input_name(rmi_dev, data->input); rmi_driver_set_input_name(rmi_dev, data->input);
if (!rmi_dev->xport->input) { if (!rmi_dev->xport->input) {
if (input_register_device(data->input)) { retval = input_register_device(data->input);
if (retval) {
dev_err(dev, "%s: Failed to register input device.\n", dev_err(dev, "%s: Failed to register input device.\n",
__func__); __func__);
goto err_destroy_functions; goto err_destroy_functions;
......
...@@ -662,6 +662,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { ...@@ -662,6 +662,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
}, },
}, },
{
/* Lenovo ThinkPad Twist S230u */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"),
},
},
{ } { }
}; };
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include <linux/bits.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -73,6 +74,7 @@ ...@@ -73,6 +74,7 @@
#define FW_POS_STATE 1 #define FW_POS_STATE 1
#define FW_POS_TOTAL 2 #define FW_POS_TOTAL 2
#define FW_POS_XY 3 #define FW_POS_XY 3
#define FW_POS_TOOL_TYPE 33
#define FW_POS_CHECKSUM 34 #define FW_POS_CHECKSUM 34
#define FW_POS_WIDTH 35 #define FW_POS_WIDTH 35
#define FW_POS_PRESSURE 45 #define FW_POS_PRESSURE 45
...@@ -842,6 +844,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf) ...@@ -842,6 +844,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
{ {
struct input_dev *input = ts->input; struct input_dev *input = ts->input;
unsigned int n_fingers; unsigned int n_fingers;
unsigned int tool_type;
u16 finger_state; u16 finger_state;
int i; int i;
...@@ -852,6 +855,10 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf) ...@@ -852,6 +855,10 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
dev_dbg(&ts->client->dev, dev_dbg(&ts->client->dev,
"n_fingers: %u, state: %04x\n", n_fingers, finger_state); "n_fingers: %u, state: %04x\n", n_fingers, finger_state);
/* Note: all fingers have the same tool type */
tool_type = buf[FW_POS_TOOL_TYPE] & BIT(0) ?
MT_TOOL_FINGER : MT_TOOL_PALM;
for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) { for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) {
if (finger_state & 1) { if (finger_state & 1) {
unsigned int x, y, p, w; unsigned int x, y, p, w;
...@@ -867,7 +874,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf) ...@@ -867,7 +874,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
i, x, y, p, w); i, x, y, p, w);
input_mt_slot(input, i); input_mt_slot(input, i);
input_mt_report_slot_state(input, MT_TOOL_FINGER, true); input_mt_report_slot_state(input, tool_type, true);
input_event(input, EV_ABS, ABS_MT_POSITION_X, x); input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
input_event(input, EV_ABS, ABS_MT_POSITION_Y, y); input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
input_event(input, EV_ABS, ABS_MT_PRESSURE, p); input_event(input, EV_ABS, ABS_MT_PRESSURE, p);
...@@ -1307,6 +1314,8 @@ static int elants_i2c_probe(struct i2c_client *client, ...@@ -1307,6 +1314,8 @@ static int elants_i2c_probe(struct i2c_client *client,
input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0); input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0);
input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, 255, 0, 0); input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
input_set_abs_params(ts->input, ABS_MT_TOOL_TYPE,
0, MT_TOOL_PALM, 0, 0);
input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res); input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res);
input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res); input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1); input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1);
......
...@@ -91,15 +91,15 @@ static int __mms114_read_reg(struct mms114_data *data, unsigned int reg, ...@@ -91,15 +91,15 @@ static int __mms114_read_reg(struct mms114_data *data, unsigned int reg,
if (reg <= MMS114_MODE_CONTROL && reg + len > MMS114_MODE_CONTROL) if (reg <= MMS114_MODE_CONTROL && reg + len > MMS114_MODE_CONTROL)
BUG(); BUG();
/* Write register: use repeated start */ /* Write register */
xfer[0].addr = client->addr; xfer[0].addr = client->addr;
xfer[0].flags = I2C_M_TEN | I2C_M_NOSTART; xfer[0].flags = client->flags & I2C_M_TEN;
xfer[0].len = 1; xfer[0].len = 1;
xfer[0].buf = &buf; xfer[0].buf = &buf;
/* Read data */ /* Read data */
xfer[1].addr = client->addr; xfer[1].addr = client->addr;
xfer[1].flags = I2C_M_RD; xfer[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
xfer[1].len = len; xfer[1].len = len;
xfer[1].buf = val; xfer[1].buf = val;
...@@ -428,10 +428,8 @@ static int mms114_probe(struct i2c_client *client, ...@@ -428,10 +428,8 @@ static int mms114_probe(struct i2c_client *client,
const void *match_data; const void *match_data;
int error; int error;
if (!i2c_check_functionality(client->adapter, if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
I2C_FUNC_PROTOCOL_MANGLING)) { dev_err(&client->dev, "Not supported I2C adapter\n");
dev_err(&client->dev,
"Need i2c bus that supports protocol mangling\n");
return -ENODEV; return -ENODEV;
} }
......
...@@ -182,6 +182,7 @@ static const struct usb_device_id usbtouch_devices[] = { ...@@ -182,6 +182,7 @@ static const struct usb_device_id usbtouch_devices[] = {
#endif #endif
#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
{USB_DEVICE(0x255e, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
{USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
{USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
{USB_DEVICE(0x6615, 0x0012), .driver_info = DEVTYPE_IRTOUCH_HIRES}, {USB_DEVICE(0x6615, 0x0012), .driver_info = DEVTYPE_IRTOUCH_HIRES},
......
/* /*
* public include for LM8333 keypad driver - same license as driver * public include for LM8333 keypad driver - same license as driver
* Copyright (C) 2012 Wolfram Sang, Pengutronix <w.sang@pengutronix.de> * Copyright (C) 2012 Wolfram Sang, Pengutronix <kernel@pengutronix.de>
*/ */
#ifndef _LM8333_H #ifndef _LM8333_H
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment