Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull input fixes from Dmitry Torokhov:

- a fix for cm109 stomping on its own control URB if it tries to toggle
buzzer immediately after userspace opens input device (found by
syzcaller)

- another fix for Raydium touchscreens that do not like splitting
command transfers

- quirks for i8042, soc_button_array, and goodix drivers to make them
work better with certain hardware.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: goodix - add upside-down quirk for Teclast X98 Pro tablet
Input: cm109 - do not stomp on control URB
Input: i8042 - add Acer laptops to the i8042 reset list
Input: cros_ec_keyb - send 'scancodes' in addition to key events
Input: soc_button_array - add Lenovo Yoga Tablet2 1051L to the dmi_use_low_level_irq list
Input: raydium_ts_i2c - do not split tx transactions

+159 -40
+1
drivers/input/keyboard/cros_ec_keyb.c
··· 183 183 "changed: [r%d c%d]: byte %02x\n", 184 184 row, col, new_state); 185 185 186 + input_event(idev, EV_MSC, MSC_SCAN, pos); 186 187 input_report_key(idev, keycodes[pos], 187 188 new_state); 188 189 }
+5 -2
drivers/input/misc/cm109.c
··· 568 568 dev->ctl_data->byte[HID_OR2] = dev->keybit; 569 569 dev->ctl_data->byte[HID_OR3] = 0x00; 570 570 571 + dev->ctl_urb_pending = 1; 571 572 error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL); 572 - if (error) 573 + if (error) { 574 + dev->ctl_urb_pending = 0; 573 575 dev_err(&dev->intf->dev, "%s: usb_submit_urb (urb_ctl) failed %d\n", 574 576 __func__, error); 575 - else 577 + } else { 576 578 dev->open = 1; 579 + } 577 580 578 581 mutex_unlock(&dev->pm_mutex); 579 582
+11
drivers/input/misc/soc_button_array.c
··· 83 83 DMI_MATCH(DMI_PRODUCT_NAME, "One S1003"), 84 84 }, 85 85 }, 86 + { 87 + /* 88 + * Lenovo Yoga Tab2 1051L, something messes with the home-button 89 + * IRQ settings, leading to a non working home-button. 90 + */ 91 + .matches = { 92 + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 93 + DMI_MATCH(DMI_PRODUCT_NAME, "60073"), 94 + DMI_MATCH(DMI_PRODUCT_VERSION, "1051L"), 95 + }, 96 + }, 86 97 {} /* Terminating entry */ 87 98 }; 88 99
+42
drivers/input/serio/i8042-x86ia64io.h
··· 612 612 }, 613 613 }, 614 614 { 615 + .matches = { 616 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 617 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"), 618 + }, 619 + }, 620 + { 621 + .matches = { 622 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 623 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"), 624 + }, 625 + }, 626 + { 627 + .matches = { 628 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 629 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"), 630 + }, 631 + }, 632 + { 633 + .matches = { 634 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 635 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"), 636 + }, 637 + }, 638 + { 639 + .matches = { 640 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 641 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"), 642 + }, 643 + }, 644 + { 645 + .matches = { 646 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 647 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"), 648 + }, 649 + }, 650 + { 651 + .matches = { 652 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 653 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"), 654 + }, 655 + }, 656 + { 615 657 /* Advent 4211 */ 616 658 .matches = { 617 659 DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
+12
drivers/input/touchscreen/goodix.c
··· 193 193 }, 194 194 }, 195 195 { 196 + .ident = "Teclast X98 Pro", 197 + .matches = { 198 + /* 199 + * Only match BIOS date, because the manufacturers 200 + * BIOS does not report the board name at all 201 + * (sometimes)... 202 + */ 203 + DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), 204 + DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"), 205 + }, 206 + }, 207 + { 196 208 .ident = "WinBook TW100", 197 209 .matches = { 198 210 DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
+88 -38
drivers/input/touchscreen/raydium_i2c_ts.c
··· 137 137 bool wake_irq_enabled; 138 138 }; 139 139 140 - static int raydium_i2c_xfer(struct i2c_client *client, 141 - u32 addr, void *data, size_t len, bool is_read) 140 + /* 141 + * Header to be sent for RM_CMD_BANK_SWITCH command. This is used by 142 + * raydium_i2c_{read|send} below. 143 + */ 144 + struct __packed raydium_bank_switch_header { 145 + u8 cmd; 146 + __be32 be_addr; 147 + }; 148 + 149 + static int raydium_i2c_xfer(struct i2c_client *client, u32 addr, 150 + struct i2c_msg *xfer, size_t xfer_count) 142 151 { 143 - struct raydium_bank_switch_header { 144 - u8 cmd; 145 - __be32 be_addr; 146 - } __packed header = { 147 - .cmd = RM_CMD_BANK_SWITCH, 148 - .be_addr = cpu_to_be32(addr), 149 - }; 150 - 151 - u8 reg_addr = addr & 0xff; 152 - 153 - struct i2c_msg xfer[] = { 154 - { 155 - .addr = client->addr, 156 - .len = sizeof(header), 157 - .buf = (u8 *)&header, 158 - }, 159 - { 160 - .addr = client->addr, 161 - .len = 1, 162 - .buf = &reg_addr, 163 - }, 164 - { 165 - .addr = client->addr, 166 - .len = len, 167 - .buf = data, 168 - .flags = is_read ? I2C_M_RD : 0, 169 - } 170 - }; 171 - 152 + int ret; 172 153 /* 173 154 * If address is greater than 255, then RM_CMD_BANK_SWITCH needs to be 174 155 * sent first. Else, skip the header i.e. xfer[0]. 175 156 */ 176 157 int xfer_start_idx = (addr > 0xff) ? 0 : 1; 177 - size_t xfer_count = ARRAY_SIZE(xfer) - xfer_start_idx; 178 - int ret; 158 + xfer_count -= xfer_start_idx; 179 159 180 160 ret = i2c_transfer(client->adapter, &xfer[xfer_start_idx], xfer_count); 181 161 if (likely(ret == xfer_count)) ··· 169 189 { 170 190 int tries = 0; 171 191 int error; 192 + u8 *tx_buf; 193 + u8 reg_addr = addr & 0xff; 194 + 195 + tx_buf = kmalloc(len + 1, GFP_KERNEL); 196 + if (!tx_buf) 197 + return -ENOMEM; 198 + 199 + tx_buf[0] = reg_addr; 200 + memcpy(tx_buf + 1, data, len); 172 201 173 202 do { 174 - error = raydium_i2c_xfer(client, addr, (void *)data, len, 175 - false); 203 + struct raydium_bank_switch_header header = { 204 + .cmd = RM_CMD_BANK_SWITCH, 205 + .be_addr = cpu_to_be32(addr), 206 + }; 207 + 208 + /* 209 + * Perform as a single i2c_transfer transaction to ensure that 210 + * no other I2C transactions are initiated on the bus to any 211 + * other device in between. Initiating transacations to other 212 + * devices after RM_CMD_BANK_SWITCH is sent is known to cause 213 + * issues. This is also why regmap infrastructure cannot be used 214 + * for this driver. Regmap handles page(bank) switch and reads 215 + * as separate i2c_transfer() operations. This can result in 216 + * problems if the Raydium device is on a shared I2C bus. 217 + */ 218 + struct i2c_msg xfer[] = { 219 + { 220 + .addr = client->addr, 221 + .len = sizeof(header), 222 + .buf = (u8 *)&header, 223 + }, 224 + { 225 + .addr = client->addr, 226 + .len = len + 1, 227 + .buf = tx_buf, 228 + }, 229 + }; 230 + 231 + error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer)); 176 232 if (likely(!error)) 177 233 return 0; 178 234 ··· 222 206 static int raydium_i2c_read(struct i2c_client *client, 223 207 u32 addr, void *data, size_t len) 224 208 { 225 - size_t xfer_len; 226 209 int error; 227 210 228 211 while (len) { 229 - xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE); 230 - error = raydium_i2c_xfer(client, addr, data, xfer_len, true); 212 + u8 reg_addr = addr & 0xff; 213 + struct raydium_bank_switch_header header = { 214 + .cmd = RM_CMD_BANK_SWITCH, 215 + .be_addr = cpu_to_be32(addr), 216 + }; 217 + size_t xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE); 218 + 219 + /* 220 + * Perform as a single i2c_transfer transaction to ensure that 221 + * no other I2C transactions are initiated on the bus to any 222 + * other device in between. Initiating transacations to other 223 + * devices after RM_CMD_BANK_SWITCH is sent is known to cause 224 + * issues. This is also why regmap infrastructure cannot be used 225 + * for this driver. Regmap handles page(bank) switch and writes 226 + * as separate i2c_transfer() operations. This can result in 227 + * problems if the Raydium device is on a shared I2C bus. 228 + */ 229 + struct i2c_msg xfer[] = { 230 + { 231 + .addr = client->addr, 232 + .len = sizeof(header), 233 + .buf = (u8 *)&header, 234 + }, 235 + { 236 + .addr = client->addr, 237 + .len = 1, 238 + .buf = &reg_addr, 239 + }, 240 + { 241 + .addr = client->addr, 242 + .len = xfer_len, 243 + .buf = data, 244 + .flags = I2C_M_RD, 245 + } 246 + }; 247 + 248 + error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer)); 231 249 if (unlikely(error)) 232 250 return error; 233 251