Skip to content

Commit e5f468b

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input fixes from Dmitry Torokhov: - joydev now implements a blacklist to avoid creating joystick nodes for accelerometers found in composite devices such as PlaStation controllers - assorted driver fixes * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: ims-psu - check if CDC union descriptor is sane Input: joydev - blacklist ds3/ds4/udraw motion sensors Input: allow matching device IDs on property bits Input: factor out and export input_device_id matching code Input: goodix - poll the 'buffer status' bit before reading data Input: axp20x-pek - fix module not auto-loading for axp221 pek Input: tca8418 - enable interrupt after it has been requested Input: stmfts - fix setting ABS_MT_POSITION_* maximum size Input: ti_am335x_tsc - fix incorrect step config for 5 wire touchscreen Input: synaptics - disable kernel tracking on SMBus devices
2 parents ec0145e + ea04efe commit e5f468b

File tree

13 files changed

+199
-97
lines changed

13 files changed

+199
-97
lines changed

drivers/input/input.c

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -933,58 +933,52 @@ int input_set_keycode(struct input_dev *dev,
933933
}
934934
EXPORT_SYMBOL(input_set_keycode);
935935

936+
bool input_match_device_id(const struct input_dev *dev,
937+
const struct input_device_id *id)
938+
{
939+
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
940+
if (id->bustype != dev->id.bustype)
941+
return false;
942+
943+
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
944+
if (id->vendor != dev->id.vendor)
945+
return false;
946+
947+
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
948+
if (id->product != dev->id.product)
949+
return false;
950+
951+
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
952+
if (id->version != dev->id.version)
953+
return false;
954+
955+
if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX) ||
956+
!bitmap_subset(id->keybit, dev->keybit, KEY_MAX) ||
957+
!bitmap_subset(id->relbit, dev->relbit, REL_MAX) ||
958+
!bitmap_subset(id->absbit, dev->absbit, ABS_MAX) ||
959+
!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX) ||
960+
!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX) ||
961+
!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX) ||
962+
!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX) ||
963+
!bitmap_subset(id->swbit, dev->swbit, SW_MAX) ||
964+
!bitmap_subset(id->propbit, dev->propbit, INPUT_PROP_MAX)) {
965+
return false;
966+
}
967+
968+
return true;
969+
}
970+
EXPORT_SYMBOL(input_match_device_id);
971+
936972
static const struct input_device_id *input_match_device(struct input_handler *handler,
937973
struct input_dev *dev)
938974
{
939975
const struct input_device_id *id;
940976

941977
for (id = handler->id_table; id->flags || id->driver_info; id++) {
942-
943-
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
944-
if (id->bustype != dev->id.bustype)
945-
continue;
946-
947-
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
948-
if (id->vendor != dev->id.vendor)
949-
continue;
950-
951-
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
952-
if (id->product != dev->id.product)
953-
continue;
954-
955-
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
956-
if (id->version != dev->id.version)
957-
continue;
958-
959-
if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX))
960-
continue;
961-
962-
if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX))
963-
continue;
964-
965-
if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX))
966-
continue;
967-
968-
if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX))
969-
continue;
970-
971-
if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX))
972-
continue;
973-
974-
if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX))
975-
continue;
976-
977-
if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX))
978-
continue;
979-
980-
if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX))
981-
continue;
982-
983-
if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX))
984-
continue;
985-
986-
if (!handler->match || handler->match(handler, dev))
978+
if (input_match_device_id(dev, id) &&
979+
(!handler->match || handler->match(handler, dev))) {
987980
return id;
981+
}
988982
}
989983

990984
return NULL;

drivers/input/joydev.c

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,68 @@ static void joydev_cleanup(struct joydev *joydev)
747747
input_close_device(handle);
748748
}
749749

750+
/*
751+
* These codes are copied from from hid-ids.h, unfortunately there is no common
752+
* usb_ids/bt_ids.h header.
753+
*/
754+
#define USB_VENDOR_ID_SONY 0x054c
755+
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
756+
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER 0x05c4
757+
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 0x09cc
758+
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE 0x0ba0
759+
760+
#define USB_VENDOR_ID_THQ 0x20d6
761+
#define USB_DEVICE_ID_THQ_PS3_UDRAW 0xcb17
762+
763+
#define ACCEL_DEV(vnd, prd) \
764+
{ \
765+
.flags = INPUT_DEVICE_ID_MATCH_VENDOR | \
766+
INPUT_DEVICE_ID_MATCH_PRODUCT | \
767+
INPUT_DEVICE_ID_MATCH_PROPBIT, \
768+
.vendor = (vnd), \
769+
.product = (prd), \
770+
.propbit = { BIT_MASK(INPUT_PROP_ACCELEROMETER) }, \
771+
}
772+
773+
static const struct input_device_id joydev_blacklist[] = {
774+
/* Avoid touchpads and touchscreens */
775+
{
776+
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
777+
INPUT_DEVICE_ID_MATCH_KEYBIT,
778+
.evbit = { BIT_MASK(EV_KEY) },
779+
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
780+
},
781+
/* Avoid tablets, digitisers and similar devices */
782+
{
783+
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
784+
INPUT_DEVICE_ID_MATCH_KEYBIT,
785+
.evbit = { BIT_MASK(EV_KEY) },
786+
.keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
787+
},
788+
/* Disable accelerometers on composite devices */
789+
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
790+
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
791+
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
792+
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE),
793+
ACCEL_DEV(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW),
794+
{ /* sentinel */ }
795+
};
796+
797+
static bool joydev_dev_is_blacklisted(struct input_dev *dev)
798+
{
799+
const struct input_device_id *id;
800+
801+
for (id = joydev_blacklist; id->flags; id++) {
802+
if (input_match_device_id(dev, id)) {
803+
dev_dbg(&dev->dev,
804+
"joydev: blacklisting '%s'\n", dev->name);
805+
return true;
806+
}
807+
}
808+
809+
return false;
810+
}
811+
750812
static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
751813
{
752814
DECLARE_BITMAP(jd_scratch, KEY_CNT);
@@ -807,12 +869,8 @@ static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
807869

808870
static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
809871
{
810-
/* Avoid touchpads and touchscreens */
811-
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
812-
return false;
813-
814-
/* Avoid tablets, digitisers and similar devices */
815-
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
872+
/* Disable blacklisted devices */
873+
if (joydev_dev_is_blacklisted(dev))
816874
return false;
817875

818876
/* Avoid absolute mice */

drivers/input/keyboard/tca8418_keypad.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,7 @@ static irqreturn_t tca8418_irq_handler(int irq, void *dev_id)
234234
static int tca8418_configure(struct tca8418_keypad *keypad_data,
235235
u32 rows, u32 cols)
236236
{
237-
int reg, error;
238-
239-
/* Write config register, if this fails assume device not present */
240-
error = tca8418_write_byte(keypad_data, REG_CFG,
241-
CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
242-
if (error < 0)
243-
return -ENODEV;
244-
237+
int reg, error = 0;
245238

246239
/* Assemble a mask for row and column registers */
247240
reg = ~(~0 << rows);
@@ -257,6 +250,12 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
257250
error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8);
258251
error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16);
259252

253+
if (error)
254+
return error;
255+
256+
error = tca8418_write_byte(keypad_data, REG_CFG,
257+
CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
258+
260259
return error;
261260
}
262261

@@ -268,6 +267,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
268267
struct input_dev *input;
269268
u32 rows = 0, cols = 0;
270269
int error, row_shift, max_keys;
270+
u8 reg;
271271

272272
/* Check i2c driver capabilities */
273273
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
@@ -301,10 +301,10 @@ static int tca8418_keypad_probe(struct i2c_client *client,
301301
keypad_data->client = client;
302302
keypad_data->row_shift = row_shift;
303303

304-
/* Initialize the chip or fail if chip isn't present */
305-
error = tca8418_configure(keypad_data, rows, cols);
306-
if (error < 0)
307-
return error;
304+
/* Read key lock register, if this fails assume device not present */
305+
error = tca8418_read_byte(keypad_data, REG_KEY_LCK_EC, &reg);
306+
if (error)
307+
return -ENODEV;
308308

309309
/* Configure input device */
310310
input = devm_input_allocate_device(dev);
@@ -340,6 +340,11 @@ static int tca8418_keypad_probe(struct i2c_client *client,
340340
return error;
341341
}
342342

343+
/* Initialize the chip */
344+
error = tca8418_configure(keypad_data, rows, cols);
345+
if (error < 0)
346+
return error;
347+
343348
error = input_register_device(input);
344349
if (error) {
345350
dev_err(dev, "Unable to register input device, error: %d\n",

drivers/input/misc/axp20x-pek.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ static const struct platform_device_id axp_pek_id_match[] = {
403403
},
404404
{ /* sentinel */ }
405405
};
406+
MODULE_DEVICE_TABLE(platform, axp_pek_id_match);
406407

407408
static struct platform_driver axp20x_pek_driver = {
408409
.probe = axp20x_pek_probe,
@@ -417,4 +418,3 @@ module_platform_driver(axp20x_pek_driver);
417418
MODULE_DESCRIPTION("axp20x Power Button");
418419
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
419420
MODULE_LICENSE("GPL");
420-
MODULE_ALIAS("platform:axp20x-pek");

drivers/input/misc/ims-pcu.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
16351635
return NULL;
16361636
}
16371637

1638-
while (buflen > 0) {
1638+
while (buflen >= sizeof(*union_desc)) {
16391639
union_desc = (struct usb_cdc_union_desc *)buf;
16401640

1641+
if (union_desc->bLength > buflen) {
1642+
dev_err(&intf->dev, "Too large descriptor\n");
1643+
return NULL;
1644+
}
1645+
16411646
if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
16421647
union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
16431648
dev_dbg(&intf->dev, "Found union header\n");
1644-
return union_desc;
1649+
1650+
if (union_desc->bLength >= sizeof(*union_desc))
1651+
return union_desc;
1652+
1653+
dev_err(&intf->dev,
1654+
"Union descriptor to short (%d vs %zd\n)",
1655+
union_desc->bLength, sizeof(*union_desc));
1656+
return NULL;
16451657
}
16461658

16471659
buflen -= union_desc->bLength;

drivers/input/mouse/synaptics.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,8 +1709,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse,
17091709
.sensor_pdata = {
17101710
.sensor_type = rmi_sensor_touchpad,
17111711
.axis_align.flip_y = true,
1712-
/* to prevent cursors jumps: */
1713-
.kernel_tracking = true,
1712+
.kernel_tracking = false,
17141713
.topbuttonpad = topbuttonpad,
17151714
},
17161715
.f30_data = {

drivers/input/touchscreen/goodix.c

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ struct goodix_ts_data {
7272
#define GOODIX_REG_CONFIG_DATA 0x8047
7373
#define GOODIX_REG_ID 0x8140
7474

75+
#define GOODIX_BUFFER_STATUS_READY BIT(7)
76+
#define GOODIX_BUFFER_STATUS_TIMEOUT 20
77+
7578
#define RESOLUTION_LOC 1
7679
#define MAX_CONTACTS_LOC 5
7780
#define TRIGGER_LOC 6
@@ -195,35 +198,53 @@ static int goodix_get_cfg_len(u16 id)
195198

196199
static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
197200
{
201+
unsigned long max_timeout;
198202
int touch_num;
199203
int error;
200204

201-
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data,
202-
GOODIX_CONTACT_SIZE + 1);
203-
if (error) {
204-
dev_err(&ts->client->dev, "I2C transfer error: %d\n", error);
205-
return error;
206-
}
205+
/*
206+
* The 'buffer status' bit, which indicates that the data is valid, is
207+
* not set as soon as the interrupt is raised, but slightly after.
208+
* This takes around 10 ms to happen, so we poll for 20 ms.
209+
*/
210+
max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT);
211+
do {
212+
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR,
213+
data, GOODIX_CONTACT_SIZE + 1);
214+
if (error) {
215+
dev_err(&ts->client->dev, "I2C transfer error: %d\n",
216+
error);
217+
return error;
218+
}
207219

208-
if (!(data[0] & 0x80))
209-
return -EAGAIN;
220+
if (data[0] & GOODIX_BUFFER_STATUS_READY) {
221+
touch_num = data[0] & 0x0f;
222+
if (touch_num > ts->max_touch_num)
223+
return -EPROTO;
224+
225+
if (touch_num > 1) {
226+
data += 1 + GOODIX_CONTACT_SIZE;
227+
error = goodix_i2c_read(ts->client,
228+
GOODIX_READ_COOR_ADDR +
229+
1 + GOODIX_CONTACT_SIZE,
230+
data,
231+
GOODIX_CONTACT_SIZE *
232+
(touch_num - 1));
233+
if (error)
234+
return error;
235+
}
236+
237+
return touch_num;
238+
}
210239

211-
touch_num = data[0] & 0x0f;
212-
if (touch_num > ts->max_touch_num)
213-
return -EPROTO;
214-
215-
if (touch_num > 1) {
216-
data += 1 + GOODIX_CONTACT_SIZE;
217-
error = goodix_i2c_read(ts->client,
218-
GOODIX_READ_COOR_ADDR +
219-
1 + GOODIX_CONTACT_SIZE,
220-
data,
221-
GOODIX_CONTACT_SIZE * (touch_num - 1));
222-
if (error)
223-
return error;
224-
}
240+
usleep_range(1000, 2000); /* Poll every 1 - 2 ms */
241+
} while (time_before(jiffies, max_timeout));
225242

226-
return touch_num;
243+
/*
244+
* The Goodix panel will send spurious interrupts after a
245+
* 'finger up' event, which will always cause a timeout.
246+
*/
247+
return 0;
227248
}
228249

229250
static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)

drivers/input/touchscreen/stmfts.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -663,12 +663,10 @@ static int stmfts_probe(struct i2c_client *client,
663663
sdata->input->open = stmfts_input_open;
664664
sdata->input->close = stmfts_input_close;
665665

666+
input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X);
667+
input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y);
666668
touchscreen_parse_properties(sdata->input, true, &sdata->prop);
667669

668-
input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0,
669-
sdata->prop.max_x, 0, 0);
670-
input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0,
671-
sdata->prop.max_y, 0, 0);
672670
input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
673671
input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
674672
input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);

0 commit comments

Comments
 (0)