Commit ec0337e0 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 second round of input updates from Dmitry Torokhov:
 "A new driver for Weida wdt87xx touch controllers, and a bunch of
  fixups for other drivers"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: wdt87xx_i2c - add a scaling factor for TOUCH_MAJOR event
  Input: wdt87xx_i2c - remove stray newline in diagnostic message
  Input: arc_ps2 - add HAS_IOMEM dependency
  Input: wdt87xx_i2c - fix format warning
  Input: improve parsing OF parameters for touchscreens
  Input: edt-ft5x06 - mark as direct input device
  Input: use for_each_set_bit() where appropriate
  Input: add a driver for wdt87xx touchscreen controller
  Input: axp20x-pek - fix reporting button state as inverted
  Input: xpad - re-send LED command on present event
  Input: xpad - set the LEDs properly on XBox Wireless controllers
  Input: imx_keypad - check for clk_prepare_enable() error
parents 5c65e7be a5cba18c
...@@ -677,12 +677,9 @@ static void input_dev_release_keys(struct input_dev *dev) ...@@ -677,12 +677,9 @@ static void input_dev_release_keys(struct input_dev *dev)
int code; int code;
if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) { if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
for (code = 0; code <= KEY_MAX; code++) { for_each_set_bit(code, dev->key, KEY_CNT)
if (is_event_supported(code, dev->keybit, KEY_MAX) && input_pass_event(dev, EV_KEY, code, 0);
__test_and_clear_bit(code, dev->key)) { memset(dev->key, 0, sizeof(dev->key));
input_pass_event(dev, EV_KEY, code, 0);
}
}
input_pass_event(dev, EV_SYN, SYN_REPORT, 1); input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
} }
} }
...@@ -1626,10 +1623,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) ...@@ -1626,10 +1623,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
if (!test_bit(EV_##type, dev->evbit)) \ if (!test_bit(EV_##type, dev->evbit)) \
break; \ break; \
\ \
for (i = 0; i < type##_MAX; i++) { \ for_each_set_bit(i, dev->bits##bit, type##_CNT) { \
if (!test_bit(i, dev->bits##bit)) \
continue; \
\
active = test_bit(i, dev->bits); \ active = test_bit(i, dev->bits); \
if (!active && !on) \ if (!active && !on) \
continue; \ continue; \
...@@ -1980,22 +1974,12 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) ...@@ -1980,22 +1974,12 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */
if (test_bit(EV_ABS, dev->evbit)) { if (test_bit(EV_ABS, dev->evbit))
for (i = 0; i < ABS_CNT; i++) { for_each_set_bit(i, dev->absbit, ABS_CNT)
if (test_bit(i, dev->absbit)) { events += input_is_mt_axis(i) ? mt_slots : 1;
if (input_is_mt_axis(i))
events += mt_slots;
else
events++;
}
}
}
if (test_bit(EV_REL, dev->evbit)) { if (test_bit(EV_REL, dev->evbit))
for (i = 0; i < REL_CNT; i++) events += bitmap_weight(dev->relbit, REL_CNT);
if (test_bit(i, dev->relbit))
events++;
}
/* Make room for KEY and MSC events */ /* Make room for KEY and MSC events */
events += 7; events += 7;
......
...@@ -344,6 +344,7 @@ struct usb_xpad { ...@@ -344,6 +344,7 @@ struct usb_xpad {
int mapping; /* map d-pad to buttons or to axes */ int mapping; /* map d-pad to buttons or to axes */
int xtype; /* type of xbox device */ int xtype; /* type of xbox device */
unsigned long led_no; /* led to lit on xbox360 controllers */
}; };
/* /*
...@@ -488,6 +489,8 @@ static void xpad360_process_packet(struct usb_xpad *xpad, ...@@ -488,6 +489,8 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
input_sync(dev); input_sync(dev);
} }
static void xpad_identify_controller(struct usb_xpad *xpad);
/* /*
* xpad360w_process_packet * xpad360w_process_packet
* *
...@@ -510,6 +513,11 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha ...@@ -510,6 +513,11 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
if (data[1] & 0x80) { if (data[1] & 0x80) {
xpad->pad_present = 1; xpad->pad_present = 1;
usb_submit_urb(xpad->bulk_out, GFP_ATOMIC); usb_submit_urb(xpad->bulk_out, GFP_ATOMIC);
/*
* Light up the segment corresponding to
* controller number.
*/
xpad_identify_controller(xpad);
} else } else
xpad->pad_present = 0; xpad->pad_present = 0;
} }
...@@ -881,17 +889,63 @@ struct xpad_led { ...@@ -881,17 +889,63 @@ struct xpad_led {
struct usb_xpad *xpad; struct usb_xpad *xpad;
}; };
/**
* @param command
* 0: off
* 1: all blink, then previous setting
* 2: 1/top-left blink, then on
* 3: 2/top-right blink, then on
* 4: 3/bottom-left blink, then on
* 5: 4/bottom-right blink, then on
* 6: 1/top-left on
* 7: 2/top-right on
* 8: 3/bottom-left on
* 9: 4/bottom-right on
* 10: rotate
* 11: blink, based on previous setting
* 12: slow blink, based on previous setting
* 13: rotate with two lights
* 14: persistent slow all blink
* 15: blink once, then previous setting
*/
static void xpad_send_led_command(struct usb_xpad *xpad, int command) static void xpad_send_led_command(struct usb_xpad *xpad, int command)
{ {
if (command >= 0 && command < 14) { command %= 16;
mutex_lock(&xpad->odata_mutex);
mutex_lock(&xpad->odata_mutex);
switch (xpad->xtype) {
case XTYPE_XBOX360:
xpad->odata[0] = 0x01; xpad->odata[0] = 0x01;
xpad->odata[1] = 0x03; xpad->odata[1] = 0x03;
xpad->odata[2] = command; xpad->odata[2] = command;
xpad->irq_out->transfer_buffer_length = 3; xpad->irq_out->transfer_buffer_length = 3;
usb_submit_urb(xpad->irq_out, GFP_KERNEL); break;
mutex_unlock(&xpad->odata_mutex); case XTYPE_XBOX360W:
xpad->odata[0] = 0x00;
xpad->odata[1] = 0x00;
xpad->odata[2] = 0x08;
xpad->odata[3] = 0x40 + command;
xpad->odata[4] = 0x00;
xpad->odata[5] = 0x00;
xpad->odata[6] = 0x00;
xpad->odata[7] = 0x00;
xpad->odata[8] = 0x00;
xpad->odata[9] = 0x00;
xpad->odata[10] = 0x00;
xpad->odata[11] = 0x00;
xpad->irq_out->transfer_buffer_length = 12;
break;
} }
usb_submit_urb(xpad->irq_out, GFP_KERNEL);
mutex_unlock(&xpad->odata_mutex);
}
static void xpad_identify_controller(struct usb_xpad *xpad)
{
/* Light up the segment corresponding to controller number */
xpad_send_led_command(xpad, (xpad->led_no % 4) + 2);
} }
static void xpad_led_set(struct led_classdev *led_cdev, static void xpad_led_set(struct led_classdev *led_cdev,
...@@ -905,22 +959,21 @@ static void xpad_led_set(struct led_classdev *led_cdev, ...@@ -905,22 +959,21 @@ static void xpad_led_set(struct led_classdev *led_cdev,
static int xpad_led_probe(struct usb_xpad *xpad) static int xpad_led_probe(struct usb_xpad *xpad)
{ {
static atomic_t led_seq = ATOMIC_INIT(-1); static atomic_t led_seq = ATOMIC_INIT(-1);
unsigned long led_no;
struct xpad_led *led; struct xpad_led *led;
struct led_classdev *led_cdev; struct led_classdev *led_cdev;
int error; int error;
if (xpad->xtype != XTYPE_XBOX360) if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W)
return 0; return 0;
xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL); xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL);
if (!led) if (!led)
return -ENOMEM; return -ENOMEM;
led_no = atomic_inc_return(&led_seq); xpad->led_no = atomic_inc_return(&led_seq);
snprintf(led->name, sizeof(led->name), "xpad%lu", led_no); snprintf(led->name, sizeof(led->name), "xpad%lu", xpad->led_no);
led->xpad = xpad; led->xpad = xpad;
led_cdev = &led->led_cdev; led_cdev = &led->led_cdev;
...@@ -934,10 +987,8 @@ static int xpad_led_probe(struct usb_xpad *xpad) ...@@ -934,10 +987,8 @@ static int xpad_led_probe(struct usb_xpad *xpad)
return error; return error;
} }
/* /* Light up the segment corresponding to controller number */
* Light up the segment corresponding to controller number xpad_identify_controller(xpad);
*/
xpad_send_led_command(xpad, (led_no % 4) + 2);
return 0; return 0;
} }
...@@ -954,6 +1005,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) ...@@ -954,6 +1005,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad)
#else #else
static int xpad_led_probe(struct usb_xpad *xpad) { return 0; } static int xpad_led_probe(struct usb_xpad *xpad) { return 0; }
static void xpad_led_disconnect(struct usb_xpad *xpad) { } static void xpad_led_disconnect(struct usb_xpad *xpad) { }
static void xpad_identify_controller(struct usb_xpad *xpad) { }
#endif #endif
......
...@@ -506,7 +506,9 @@ static int imx_keypad_probe(struct platform_device *pdev) ...@@ -506,7 +506,9 @@ static int imx_keypad_probe(struct platform_device *pdev)
input_set_drvdata(input_dev, keypad); input_set_drvdata(input_dev, keypad);
/* Ensure that the keypad will stay dormant until opened */ /* Ensure that the keypad will stay dormant until opened */
clk_prepare_enable(keypad->clk); error = clk_prepare_enable(keypad->clk);
if (error)
return error;
imx_keypad_inhibit(keypad); imx_keypad_inhibit(keypad);
clk_disable_unprepare(keypad->clk); clk_disable_unprepare(keypad->clk);
......
...@@ -167,9 +167,13 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr) ...@@ -167,9 +167,13 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
struct input_dev *idev = pwr; struct input_dev *idev = pwr;
struct axp20x_pek *axp20x_pek = input_get_drvdata(idev); struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);
if (irq == axp20x_pek->irq_dbr) /*
* The power-button is connected to ground so a falling edge (dbf)
* means it is pressed.
*/
if (irq == axp20x_pek->irq_dbf)
input_report_key(idev, KEY_POWER, true); input_report_key(idev, KEY_POWER, true);
else if (irq == axp20x_pek->irq_dbf) else if (irq == axp20x_pek->irq_dbr)
input_report_key(idev, KEY_POWER, false); input_report_key(idev, KEY_POWER, false);
input_sync(idev); input_sync(idev);
......
...@@ -244,6 +244,7 @@ config SERIO_PS2MULT ...@@ -244,6 +244,7 @@ config SERIO_PS2MULT
config SERIO_ARC_PS2 config SERIO_ARC_PS2
tristate "ARC PS/2 support" tristate "ARC PS/2 support"
depends on HAS_IOMEM
help help
Say Y here if you have an ARC FPGA platform with a PS/2 Say Y here if you have an ARC FPGA platform with a PS/2
controller in it. controller in it.
......
...@@ -658,6 +658,18 @@ config TOUCHSCREEN_PIXCIR ...@@ -658,6 +658,18 @@ config TOUCHSCREEN_PIXCIR
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called pixcir_i2c_ts. module will be called pixcir_i2c_ts.
config TOUCHSCREEN_WDT87XX_I2C
tristate "Weida HiTech I2C touchscreen"
depends on I2C
help
Say Y here if you have a Weida WDT87XX I2C touchscreen
connected to your system.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called wdt87xx_i2c.
config TOUCHSCREEN_WM831X config TOUCHSCREEN_WM831X
tristate "Support for WM831x touchscreen controllers" tristate "Support for WM831x touchscreen controllers"
depends on MFD_WM831X depends on MFD_WM831X
......
...@@ -72,6 +72,7 @@ obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o ...@@ -72,6 +72,7 @@ obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
obj-$(CONFIG_TOUCHSCREEN_WACOM_I2C) += wacom_i2c.o obj-$(CONFIG_TOUCHSCREEN_WACOM_I2C) += wacom_i2c.o
obj-$(CONFIG_TOUCHSCREEN_WDT87XX_I2C) += wdt87xx_i2c.o
obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o
obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
......
...@@ -1035,20 +1035,15 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, ...@@ -1035,20 +1035,15 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
input->id.bustype = BUS_I2C; input->id.bustype = BUS_I2C;
input->dev.parent = &client->dev; input->dev.parent = &client->dev;
__set_bit(EV_KEY, input->evbit);
__set_bit(EV_ABS, input->evbit);
__set_bit(BTN_TOUCH, input->keybit);
input_set_abs_params(input, ABS_X, 0, tsdata->num_x * 64 - 1, 0, 0);
input_set_abs_params(input, ABS_Y, 0, tsdata->num_y * 64 - 1, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_X, input_set_abs_params(input, ABS_MT_POSITION_X,
0, tsdata->num_x * 64 - 1, 0, 0); 0, tsdata->num_x * 64 - 1, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y, input_set_abs_params(input, ABS_MT_POSITION_Y,
0, tsdata->num_y * 64 - 1, 0, 0); 0, tsdata->num_y * 64 - 1, 0, 0);
if (!pdata) if (!pdata)
touchscreen_parse_of_params(input); touchscreen_parse_of_params(input, true);
error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0); error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, INPUT_MT_DIRECT);
if (error) { if (error) {
dev_err(&client->dev, "Unable to init MT slots.\n"); dev_err(&client->dev, "Unable to init MT slots.\n");
return error; return error;
......
...@@ -14,14 +14,22 @@ ...@@ -14,14 +14,22 @@
#include <linux/input/mt.h> #include <linux/input/mt.h>
#include <linux/input/touchscreen.h> #include <linux/input/touchscreen.h>
static u32 of_get_optional_u32(struct device_node *np, static bool touchscreen_get_prop_u32(struct device_node *np,
const char *property) const char *property,
unsigned int default_value,
unsigned int *value)
{ {
u32 val = 0; u32 val;
int error;
of_property_read_u32(np, property, &val); error = of_property_read_u32(np, property, &val);
if (error) {
*value = default_value;
return false;
}
return val; *value = val;
return true;
} }
static void touchscreen_set_params(struct input_dev *dev, static void touchscreen_set_params(struct input_dev *dev,
...@@ -54,34 +62,45 @@ static void touchscreen_set_params(struct input_dev *dev, ...@@ -54,34 +62,45 @@ static void touchscreen_set_params(struct input_dev *dev,
* input device accordingly. The function keeps previously setuped default * input device accordingly. The function keeps previously setuped default
* values if no value is specified via DT. * values if no value is specified via DT.
*/ */
void touchscreen_parse_of_params(struct input_dev *dev) void touchscreen_parse_of_params(struct input_dev *dev, bool multitouch)
{ {
struct device_node *np = dev->dev.parent->of_node; struct device_node *np = dev->dev.parent->of_node;
u32 maximum, fuzz; unsigned int axis;
unsigned int maximum, fuzz;
bool data_present;
input_alloc_absinfo(dev); input_alloc_absinfo(dev);
if (!dev->absinfo) if (!dev->absinfo)
return; return;
maximum = of_get_optional_u32(np, "touchscreen-size-x"); axis = multitouch ? ABS_MT_POSITION_X : ABS_X;
fuzz = of_get_optional_u32(np, "touchscreen-fuzz-x"); data_present = touchscreen_get_prop_u32(np, "touchscreen-size-x",
if (maximum || fuzz) { input_abs_get_max(dev, axis),
touchscreen_set_params(dev, ABS_X, maximum, fuzz); &maximum) |
touchscreen_set_params(dev, ABS_MT_POSITION_X, maximum, fuzz); touchscreen_get_prop_u32(np, "touchscreen-fuzz-x",
} input_abs_get_fuzz(dev, axis),
&fuzz);
if (data_present)
touchscreen_set_params(dev, axis, maximum, fuzz);
maximum = of_get_optional_u32(np, "touchscreen-size-y"); axis = multitouch ? ABS_MT_POSITION_Y : ABS_Y;
fuzz = of_get_optional_u32(np, "touchscreen-fuzz-y"); data_present = touchscreen_get_prop_u32(np, "touchscreen-size-y",
if (maximum || fuzz) { input_abs_get_max(dev, axis),
touchscreen_set_params(dev, ABS_Y, maximum, fuzz); &maximum) |
touchscreen_set_params(dev, ABS_MT_POSITION_Y, maximum, fuzz); touchscreen_get_prop_u32(np, "touchscreen-fuzz-y",
} input_abs_get_fuzz(dev, axis),
&fuzz);
if (data_present)
touchscreen_set_params(dev, axis, maximum, fuzz);
maximum = of_get_optional_u32(np, "touchscreen-max-pressure"); axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE;
fuzz = of_get_optional_u32(np, "touchscreen-fuzz-pressure"); data_present = touchscreen_get_prop_u32(np, "touchscreen-max-pressure",
if (maximum || fuzz) { input_abs_get_max(dev, axis),
touchscreen_set_params(dev, ABS_PRESSURE, maximum, fuzz); &maximum) |
touchscreen_set_params(dev, ABS_MT_PRESSURE, maximum, fuzz); touchscreen_get_prop_u32(np, "touchscreen-fuzz-pressure",
} input_abs_get_fuzz(dev, axis),
&fuzz);
if (data_present)
touchscreen_set_params(dev, axis, maximum, fuzz);
} }
EXPORT_SYMBOL(touchscreen_parse_of_params); EXPORT_SYMBOL(touchscreen_parse_of_params);
...@@ -709,7 +709,7 @@ static int tsc2005_probe(struct spi_device *spi) ...@@ -709,7 +709,7 @@ static int tsc2005_probe(struct spi_device *spi)
input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);
if (np) if (np)
touchscreen_parse_of_params(input_dev); touchscreen_parse_of_params(input_dev, false);
input_dev->open = tsc2005_open; input_dev->open = tsc2005_open;
input_dev->close = tsc2005_close; input_dev->close = tsc2005_close;
......
This diff is collapsed.
...@@ -12,9 +12,10 @@ ...@@ -12,9 +12,10 @@
#include <linux/input.h> #include <linux/input.h>
#ifdef CONFIG_OF #ifdef CONFIG_OF
void touchscreen_parse_of_params(struct input_dev *dev); void touchscreen_parse_of_params(struct input_dev *dev, bool multitouch);
#else #else
static inline void touchscreen_parse_of_params(struct input_dev *dev) static inline void touchscreen_parse_of_params(struct input_dev *dev,
bool multitouch)
{ {
} }
#endif #endif
......
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