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)
int code;
if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
for (code = 0; code <= KEY_MAX; code++) {
if (is_event_supported(code, dev->keybit, KEY_MAX) &&
__test_and_clear_bit(code, dev->key)) {
input_pass_event(dev, EV_KEY, code, 0);
}
}
for_each_set_bit(code, dev->key, KEY_CNT)
input_pass_event(dev, EV_KEY, code, 0);
memset(dev->key, 0, sizeof(dev->key));
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)
if (!test_bit(EV_##type, dev->evbit)) \
break; \
\
for (i = 0; i < type##_MAX; i++) { \
if (!test_bit(i, dev->bits##bit)) \
continue; \
\
for_each_set_bit(i, dev->bits##bit, type##_CNT) { \
active = test_bit(i, dev->bits); \
if (!active && !on) \
continue; \
......@@ -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 */
if (test_bit(EV_ABS, dev->evbit)) {
for (i = 0; i < ABS_CNT; i++) {
if (test_bit(i, dev->absbit)) {
if (input_is_mt_axis(i))
events += mt_slots;
else
events++;
}
}
}
if (test_bit(EV_ABS, dev->evbit))
for_each_set_bit(i, dev->absbit, ABS_CNT)
events += input_is_mt_axis(i) ? mt_slots : 1;
if (test_bit(EV_REL, dev->evbit)) {
for (i = 0; i < REL_CNT; i++)
if (test_bit(i, dev->relbit))
events++;
}
if (test_bit(EV_REL, dev->evbit))
events += bitmap_weight(dev->relbit, REL_CNT);
/* Make room for KEY and MSC events */
events += 7;
......
......@@ -344,6 +344,7 @@ struct usb_xpad {
int mapping; /* map d-pad to buttons or to axes */
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,
input_sync(dev);
}
static void xpad_identify_controller(struct usb_xpad *xpad);
/*
* xpad360w_process_packet
*
......@@ -510,6 +513,11 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
if (data[1] & 0x80) {
xpad->pad_present = 1;
usb_submit_urb(xpad->bulk_out, GFP_ATOMIC);
/*
* Light up the segment corresponding to
* controller number.
*/
xpad_identify_controller(xpad);
} else
xpad->pad_present = 0;
}
......@@ -881,17 +889,63 @@ struct xpad_led {
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)
{
if (command >= 0 && command < 14) {
mutex_lock(&xpad->odata_mutex);
command %= 16;
mutex_lock(&xpad->odata_mutex);
switch (xpad->xtype) {
case XTYPE_XBOX360:
xpad->odata[0] = 0x01;
xpad->odata[1] = 0x03;
xpad->odata[2] = command;
xpad->irq_out->transfer_buffer_length = 3;
usb_submit_urb(xpad->irq_out, GFP_KERNEL);
mutex_unlock(&xpad->odata_mutex);
break;
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,
......@@ -905,22 +959,21 @@ static void xpad_led_set(struct led_classdev *led_cdev,
static int xpad_led_probe(struct usb_xpad *xpad)
{
static atomic_t led_seq = ATOMIC_INIT(-1);
unsigned long led_no;
static atomic_t led_seq = ATOMIC_INIT(-1);
struct xpad_led *led;
struct led_classdev *led_cdev;
int error;
if (xpad->xtype != XTYPE_XBOX360)
if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W)
return 0;
xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL);
if (!led)
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_cdev = &led->led_cdev;
......@@ -934,10 +987,8 @@ static int xpad_led_probe(struct usb_xpad *xpad)
return error;
}
/*
* Light up the segment corresponding to controller number
*/
xpad_send_led_command(xpad, (led_no % 4) + 2);
/* Light up the segment corresponding to controller number */
xpad_identify_controller(xpad);
return 0;
}
......@@ -954,6 +1005,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad)
#else
static int xpad_led_probe(struct usb_xpad *xpad) { return 0; }
static void xpad_led_disconnect(struct usb_xpad *xpad) { }
static void xpad_identify_controller(struct usb_xpad *xpad) { }
#endif
......
......@@ -506,7 +506,9 @@ static int 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);
error = clk_prepare_enable(keypad->clk);
if (error)
return error;
imx_keypad_inhibit(keypad);
clk_disable_unprepare(keypad->clk);
......
......@@ -167,9 +167,13 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
struct input_dev *idev = pwr;
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);
else if (irq == axp20x_pek->irq_dbf)
else if (irq == axp20x_pek->irq_dbr)
input_report_key(idev, KEY_POWER, false);
input_sync(idev);
......
......@@ -244,6 +244,7 @@ config SERIO_PS2MULT
config SERIO_ARC_PS2
tristate "ARC PS/2 support"
depends on HAS_IOMEM
help
Say Y here if you have an ARC FPGA platform with a PS/2
controller in it.
......
......@@ -658,6 +658,18 @@ config TOUCHSCREEN_PIXCIR
To compile this driver as a module, choose M here: the
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
tristate "Support for WM831x touchscreen controllers"
depends on MFD_WM831X
......
......@@ -72,6 +72,7 @@ obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.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_WM97XX) += wm97xx-ts.o
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
......
......@@ -1035,20 +1035,15 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
input->id.bustype = BUS_I2C;
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,
0, tsdata->num_x * 64 - 1, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y,
0, tsdata->num_y * 64 - 1, 0, 0);
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) {
dev_err(&client->dev, "Unable to init MT slots.\n");
return error;
......
......@@ -14,14 +14,22 @@
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
static u32 of_get_optional_u32(struct device_node *np,
const char *property)
static bool touchscreen_get_prop_u32(struct device_node *np,
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,
......@@ -54,34 +62,45 @@ static void touchscreen_set_params(struct input_dev *dev,
* input device accordingly. The function keeps previously setuped default
* 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;
u32 maximum, fuzz;
unsigned int axis;
unsigned int maximum, fuzz;
bool data_present;
input_alloc_absinfo(dev);
if (!dev->absinfo)
return;
maximum = of_get_optional_u32(np, "touchscreen-size-x");
fuzz = of_get_optional_u32(np, "touchscreen-fuzz-x");
if (maximum || fuzz) {
touchscreen_set_params(dev, ABS_X, maximum, fuzz);
touchscreen_set_params(dev, ABS_MT_POSITION_X, maximum, fuzz);
}
axis = multitouch ? ABS_MT_POSITION_X : ABS_X;
data_present = touchscreen_get_prop_u32(np, "touchscreen-size-x",
input_abs_get_max(dev, axis),
&maximum) |
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");
fuzz = of_get_optional_u32(np, "touchscreen-fuzz-y");
if (maximum || fuzz) {
touchscreen_set_params(dev, ABS_Y, maximum, fuzz);
touchscreen_set_params(dev, ABS_MT_POSITION_Y, maximum, fuzz);
}
axis = multitouch ? ABS_MT_POSITION_Y : ABS_Y;
data_present = touchscreen_get_prop_u32(np, "touchscreen-size-y",
input_abs_get_max(dev, axis),
&maximum) |
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");
fuzz = of_get_optional_u32(np, "touchscreen-fuzz-pressure");
if (maximum || fuzz) {
touchscreen_set_params(dev, ABS_PRESSURE, maximum, fuzz);
touchscreen_set_params(dev, ABS_MT_PRESSURE, maximum, fuzz);
}
axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE;
data_present = touchscreen_get_prop_u32(np, "touchscreen-max-pressure",
input_abs_get_max(dev, axis),
&maximum) |
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);
......@@ -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);
if (np)
touchscreen_parse_of_params(input_dev);
touchscreen_parse_of_params(input_dev, false);
input_dev->open = tsc2005_open;
input_dev->close = tsc2005_close;
......
This diff is collapsed.
......@@ -12,9 +12,10 @@
#include <linux/input.h>
#ifdef CONFIG_OF
void touchscreen_parse_of_params(struct input_dev *dev);
void touchscreen_parse_of_params(struct input_dev *dev, bool multitouch);
#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
......
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