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

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

Pull more input updates from Dmitry Torokhov:
"Two new drivers for touchscreen controllers:

- Silead touchscreen controllers
- SiS 9200 family touchscreen controllers

and a few driver fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: silead - remove some dead code
Input: sis-i2c - select CONFIG_CRC_ITU_T
Input: add driver for SiS 9200 family I2C touchscreen controllers
Input: ili210x - fix permissions on "calibrate" attribute
Input: elan_i2c - properly wake up touchpad on ASUS laptops
Input: add driver for Silead touchscreens
Input: elantech - fix debug dump of the current packet
Input: rotary_encoder - support binary encoding of states
Input: xpad - power off wireless 360 controllers on suspend
Input: i8042 - break load dependency between atkbd/psmouse and i8042
Input: synaptics-rmi4 - do not check for NULL when calling of_node_put()
Input: cros_ec_keyb - cleanup use of dev

+1244 -70
+4
Documentation/devicetree/bindings/input/rotary-encoder.txt
··· 20 20 2: Half-period mode 21 21 4: Quarter-period mode 22 22 - wakeup-source: Boolean, rotary encoder can wake up the system. 23 + - rotary-encoder,encoding: String, the method used to encode steps. 24 + Supported are "gray" (the default and more common) and "binary". 23 25 24 26 Deprecated properties: 25 27 - rotary-encoder,half-period: Makes the driver work on half-period mode. ··· 36 34 compatible = "rotary-encoder"; 37 35 gpios = <&gpio 19 1>, <&gpio 20 0>; /* GPIO19 is inverted */ 38 36 linux,axis = <0>; /* REL_X */ 37 + rotary-encoder,encoding = "gray"; 39 38 rotary-encoder,relative-axis; 40 39 }; 41 40 ··· 45 42 gpios = <&gpio 21 0>, <&gpio 22 0>; 46 43 linux,axis = <1>; /* ABS_Y */ 47 44 rotary-encoder,steps = <24>; 45 + rotary-encoder,encoding = "binary"; 48 46 rotary-encoder,rollover; 49 47 };
+36
Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt
··· 1 + * GSL 1680 touchscreen controller 2 + 3 + Required properties: 4 + - compatible : "silead,gsl1680" 5 + - reg : I2C slave address of the chip (0x40) 6 + - interrupt-parent : a phandle pointing to the interrupt controller 7 + serving the interrupt for this chip 8 + - interrupts : interrupt specification for the gsl1680 interrupt 9 + - power-gpios : Specification for the pin connected to the gsl1680's 10 + shutdown input. This needs to be driven high to take the 11 + gsl1680 out of its low power state 12 + - touchscreen-size-x : See touchscreen.txt 13 + - touchscreen-size-y : See touchscreen.txt 14 + 15 + Optional properties: 16 + - touchscreen-inverted-x : See touchscreen.txt 17 + - touchscreen-inverted-y : See touchscreen.txt 18 + - touchscreen-swapped-x-y : See touchscreen.txt 19 + - silead,max-fingers : maximum number of fingers the touchscreen can detect 20 + 21 + Example: 22 + 23 + i2c@00000000 { 24 + gsl1680: touchscreen@40 { 25 + compatible = "silead,gsl1680"; 26 + reg = <0x40>; 27 + interrupt-parent = <&pio>; 28 + interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>; 29 + power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; 30 + touchscreen-size-x = <480>; 31 + touchscreen-size-y = <800>; 32 + touchscreen-inverted-x; 33 + touchscreen-swapped-x-y; 34 + silead,max-fingers = <5>; 35 + }; 36 + };
+33
Documentation/devicetree/bindings/input/touchscreen/sis_i2c.txt
··· 1 + * SiS I2C Multiple Touch Controller 2 + 3 + Required properties: 4 + - compatible: must be "sis,9200-ts" 5 + - reg: i2c slave address 6 + - interrupt-parent: the phandle for the interrupt controller 7 + (see interrupt binding [0]) 8 + - interrupts: touch controller interrupt (see interrupt 9 + binding [0]) 10 + 11 + Optional properties: 12 + - pinctrl-names: should be "default" (see pinctrl binding [1]). 13 + - pinctrl-0: a phandle pointing to the pin settings for the 14 + device (see pinctrl binding [1]). 15 + - attn-gpios: the gpio pin used as attention line 16 + - reset-gpios: the gpio pin used to reset the controller 17 + - wakeup-source: touchscreen can be used as a wakeup source 18 + 19 + [0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt 20 + [1]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 21 + 22 + Example: 23 + 24 + sis9255@5c { 25 + compatible = "sis,9200-ts"; 26 + reg = <0x5c>; 27 + pinctrl-names = "default"; 28 + pinctrl-0 = <&pinctrl_sis>; 29 + interrupt-parent = <&gpio3>; 30 + interrupts = <19 IRQ_TYPE_EDGE_FALLING>; 31 + irq-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; 32 + reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>; 33 + };
+1
Documentation/devicetree/bindings/vendor-prefixes.txt
··· 238 238 sii Seiko Instruments, Inc. 239 239 silergy Silergy Corp. 240 240 sirf SiRF Technology, Inc. 241 + sis Silicon Integrated Systems Corp. 241 242 sitronix Sitronix Technology Corporation 242 243 skyworks Skyworks Solutions, Inc. 243 244 smsc Standard Microsystems Corporation
+43
drivers/input/joystick/xpad.c
··· 115 115 module_param(sticks_to_null, bool, S_IRUGO); 116 116 MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads"); 117 117 118 + static bool auto_poweroff = true; 119 + module_param(auto_poweroff, bool, S_IWUSR | S_IRUGO); 120 + MODULE_PARM_DESC(auto_poweroff, "Power off wireless controllers on suspend"); 121 + 118 122 static const struct xpad_device { 119 123 u16 idVendor; 120 124 u16 idProduct; ··· 1252 1248 usb_kill_urb(xpad->irq_in); 1253 1249 } 1254 1250 1251 + static void xpad360w_poweroff_controller(struct usb_xpad *xpad) 1252 + { 1253 + unsigned long flags; 1254 + struct xpad_output_packet *packet = 1255 + &xpad->out_packets[XPAD_OUT_CMD_IDX]; 1256 + 1257 + spin_lock_irqsave(&xpad->odata_lock, flags); 1258 + 1259 + packet->data[0] = 0x00; 1260 + packet->data[1] = 0x00; 1261 + packet->data[2] = 0x08; 1262 + packet->data[3] = 0xC0; 1263 + packet->data[4] = 0x00; 1264 + packet->data[5] = 0x00; 1265 + packet->data[6] = 0x00; 1266 + packet->data[7] = 0x00; 1267 + packet->data[8] = 0x00; 1268 + packet->data[9] = 0x00; 1269 + packet->data[10] = 0x00; 1270 + packet->data[11] = 0x00; 1271 + packet->len = 12; 1272 + packet->pending = true; 1273 + 1274 + /* Reset the sequence so we send out poweroff now */ 1275 + xpad->last_out_packet = -1; 1276 + xpad_try_sending_next_out_packet(xpad); 1277 + 1278 + spin_unlock_irqrestore(&xpad->odata_lock, flags); 1279 + } 1280 + 1255 1281 static int xpad360w_start_input(struct usb_xpad *xpad) 1256 1282 { 1257 1283 int error; ··· 1624 1590 * or goes away. 1625 1591 */ 1626 1592 xpad360w_stop_input(xpad); 1593 + 1594 + /* 1595 + * The wireless adapter is going off now, so the 1596 + * gamepads are going to become disconnected. 1597 + * Unless explicitly disabled, power them down 1598 + * so they don't just sit there flashing. 1599 + */ 1600 + if (auto_poweroff && xpad->pad_present) 1601 + xpad360w_poweroff_controller(xpad); 1627 1602 } else { 1628 1603 mutex_lock(&input->mutex); 1629 1604 if (input->users)
+9 -10
drivers/input/keyboard/cros_ec_keyb.c
··· 186 186 if (ret >= 0) 187 187 cros_ec_keyb_process(ckdev, kb_state, ret); 188 188 else 189 - dev_err(ec->dev, "failed to get keyboard state: %d\n", ret); 189 + dev_err(ckdev->dev, "failed to get keyboard state: %d\n", ret); 190 190 191 191 return IRQ_HANDLED; 192 192 } ··· 236 236 static int cros_ec_keyb_probe(struct platform_device *pdev) 237 237 { 238 238 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); 239 - struct device *dev = ec->dev; 239 + struct device *dev = &pdev->dev; 240 240 struct cros_ec_keyb *ckdev; 241 241 struct input_dev *idev; 242 242 struct device_node *np; ··· 246 246 if (!np) 247 247 return -ENODEV; 248 248 249 - ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL); 249 + ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL); 250 250 if (!ckdev) 251 251 return -ENOMEM; 252 - err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows, 253 - &ckdev->cols); 252 + err = matrix_keypad_parse_of_params(dev, &ckdev->rows, &ckdev->cols); 254 253 if (err) 255 254 return err; 256 255 257 - ckdev->valid_keys = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); 256 + ckdev->valid_keys = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL); 258 257 if (!ckdev->valid_keys) 259 258 return -ENOMEM; 260 259 261 - ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); 260 + ckdev->old_kb_state = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL); 262 261 if (!ckdev->old_kb_state) 263 262 return -ENOMEM; 264 263 265 - idev = devm_input_allocate_device(&pdev->dev); 264 + idev = devm_input_allocate_device(dev); 266 265 if (!idev) 267 266 return -ENOMEM; 268 267 ··· 272 273 273 274 ckdev->ec = ec; 274 275 ckdev->dev = dev; 275 - dev_set_drvdata(&pdev->dev, ckdev); 276 + dev_set_drvdata(dev, ckdev); 276 277 277 278 idev->name = CROS_EC_DEV_NAME; 278 279 idev->phys = ec->phys_name; ··· 281 282 idev->id.bustype = BUS_VIRTUAL; 282 283 idev->id.version = 1; 283 284 idev->id.product = 0; 284 - idev->dev.parent = &pdev->dev; 285 + idev->dev.parent = dev; 285 286 idev->open = cros_ec_keyb_open; 286 287 idev->close = cros_ec_keyb_close; 287 288
+22 -1
drivers/input/misc/rotary_encoder.c
··· 28 28 29 29 #define DRV_NAME "rotary-encoder" 30 30 31 + enum rotary_encoder_encoding { 32 + ROTENC_GRAY, 33 + ROTENC_BINARY, 34 + }; 35 + 31 36 struct rotary_encoder { 32 37 struct input_dev *input; 33 38 ··· 42 37 u32 axis; 43 38 bool relative_axis; 44 39 bool rollover; 40 + enum rotary_encoder_encoding encoding; 45 41 46 42 unsigned int pos; 47 43 ··· 63 57 64 58 for (i = 0; i < encoder->gpios->ndescs; ++i) { 65 59 int val = gpiod_get_value_cansleep(encoder->gpios->desc[i]); 60 + 66 61 /* convert from gray encoding to normal */ 67 - if (ret & 1) 62 + if (encoder->encoding == ROTENC_GRAY && ret & 1) 68 63 val = !val; 69 64 70 65 ret = ret << 1 | val; ··· 219 212 220 213 encoder->rollover = 221 214 device_property_read_bool(dev, "rotary-encoder,rollover"); 215 + 216 + if (!device_property_present(dev, "rotary-encoder,encoding") || 217 + !device_property_match_string(dev, "rotary-encoder,encoding", 218 + "gray")) { 219 + dev_info(dev, "gray"); 220 + encoder->encoding = ROTENC_GRAY; 221 + } else if (!device_property_match_string(dev, "rotary-encoder,encoding", 222 + "binary")) { 223 + dev_info(dev, "binary"); 224 + encoder->encoding = ROTENC_BINARY; 225 + } else { 226 + dev_err(dev, "unknown encoding setting\n"); 227 + return -EINVAL; 228 + } 222 229 223 230 device_property_read_u32(dev, "linux,axis", &encoder->axis); 224 231 encoder->relative_axis =
+63 -16
drivers/input/mouse/elan_i2c_core.c
··· 4 4 * Copyright (c) 2013 ELAN Microelectronics Corp. 5 5 * 6 6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> 7 - * Version: 1.6.0 7 + * Author: KT Liao <kt.liao@emc.com.tw> 8 + * Version: 1.6.2 8 9 * 9 10 * Based on cyapa driver: 10 11 * copyright (c) 2011-2012 Cypress Semiconductor, Inc. ··· 41 40 #include "elan_i2c.h" 42 41 43 42 #define DRIVER_NAME "elan_i2c" 44 - #define ELAN_DRIVER_VERSION "1.6.1" 43 + #define ELAN_DRIVER_VERSION "1.6.2" 45 44 #define ELAN_VENDOR_ID 0x04f3 46 45 #define ETP_MAX_PRESSURE 255 47 46 #define ETP_FWIDTH_REDUCE 90 ··· 200 199 return error; 201 200 } 202 201 202 + static int elan_query_product(struct elan_tp_data *data) 203 + { 204 + int error; 205 + 206 + error = data->ops->get_product_id(data->client, &data->product_id); 207 + if (error) 208 + return error; 209 + 210 + error = data->ops->get_sm_version(data->client, &data->ic_type, 211 + &data->sm_version); 212 + if (error) 213 + return error; 214 + 215 + return 0; 216 + } 217 + 218 + static int elan_check_ASUS_special_fw(struct elan_tp_data *data) 219 + { 220 + if (data->ic_type != 0x0E) 221 + return false; 222 + 223 + switch (data->product_id) { 224 + case 0x05 ... 0x07: 225 + case 0x09: 226 + case 0x13: 227 + return true; 228 + default: 229 + return false; 230 + } 231 + } 232 + 203 233 static int __elan_initialize(struct elan_tp_data *data) 204 234 { 205 235 struct i2c_client *client = data->client; 236 + bool woken_up = false; 206 237 int error; 207 238 208 239 error = data->ops->initialize(client); 209 240 if (error) { 210 241 dev_err(&client->dev, "device initialize failed: %d\n", error); 211 242 return error; 243 + } 244 + 245 + error = elan_query_product(data); 246 + if (error) 247 + return error; 248 + 249 + /* 250 + * Some ASUS devices were shipped with firmware that requires 251 + * touchpads to be woken up first, before attempting to switch 252 + * them into absolute reporting mode. 253 + */ 254 + if (elan_check_ASUS_special_fw(data)) { 255 + error = data->ops->sleep_control(client, false); 256 + if (error) { 257 + dev_err(&client->dev, 258 + "failed to wake device up: %d\n", error); 259 + return error; 260 + } 261 + 262 + msleep(200); 263 + woken_up = true; 212 264 } 213 265 214 266 data->mode |= ETP_ENABLE_ABS; ··· 272 218 return error; 273 219 } 274 220 275 - error = data->ops->sleep_control(client, false); 276 - if (error) { 277 - dev_err(&client->dev, 278 - "failed to wake device up: %d\n", error); 279 - return error; 221 + if (!woken_up) { 222 + error = data->ops->sleep_control(client, false); 223 + if (error) { 224 + dev_err(&client->dev, 225 + "failed to wake device up: %d\n", error); 226 + return error; 227 + } 280 228 } 281 229 282 230 return 0; ··· 304 248 { 305 249 int error; 306 250 307 - error = data->ops->get_product_id(data->client, &data->product_id); 308 - if (error) 309 - return error; 310 - 311 251 error = data->ops->get_version(data->client, false, &data->fw_version); 312 252 if (error) 313 253 return error; 314 254 315 255 error = data->ops->get_checksum(data->client, false, 316 256 &data->fw_checksum); 317 - if (error) 318 - return error; 319 - 320 - error = data->ops->get_sm_version(data->client, &data->ic_type, 321 - &data->sm_version); 322 257 if (error) 323 258 return error; 324 259
+2 -6
drivers/input/mouse/elantech.c
··· 222 222 */ 223 223 static void elantech_packet_dump(struct psmouse *psmouse) 224 224 { 225 - int i; 226 - 227 - psmouse_printk(KERN_DEBUG, psmouse, "PS/2 packet ["); 228 - for (i = 0; i < psmouse->pktsize; i++) 229 - printk("%s0x%02x ", i ? ", " : " ", psmouse->packet[i]); 230 - printk("]\n"); 225 + psmouse_printk(KERN_DEBUG, psmouse, "PS/2 packet [%*ph]\n", 226 + psmouse->pktsize, psmouse->packet); 231 227 } 232 228 233 229 /*
+1 -4
drivers/input/rmi4/rmi_bus.c
··· 232 232 void rmi_unregister_function(struct rmi_function *fn) 233 233 { 234 234 device_del(&fn->dev); 235 - 236 - if (fn->dev.of_node) 237 - of_node_put(fn->dev.of_node); 238 - 235 + of_node_put(fn->dev.of_node); 239 236 put_device(&fn->dev); 240 237 } 241 238
+1 -15
drivers/input/serio/i8042.c
··· 1277 1277 serio->start = i8042_start; 1278 1278 serio->stop = i8042_stop; 1279 1279 serio->close = i8042_port_close; 1280 + serio->ps2_cmd_mutex = &i8042_mutex; 1280 1281 serio->port_data = port; 1281 1282 serio->dev.parent = &i8042_platform_device->dev; 1282 1283 strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name)); ··· 1373 1372 } 1374 1373 } 1375 1374 } 1376 - 1377 - /* 1378 - * Checks whether port belongs to i8042 controller. 1379 - */ 1380 - bool i8042_check_port_owner(const struct serio *port) 1381 - { 1382 - int i; 1383 - 1384 - for (i = 0; i < I8042_NUM_PORTS; i++) 1385 - if (i8042_ports[i].serio == port) 1386 - return true; 1387 - 1388 - return false; 1389 - } 1390 - EXPORT_SYMBOL(i8042_check_port_owner); 1391 1375 1392 1376 static void i8042_free_irqs(void) 1393 1377 {
+4 -6
drivers/input/serio/libps2.c
··· 56 56 57 57 void ps2_begin_command(struct ps2dev *ps2dev) 58 58 { 59 - mutex_lock(&ps2dev->cmd_mutex); 59 + struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; 60 60 61 - if (i8042_check_port_owner(ps2dev->serio)) 62 - i8042_lock_chip(); 61 + mutex_lock(m); 63 62 } 64 63 EXPORT_SYMBOL(ps2_begin_command); 65 64 66 65 void ps2_end_command(struct ps2dev *ps2dev) 67 66 { 68 - if (i8042_check_port_owner(ps2dev->serio)) 69 - i8042_unlock_chip(); 67 + struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex; 70 68 71 - mutex_unlock(&ps2dev->cmd_mutex); 69 + mutex_unlock(m); 72 70 } 73 71 EXPORT_SYMBOL(ps2_end_command); 74 72
+25
drivers/input/touchscreen/Kconfig
··· 1059 1059 To compile this driver as a module, choose M here: the 1060 1060 module will be called raydium_i2c_ts. 1061 1061 1062 + config TOUCHSCREEN_SILEAD 1063 + tristate "Silead I2C touchscreen" 1064 + depends on I2C 1065 + help 1066 + Say Y here if you have the Silead touchscreen connected to 1067 + your system. 1068 + 1069 + If unsure, say N. 1070 + 1071 + To compile this driver as a module, choose M here: the 1072 + module will be called silead. 1073 + 1074 + config TOUCHSCREEN_SIS_I2C 1075 + tristate "SiS 9200 family I2C touchscreen" 1076 + depends on I2C 1077 + select CRC_ITU_T 1078 + depends on GPIOLIB || COMPILE_TEST 1079 + help 1080 + This enables support for SiS 9200 family over I2C based touchscreens. 1081 + 1082 + If unsure, say N. 1083 + 1084 + To compile this driver as a module, choose M here: the 1085 + module will be called sis_i2c. 1086 + 1062 1087 config TOUCHSCREEN_ST1232 1063 1088 tristate "Sitronix ST1232 touchscreen controllers" 1064 1089 depends on I2C
+2
drivers/input/touchscreen/Makefile
··· 64 64 obj-$(CONFIG_TOUCHSCREEN_PIXCIR) += pixcir_i2c_ts.o 65 65 obj-$(CONFIG_TOUCHSCREEN_RM_TS) += raydium_i2c_ts.o 66 66 obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o 67 + obj-$(CONFIG_TOUCHSCREEN_SILEAD) += silead.o 68 + obj-$(CONFIG_TOUCHSCREEN_SIS_I2C) += sis_i2c.o 67 69 obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o 68 70 obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o 69 71 obj-$(CONFIG_TOUCHSCREEN_SUN4I) += sun4i-ts.o
+1 -1
drivers/input/touchscreen/ili210x.c
··· 169 169 170 170 return count; 171 171 } 172 - static DEVICE_ATTR(calibrate, 0644, NULL, ili210x_calibrate); 172 + static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ili210x_calibrate); 173 173 174 174 static struct attribute *ili210x_attributes[] = { 175 175 &dev_attr_calibrate.attr,
+565
drivers/input/touchscreen/silead.c
··· 1 + /* ------------------------------------------------------------------------- 2 + * Copyright (C) 2014-2015, Intel Corporation 3 + * 4 + * Derived from: 5 + * gslX68X.c 6 + * Copyright (C) 2010-2015, Shanghai Sileadinc Co.Ltd 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; either version 2 of the License, or 11 + * (at your option) any later version. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + * ------------------------------------------------------------------------- 18 + */ 19 + 20 + #include <linux/i2c.h> 21 + #include <linux/module.h> 22 + #include <linux/acpi.h> 23 + #include <linux/interrupt.h> 24 + #include <linux/gpio/consumer.h> 25 + #include <linux/delay.h> 26 + #include <linux/firmware.h> 27 + #include <linux/input.h> 28 + #include <linux/input/mt.h> 29 + #include <linux/input/touchscreen.h> 30 + #include <linux/pm.h> 31 + #include <linux/irq.h> 32 + 33 + #include <asm/unaligned.h> 34 + 35 + #define SILEAD_TS_NAME "silead_ts" 36 + 37 + #define SILEAD_REG_RESET 0xE0 38 + #define SILEAD_REG_DATA 0x80 39 + #define SILEAD_REG_TOUCH_NR 0x80 40 + #define SILEAD_REG_POWER 0xBC 41 + #define SILEAD_REG_CLOCK 0xE4 42 + #define SILEAD_REG_STATUS 0xB0 43 + #define SILEAD_REG_ID 0xFC 44 + #define SILEAD_REG_MEM_CHECK 0xB0 45 + 46 + #define SILEAD_STATUS_OK 0x5A5A5A5A 47 + #define SILEAD_TS_DATA_LEN 44 48 + #define SILEAD_CLOCK 0x04 49 + 50 + #define SILEAD_CMD_RESET 0x88 51 + #define SILEAD_CMD_START 0x00 52 + 53 + #define SILEAD_POINT_DATA_LEN 0x04 54 + #define SILEAD_POINT_Y_OFF 0x00 55 + #define SILEAD_POINT_Y_MSB_OFF 0x01 56 + #define SILEAD_POINT_X_OFF 0x02 57 + #define SILEAD_POINT_X_MSB_OFF 0x03 58 + #define SILEAD_TOUCH_ID_MASK 0xF0 59 + 60 + #define SILEAD_CMD_SLEEP_MIN 10000 61 + #define SILEAD_CMD_SLEEP_MAX 20000 62 + #define SILEAD_POWER_SLEEP 20 63 + #define SILEAD_STARTUP_SLEEP 30 64 + 65 + #define SILEAD_MAX_FINGERS 10 66 + 67 + enum silead_ts_power { 68 + SILEAD_POWER_ON = 1, 69 + SILEAD_POWER_OFF = 0 70 + }; 71 + 72 + struct silead_ts_data { 73 + struct i2c_client *client; 74 + struct gpio_desc *gpio_power; 75 + struct input_dev *input; 76 + char fw_name[64]; 77 + struct touchscreen_properties prop; 78 + u32 max_fingers; 79 + u32 chip_id; 80 + struct input_mt_pos pos[SILEAD_MAX_FINGERS]; 81 + int slots[SILEAD_MAX_FINGERS]; 82 + int id[SILEAD_MAX_FINGERS]; 83 + }; 84 + 85 + struct silead_fw_data { 86 + u32 offset; 87 + u32 val; 88 + }; 89 + 90 + static int silead_ts_request_input_dev(struct silead_ts_data *data) 91 + { 92 + struct device *dev = &data->client->dev; 93 + int error; 94 + 95 + data->input = devm_input_allocate_device(dev); 96 + if (!data->input) { 97 + dev_err(dev, 98 + "Failed to allocate input device\n"); 99 + return -ENOMEM; 100 + } 101 + 102 + input_set_abs_params(data->input, ABS_MT_POSITION_X, 0, 4095, 0, 0); 103 + input_set_abs_params(data->input, ABS_MT_POSITION_Y, 0, 4095, 0, 0); 104 + touchscreen_parse_properties(data->input, true, &data->prop); 105 + 106 + input_mt_init_slots(data->input, data->max_fingers, 107 + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | 108 + INPUT_MT_TRACK); 109 + 110 + data->input->name = SILEAD_TS_NAME; 111 + data->input->phys = "input/ts"; 112 + data->input->id.bustype = BUS_I2C; 113 + 114 + error = input_register_device(data->input); 115 + if (error) { 116 + dev_err(dev, "Failed to register input device: %d\n", error); 117 + return error; 118 + } 119 + 120 + return 0; 121 + } 122 + 123 + static void silead_ts_set_power(struct i2c_client *client, 124 + enum silead_ts_power state) 125 + { 126 + struct silead_ts_data *data = i2c_get_clientdata(client); 127 + 128 + if (data->gpio_power) { 129 + gpiod_set_value_cansleep(data->gpio_power, state); 130 + msleep(SILEAD_POWER_SLEEP); 131 + } 132 + } 133 + 134 + static void silead_ts_read_data(struct i2c_client *client) 135 + { 136 + struct silead_ts_data *data = i2c_get_clientdata(client); 137 + struct input_dev *input = data->input; 138 + struct device *dev = &client->dev; 139 + u8 *bufp, buf[SILEAD_TS_DATA_LEN]; 140 + int touch_nr, error, i; 141 + 142 + error = i2c_smbus_read_i2c_block_data(client, SILEAD_REG_DATA, 143 + SILEAD_TS_DATA_LEN, buf); 144 + if (error < 0) { 145 + dev_err(dev, "Data read error %d\n", error); 146 + return; 147 + } 148 + 149 + touch_nr = buf[0]; 150 + if (touch_nr > data->max_fingers) { 151 + dev_warn(dev, "More touches reported then supported %d > %d\n", 152 + touch_nr, data->max_fingers); 153 + touch_nr = data->max_fingers; 154 + } 155 + 156 + bufp = buf + SILEAD_POINT_DATA_LEN; 157 + for (i = 0; i < touch_nr; i++, bufp += SILEAD_POINT_DATA_LEN) { 158 + /* Bits 4-7 are the touch id */ 159 + data->id[i] = (bufp[SILEAD_POINT_X_MSB_OFF] & 160 + SILEAD_TOUCH_ID_MASK) >> 4; 161 + touchscreen_set_mt_pos(&data->pos[i], &data->prop, 162 + get_unaligned_le16(&bufp[SILEAD_POINT_X_OFF]) & 0xfff, 163 + get_unaligned_le16(&bufp[SILEAD_POINT_Y_OFF]) & 0xfff); 164 + } 165 + 166 + input_mt_assign_slots(input, data->slots, data->pos, touch_nr, 0); 167 + 168 + for (i = 0; i < touch_nr; i++) { 169 + input_mt_slot(input, data->slots[i]); 170 + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); 171 + input_report_abs(input, ABS_MT_POSITION_X, data->pos[i].x); 172 + input_report_abs(input, ABS_MT_POSITION_Y, data->pos[i].y); 173 + 174 + dev_dbg(dev, "x=%d y=%d hw_id=%d sw_id=%d\n", data->pos[i].x, 175 + data->pos[i].y, data->id[i], data->slots[i]); 176 + } 177 + 178 + input_mt_sync_frame(input); 179 + input_sync(input); 180 + } 181 + 182 + static int silead_ts_init(struct i2c_client *client) 183 + { 184 + struct silead_ts_data *data = i2c_get_clientdata(client); 185 + int error; 186 + 187 + error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET, 188 + SILEAD_CMD_RESET); 189 + if (error) 190 + goto i2c_write_err; 191 + usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); 192 + 193 + error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR, 194 + data->max_fingers); 195 + if (error) 196 + goto i2c_write_err; 197 + usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); 198 + 199 + error = i2c_smbus_write_byte_data(client, SILEAD_REG_CLOCK, 200 + SILEAD_CLOCK); 201 + if (error) 202 + goto i2c_write_err; 203 + usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); 204 + 205 + error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET, 206 + SILEAD_CMD_START); 207 + if (error) 208 + goto i2c_write_err; 209 + usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); 210 + 211 + return 0; 212 + 213 + i2c_write_err: 214 + dev_err(&client->dev, "Registers clear error %d\n", error); 215 + return error; 216 + } 217 + 218 + static int silead_ts_reset(struct i2c_client *client) 219 + { 220 + int error; 221 + 222 + error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET, 223 + SILEAD_CMD_RESET); 224 + if (error) 225 + goto i2c_write_err; 226 + usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); 227 + 228 + error = i2c_smbus_write_byte_data(client, SILEAD_REG_CLOCK, 229 + SILEAD_CLOCK); 230 + if (error) 231 + goto i2c_write_err; 232 + usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); 233 + 234 + error = i2c_smbus_write_byte_data(client, SILEAD_REG_POWER, 235 + SILEAD_CMD_START); 236 + if (error) 237 + goto i2c_write_err; 238 + usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); 239 + 240 + return 0; 241 + 242 + i2c_write_err: 243 + dev_err(&client->dev, "Chip reset error %d\n", error); 244 + return error; 245 + } 246 + 247 + static int silead_ts_startup(struct i2c_client *client) 248 + { 249 + int error; 250 + 251 + error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET, 0x00); 252 + if (error) { 253 + dev_err(&client->dev, "Startup error %d\n", error); 254 + return error; 255 + } 256 + 257 + msleep(SILEAD_STARTUP_SLEEP); 258 + 259 + return 0; 260 + } 261 + 262 + static int silead_ts_load_fw(struct i2c_client *client) 263 + { 264 + struct device *dev = &client->dev; 265 + struct silead_ts_data *data = i2c_get_clientdata(client); 266 + unsigned int fw_size, i; 267 + const struct firmware *fw; 268 + struct silead_fw_data *fw_data; 269 + int error; 270 + 271 + dev_dbg(dev, "Firmware file name: %s", data->fw_name); 272 + 273 + error = request_firmware(&fw, data->fw_name, dev); 274 + if (error) { 275 + dev_err(dev, "Firmware request error %d\n", error); 276 + return error; 277 + } 278 + 279 + fw_size = fw->size / sizeof(*fw_data); 280 + fw_data = (struct silead_fw_data *)fw->data; 281 + 282 + for (i = 0; i < fw_size; i++) { 283 + error = i2c_smbus_write_i2c_block_data(client, 284 + fw_data[i].offset, 285 + 4, 286 + (u8 *)&fw_data[i].val); 287 + if (error) { 288 + dev_err(dev, "Firmware load error %d\n", error); 289 + break; 290 + } 291 + } 292 + 293 + release_firmware(fw); 294 + return error ?: 0; 295 + } 296 + 297 + static u32 silead_ts_get_status(struct i2c_client *client) 298 + { 299 + int error; 300 + __le32 status; 301 + 302 + error = i2c_smbus_read_i2c_block_data(client, SILEAD_REG_STATUS, 303 + sizeof(status), (u8 *)&status); 304 + if (error < 0) { 305 + dev_err(&client->dev, "Status read error %d\n", error); 306 + return error; 307 + } 308 + 309 + return le32_to_cpu(status); 310 + } 311 + 312 + static int silead_ts_get_id(struct i2c_client *client) 313 + { 314 + struct silead_ts_data *data = i2c_get_clientdata(client); 315 + __le32 chip_id; 316 + int error; 317 + 318 + error = i2c_smbus_read_i2c_block_data(client, SILEAD_REG_ID, 319 + sizeof(chip_id), (u8 *)&chip_id); 320 + if (error < 0) { 321 + dev_err(&client->dev, "Chip ID read error %d\n", error); 322 + return error; 323 + } 324 + 325 + data->chip_id = le32_to_cpu(chip_id); 326 + dev_info(&client->dev, "Silead chip ID: 0x%8X", data->chip_id); 327 + 328 + return 0; 329 + } 330 + 331 + static int silead_ts_setup(struct i2c_client *client) 332 + { 333 + int error; 334 + u32 status; 335 + 336 + silead_ts_set_power(client, SILEAD_POWER_OFF); 337 + silead_ts_set_power(client, SILEAD_POWER_ON); 338 + 339 + error = silead_ts_get_id(client); 340 + if (error) 341 + return error; 342 + 343 + error = silead_ts_init(client); 344 + if (error) 345 + return error; 346 + 347 + error = silead_ts_reset(client); 348 + if (error) 349 + return error; 350 + 351 + error = silead_ts_load_fw(client); 352 + if (error) 353 + return error; 354 + 355 + error = silead_ts_startup(client); 356 + if (error) 357 + return error; 358 + 359 + status = silead_ts_get_status(client); 360 + if (status != SILEAD_STATUS_OK) { 361 + dev_err(&client->dev, 362 + "Initialization error, status: 0x%X\n", status); 363 + return -ENODEV; 364 + } 365 + 366 + return 0; 367 + } 368 + 369 + static irqreturn_t silead_ts_threaded_irq_handler(int irq, void *id) 370 + { 371 + struct silead_ts_data *data = id; 372 + struct i2c_client *client = data->client; 373 + 374 + silead_ts_read_data(client); 375 + 376 + return IRQ_HANDLED; 377 + } 378 + 379 + static void silead_ts_read_props(struct i2c_client *client) 380 + { 381 + struct silead_ts_data *data = i2c_get_clientdata(client); 382 + struct device *dev = &client->dev; 383 + const char *str; 384 + int error; 385 + 386 + error = device_property_read_u32(dev, "silead,max-fingers", 387 + &data->max_fingers); 388 + if (error) { 389 + dev_dbg(dev, "Max fingers read error %d\n", error); 390 + data->max_fingers = 5; /* Most devices handle up-to 5 fingers */ 391 + } 392 + 393 + error = device_property_read_string(dev, "touchscreen-fw-name", &str); 394 + if (!error) 395 + snprintf(data->fw_name, sizeof(data->fw_name), "%s", str); 396 + else 397 + dev_dbg(dev, "Firmware file name read error. Using default."); 398 + } 399 + 400 + #ifdef CONFIG_ACPI 401 + static int silead_ts_set_default_fw_name(struct silead_ts_data *data, 402 + const struct i2c_device_id *id) 403 + { 404 + const struct acpi_device_id *acpi_id; 405 + struct device *dev = &data->client->dev; 406 + int i; 407 + 408 + if (ACPI_HANDLE(dev)) { 409 + acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); 410 + if (!acpi_id) 411 + return -ENODEV; 412 + 413 + snprintf(data->fw_name, sizeof(data->fw_name), "%s.fw", 414 + acpi_id->id); 415 + 416 + for (i = 0; i < strlen(data->fw_name); i++) 417 + data->fw_name[i] = tolower(data->fw_name[i]); 418 + } else { 419 + snprintf(data->fw_name, sizeof(data->fw_name), "%s.fw", 420 + id->name); 421 + } 422 + 423 + return 0; 424 + } 425 + #else 426 + static int silead_ts_set_default_fw_name(struct silead_ts_data *data, 427 + const struct i2c_device_id *id) 428 + { 429 + snprintf(data->fw_name, sizeof(data->fw_name), "%s.fw", id->name); 430 + return 0; 431 + } 432 + #endif 433 + 434 + static int silead_ts_probe(struct i2c_client *client, 435 + const struct i2c_device_id *id) 436 + { 437 + struct silead_ts_data *data; 438 + struct device *dev = &client->dev; 439 + int error; 440 + 441 + if (!i2c_check_functionality(client->adapter, 442 + I2C_FUNC_I2C | 443 + I2C_FUNC_SMBUS_READ_I2C_BLOCK | 444 + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { 445 + dev_err(dev, "I2C functionality check failed\n"); 446 + return -ENXIO; 447 + } 448 + 449 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 450 + if (!data) 451 + return -ENOMEM; 452 + 453 + i2c_set_clientdata(client, data); 454 + data->client = client; 455 + 456 + error = silead_ts_set_default_fw_name(data, id); 457 + if (error) 458 + return error; 459 + 460 + silead_ts_read_props(client); 461 + 462 + /* We must have the IRQ provided by DT or ACPI subsytem */ 463 + if (client->irq <= 0) 464 + return -ENODEV; 465 + 466 + /* Power GPIO pin */ 467 + data->gpio_power = gpiod_get_optional(dev, "power", GPIOD_OUT_LOW); 468 + if (IS_ERR(data->gpio_power)) { 469 + if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER) 470 + dev_err(dev, "Shutdown GPIO request failed\n"); 471 + return PTR_ERR(data->gpio_power); 472 + } 473 + 474 + error = silead_ts_setup(client); 475 + if (error) 476 + return error; 477 + 478 + error = silead_ts_request_input_dev(data); 479 + if (error) 480 + return error; 481 + 482 + error = devm_request_threaded_irq(dev, client->irq, 483 + NULL, silead_ts_threaded_irq_handler, 484 + IRQF_ONESHOT, client->name, data); 485 + if (error) { 486 + if (error != -EPROBE_DEFER) 487 + dev_err(dev, "IRQ request failed %d\n", error); 488 + return error; 489 + } 490 + 491 + return 0; 492 + } 493 + 494 + static int __maybe_unused silead_ts_suspend(struct device *dev) 495 + { 496 + struct i2c_client *client = to_i2c_client(dev); 497 + 498 + silead_ts_set_power(client, SILEAD_POWER_OFF); 499 + return 0; 500 + } 501 + 502 + static int __maybe_unused silead_ts_resume(struct device *dev) 503 + { 504 + struct i2c_client *client = to_i2c_client(dev); 505 + int error, status; 506 + 507 + silead_ts_set_power(client, SILEAD_POWER_ON); 508 + 509 + error = silead_ts_reset(client); 510 + if (error) 511 + return error; 512 + 513 + error = silead_ts_startup(client); 514 + if (error) 515 + return error; 516 + 517 + status = silead_ts_get_status(client); 518 + if (status != SILEAD_STATUS_OK) { 519 + dev_err(dev, "Resume error, status: 0x%02x\n", status); 520 + return -ENODEV; 521 + } 522 + 523 + return 0; 524 + } 525 + 526 + static SIMPLE_DEV_PM_OPS(silead_ts_pm, silead_ts_suspend, silead_ts_resume); 527 + 528 + static const struct i2c_device_id silead_ts_id[] = { 529 + { "gsl1680", 0 }, 530 + { "gsl1688", 0 }, 531 + { "gsl3670", 0 }, 532 + { "gsl3675", 0 }, 533 + { "gsl3692", 0 }, 534 + { "mssl1680", 0 }, 535 + { } 536 + }; 537 + MODULE_DEVICE_TABLE(i2c, silead_ts_id); 538 + 539 + #ifdef CONFIG_ACPI 540 + static const struct acpi_device_id silead_ts_acpi_match[] = { 541 + { "GSL1680", 0 }, 542 + { "GSL1688", 0 }, 543 + { "GSL3670", 0 }, 544 + { "GSL3675", 0 }, 545 + { "GSL3692", 0 }, 546 + { "MSSL1680", 0 }, 547 + { } 548 + }; 549 + MODULE_DEVICE_TABLE(acpi, silead_ts_acpi_match); 550 + #endif 551 + 552 + static struct i2c_driver silead_ts_driver = { 553 + .probe = silead_ts_probe, 554 + .id_table = silead_ts_id, 555 + .driver = { 556 + .name = SILEAD_TS_NAME, 557 + .acpi_match_table = ACPI_PTR(silead_ts_acpi_match), 558 + .pm = &silead_ts_pm, 559 + }, 560 + }; 561 + module_i2c_driver(silead_ts_driver); 562 + 563 + MODULE_AUTHOR("Robert Dolca <robert.dolca@intel.com>"); 564 + MODULE_DESCRIPTION("Silead I2C touchscreen driver"); 565 + MODULE_LICENSE("GPL");
+413
drivers/input/touchscreen/sis_i2c.c
··· 1 + /* 2 + * Touch Screen driver for SiS 9200 family I2C Touch panels 3 + * 4 + * Copyright (C) 2015 SiS, Inc. 5 + * Copyright (C) 2016 Nextfour Group 6 + * 7 + * This software is licensed under the terms of the GNU General Public 8 + * License version 2, as published by the Free Software Foundation, and 9 + * may be copied, distributed, and modified under those terms. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <linux/crc-itu-t.h> 18 + #include <linux/delay.h> 19 + #include <linux/i2c.h> 20 + #include <linux/input.h> 21 + #include <linux/input/mt.h> 22 + #include <linux/interrupt.h> 23 + #include <linux/gpio/consumer.h> 24 + #include <linux/module.h> 25 + #include <linux/slab.h> 26 + #include <asm/unaligned.h> 27 + 28 + #define SIS_I2C_NAME "sis_i2c_ts" 29 + 30 + /* 31 + * The I2C packet format: 32 + * le16 byte count 33 + * u8 Report ID 34 + * <contact data - variable length> 35 + * u8 Number of contacts 36 + * le16 Scan Time (optional) 37 + * le16 CRC 38 + * 39 + * One touch point information consists of 6+ bytes, the order is: 40 + * u8 contact state 41 + * u8 finger id 42 + * le16 x axis 43 + * le16 y axis 44 + * u8 contact width (optional) 45 + * u8 contact height (optional) 46 + * u8 pressure (optional) 47 + * 48 + * Maximum amount of data transmitted in one shot is 64 bytes, if controller 49 + * needs to report more contacts than fit in one packet it will send true 50 + * number of contacts in first packet and 0 as number of contacts in second 51 + * packet. 52 + */ 53 + 54 + #define SIS_MAX_PACKET_SIZE 64 55 + 56 + #define SIS_PKT_LEN_OFFSET 0 57 + #define SIS_PKT_REPORT_OFFSET 2 /* Report ID/type */ 58 + #define SIS_PKT_CONTACT_OFFSET 3 /* First contact */ 59 + 60 + #define SIS_SCAN_TIME_LEN 2 61 + 62 + /* Supported report types */ 63 + #define SIS_ALL_IN_ONE_PACKAGE 0x10 64 + #define SIS_PKT_IS_TOUCH(x) (((x) & 0x0f) == 0x01) 65 + #define SIS_PKT_IS_HIDI2C(x) (((x) & 0x0f) == 0x06) 66 + 67 + /* Contact properties within report */ 68 + #define SIS_PKT_HAS_AREA(x) ((x) & BIT(4)) 69 + #define SIS_PKT_HAS_PRESSURE(x) ((x) & BIT(5)) 70 + #define SIS_PKT_HAS_SCANTIME(x) ((x) & BIT(6)) 71 + 72 + /* Contact size */ 73 + #define SIS_BASE_LEN_PER_CONTACT 6 74 + #define SIS_AREA_LEN_PER_CONTACT 2 75 + #define SIS_PRESSURE_LEN_PER_CONTACT 1 76 + 77 + /* Offsets within contact data */ 78 + #define SIS_CONTACT_STATUS_OFFSET 0 79 + #define SIS_CONTACT_ID_OFFSET 1 /* Contact ID */ 80 + #define SIS_CONTACT_X_OFFSET 2 81 + #define SIS_CONTACT_Y_OFFSET 4 82 + #define SIS_CONTACT_WIDTH_OFFSET 6 83 + #define SIS_CONTACT_HEIGHT_OFFSET 7 84 + #define SIS_CONTACT_PRESSURE_OFFSET(id) (SIS_PKT_HAS_AREA(id) ? 8 : 6) 85 + 86 + /* Individual contact state */ 87 + #define SIS_STATUS_UP 0x0 88 + #define SIS_STATUS_DOWN 0x3 89 + 90 + /* Touchscreen parameters */ 91 + #define SIS_MAX_FINGERS 10 92 + #define SIS_MAX_X 4095 93 + #define SIS_MAX_Y 4095 94 + #define SIS_MAX_PRESSURE 255 95 + 96 + /* Resolution diagonal */ 97 + #define SIS_AREA_LENGTH_LONGER 5792 98 + /*((SIS_MAX_X^2) + (SIS_MAX_Y^2))^0.5*/ 99 + #define SIS_AREA_LENGTH_SHORT 5792 100 + #define SIS_AREA_UNIT (5792 / 32) 101 + 102 + struct sis_ts_data { 103 + struct i2c_client *client; 104 + struct input_dev *input; 105 + 106 + struct gpio_desc *attn_gpio; 107 + struct gpio_desc *reset_gpio; 108 + 109 + u8 packet[SIS_MAX_PACKET_SIZE]; 110 + }; 111 + 112 + static int sis_read_packet(struct i2c_client *client, u8 *buf, 113 + unsigned int *num_contacts, 114 + unsigned int *contact_size) 115 + { 116 + int count_idx; 117 + int ret; 118 + u16 len; 119 + u16 crc, pkg_crc; 120 + u8 report_id; 121 + 122 + ret = i2c_master_recv(client, buf, SIS_MAX_PACKET_SIZE); 123 + if (ret <= 0) 124 + return -EIO; 125 + 126 + len = get_unaligned_le16(&buf[SIS_PKT_LEN_OFFSET]); 127 + if (len > SIS_MAX_PACKET_SIZE) { 128 + dev_err(&client->dev, 129 + "%s: invalid packet length (%d vs %d)\n", 130 + __func__, len, SIS_MAX_PACKET_SIZE); 131 + return -E2BIG; 132 + } 133 + 134 + if (len < 10) 135 + return -EINVAL; 136 + 137 + report_id = buf[SIS_PKT_REPORT_OFFSET]; 138 + count_idx = len - 1; 139 + *contact_size = SIS_BASE_LEN_PER_CONTACT; 140 + 141 + if (report_id != SIS_ALL_IN_ONE_PACKAGE) { 142 + if (SIS_PKT_IS_TOUCH(report_id)) { 143 + /* 144 + * Calculate CRC ignoring packet length 145 + * in the beginning and CRC transmitted 146 + * at the end of the packet. 147 + */ 148 + crc = crc_itu_t(0, buf + 2, len - 2 - 2); 149 + pkg_crc = get_unaligned_le16(&buf[len - 2]); 150 + 151 + if (crc != pkg_crc) { 152 + dev_err(&client->dev, 153 + "%s: CRC Error (%d vs %d)\n", 154 + __func__, crc, pkg_crc); 155 + return -EINVAL; 156 + } 157 + 158 + count_idx -= 2; 159 + 160 + } else if (!SIS_PKT_IS_HIDI2C(report_id)) { 161 + dev_err(&client->dev, 162 + "%s: invalid packet ID %#02x\n", 163 + __func__, report_id); 164 + return -EINVAL; 165 + } 166 + 167 + if (SIS_PKT_HAS_SCANTIME(report_id)) 168 + count_idx -= SIS_SCAN_TIME_LEN; 169 + 170 + if (SIS_PKT_HAS_AREA(report_id)) 171 + *contact_size += SIS_AREA_LEN_PER_CONTACT; 172 + if (SIS_PKT_HAS_PRESSURE(report_id)) 173 + *contact_size += SIS_PRESSURE_LEN_PER_CONTACT; 174 + } 175 + 176 + *num_contacts = buf[count_idx]; 177 + return 0; 178 + } 179 + 180 + static int sis_ts_report_contact(struct sis_ts_data *ts, const u8 *data, u8 id) 181 + { 182 + struct input_dev *input = ts->input; 183 + int slot; 184 + u8 status = data[SIS_CONTACT_STATUS_OFFSET]; 185 + u8 pressure; 186 + u8 height, width; 187 + u16 x, y; 188 + 189 + if (status != SIS_STATUS_DOWN && status != SIS_STATUS_UP) { 190 + dev_err(&ts->client->dev, "Unexpected touch status: %#02x\n", 191 + data[SIS_CONTACT_STATUS_OFFSET]); 192 + return -EINVAL; 193 + } 194 + 195 + slot = input_mt_get_slot_by_key(input, data[SIS_CONTACT_ID_OFFSET]); 196 + if (slot < 0) 197 + return -ENOENT; 198 + 199 + input_mt_slot(input, slot); 200 + input_mt_report_slot_state(input, MT_TOOL_FINGER, 201 + status == SIS_STATUS_DOWN); 202 + 203 + if (status == SIS_STATUS_DOWN) { 204 + pressure = height = width = 1; 205 + if (id != SIS_ALL_IN_ONE_PACKAGE) { 206 + if (SIS_PKT_HAS_AREA(id)) { 207 + width = data[SIS_CONTACT_WIDTH_OFFSET]; 208 + height = data[SIS_CONTACT_HEIGHT_OFFSET]; 209 + } 210 + 211 + if (SIS_PKT_HAS_PRESSURE(id)) 212 + pressure = 213 + data[SIS_CONTACT_PRESSURE_OFFSET(id)]; 214 + } 215 + 216 + x = get_unaligned_le16(&data[SIS_CONTACT_X_OFFSET]); 217 + y = get_unaligned_le16(&data[SIS_CONTACT_Y_OFFSET]); 218 + 219 + input_report_abs(input, ABS_MT_TOUCH_MAJOR, 220 + width * SIS_AREA_UNIT); 221 + input_report_abs(input, ABS_MT_TOUCH_MINOR, 222 + height * SIS_AREA_UNIT); 223 + input_report_abs(input, ABS_MT_PRESSURE, pressure); 224 + input_report_abs(input, ABS_MT_POSITION_X, x); 225 + input_report_abs(input, ABS_MT_POSITION_Y, y); 226 + } 227 + 228 + return 0; 229 + } 230 + 231 + static void sis_ts_handle_packet(struct sis_ts_data *ts) 232 + { 233 + const u8 *contact; 234 + unsigned int num_to_report = 0; 235 + unsigned int num_contacts; 236 + unsigned int num_reported; 237 + unsigned int contact_size; 238 + int error; 239 + u8 report_id; 240 + 241 + do { 242 + error = sis_read_packet(ts->client, ts->packet, 243 + &num_contacts, &contact_size); 244 + if (error) 245 + break; 246 + 247 + if (num_to_report == 0) { 248 + num_to_report = num_contacts; 249 + } else if (num_contacts != 0) { 250 + dev_err(&ts->client->dev, 251 + "%s: nonzero (%d) point count in tail packet\n", 252 + __func__, num_contacts); 253 + break; 254 + } 255 + 256 + report_id = ts->packet[SIS_PKT_REPORT_OFFSET]; 257 + contact = &ts->packet[SIS_PKT_CONTACT_OFFSET]; 258 + num_reported = 0; 259 + 260 + while (num_to_report > 0) { 261 + error = sis_ts_report_contact(ts, contact, report_id); 262 + if (error) 263 + break; 264 + 265 + contact += contact_size; 266 + num_to_report--; 267 + num_reported++; 268 + 269 + if (report_id != SIS_ALL_IN_ONE_PACKAGE && 270 + num_reported >= 5) { 271 + /* 272 + * The remainder of contacts is sent 273 + * in the 2nd packet. 274 + */ 275 + break; 276 + } 277 + } 278 + } while (num_to_report > 0); 279 + 280 + input_mt_sync_frame(ts->input); 281 + input_sync(ts->input); 282 + } 283 + 284 + static irqreturn_t sis_ts_irq_handler(int irq, void *dev_id) 285 + { 286 + struct sis_ts_data *ts = dev_id; 287 + 288 + do { 289 + sis_ts_handle_packet(ts); 290 + } while (ts->attn_gpio && gpiod_get_value_cansleep(ts->attn_gpio)); 291 + 292 + return IRQ_HANDLED; 293 + } 294 + 295 + static void sis_ts_reset(struct sis_ts_data *ts) 296 + { 297 + if (ts->reset_gpio) { 298 + /* Get out of reset */ 299 + usleep_range(1000, 2000); 300 + gpiod_set_value(ts->reset_gpio, 1); 301 + usleep_range(1000, 2000); 302 + gpiod_set_value(ts->reset_gpio, 0); 303 + msleep(100); 304 + } 305 + } 306 + 307 + static int sis_ts_probe(struct i2c_client *client, 308 + const struct i2c_device_id *id) 309 + { 310 + struct sis_ts_data *ts; 311 + struct input_dev *input; 312 + int error; 313 + 314 + ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); 315 + if (!ts) 316 + return -ENOMEM; 317 + 318 + ts->client = client; 319 + i2c_set_clientdata(client, ts); 320 + 321 + ts->attn_gpio = devm_gpiod_get_optional(&client->dev, 322 + "attn", GPIOD_IN); 323 + if (IS_ERR(ts->attn_gpio)) { 324 + error = PTR_ERR(ts->attn_gpio); 325 + if (error != -EPROBE_DEFER) 326 + dev_err(&client->dev, 327 + "Failed to get attention GPIO: %d\n", error); 328 + return error; 329 + } 330 + 331 + ts->reset_gpio = devm_gpiod_get_optional(&client->dev, 332 + "reset", GPIOD_OUT_LOW); 333 + if (IS_ERR(ts->reset_gpio)) { 334 + error = PTR_ERR(ts->reset_gpio); 335 + if (error != -EPROBE_DEFER) 336 + dev_err(&client->dev, 337 + "Failed to get reset GPIO: %d\n", error); 338 + return error; 339 + } 340 + 341 + sis_ts_reset(ts); 342 + 343 + ts->input = input = devm_input_allocate_device(&client->dev); 344 + if (!input) { 345 + dev_err(&client->dev, "Failed to allocate input device\n"); 346 + return -ENOMEM; 347 + } 348 + 349 + input->name = "SiS Touchscreen"; 350 + input->id.bustype = BUS_I2C; 351 + 352 + input_set_abs_params(input, ABS_MT_POSITION_X, 0, SIS_MAX_X, 0, 0); 353 + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, SIS_MAX_Y, 0, 0); 354 + input_set_abs_params(input, ABS_MT_PRESSURE, 0, SIS_MAX_PRESSURE, 0, 0); 355 + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 356 + 0, SIS_AREA_LENGTH_LONGER, 0, 0); 357 + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 358 + 0, SIS_AREA_LENGTH_SHORT, 0, 0); 359 + 360 + error = input_mt_init_slots(input, SIS_MAX_FINGERS, INPUT_MT_DIRECT); 361 + if (error) { 362 + dev_err(&client->dev, 363 + "Failed to initialize MT slots: %d\n", error); 364 + return error; 365 + } 366 + 367 + error = devm_request_threaded_irq(&client->dev, client->irq, 368 + NULL, sis_ts_irq_handler, 369 + IRQF_ONESHOT, 370 + client->name, ts); 371 + if (error) { 372 + dev_err(&client->dev, "Failed to request IRQ: %d\n", error); 373 + return error; 374 + } 375 + 376 + error = input_register_device(ts->input); 377 + if (error) { 378 + dev_err(&client->dev, 379 + "Failed to register input device: %d\n", error); 380 + return error; 381 + } 382 + 383 + return 0; 384 + } 385 + 386 + #ifdef CONFIG_OF 387 + static const struct of_device_id sis_ts_dt_ids[] = { 388 + { .compatible = "sis,9200-ts" }, 389 + { /* sentinel */ } 390 + }; 391 + MODULE_DEVICE_TABLE(of, sis_ts_dt_ids); 392 + #endif 393 + 394 + static const struct i2c_device_id sis_ts_id[] = { 395 + { SIS_I2C_NAME, 0 }, 396 + { "9200-ts", 0 }, 397 + { /* sentinel */ } 398 + }; 399 + MODULE_DEVICE_TABLE(i2c, sis_ts_id); 400 + 401 + static struct i2c_driver sis_ts_driver = { 402 + .driver = { 403 + .name = SIS_I2C_NAME, 404 + .of_match_table = of_match_ptr(sis_ts_dt_ids), 405 + }, 406 + .probe = sis_ts_probe, 407 + .id_table = sis_ts_id, 408 + }; 409 + module_i2c_driver(sis_ts_driver); 410 + 411 + MODULE_DESCRIPTION("SiS 9200 Family Touchscreen Driver"); 412 + MODULE_LICENSE("GPL v2"); 413 + MODULE_AUTHOR("Mika Penttilä <mika.penttila@nextfour.com>");
-6
include/linux/i8042.h
··· 62 62 void i8042_lock_chip(void); 63 63 void i8042_unlock_chip(void); 64 64 int i8042_command(unsigned char *param, int command); 65 - bool i8042_check_port_owner(const struct serio *); 66 65 int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str, 67 66 struct serio *serio)); 68 67 int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str, ··· 80 81 static inline int i8042_command(unsigned char *param, int command) 81 82 { 82 83 return -ENODEV; 83 - } 84 - 85 - static inline bool i8042_check_port_owner(const struct serio *serio) 86 - { 87 - return false; 88 84 } 89 85 90 86 static inline int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
+19 -5
include/linux/serio.h
··· 31 31 32 32 struct serio_device_id id; 33 33 34 - spinlock_t lock; /* protects critical sections from port's interrupt handler */ 34 + /* Protects critical sections from port's interrupt handler */ 35 + spinlock_t lock; 35 36 36 37 int (*write)(struct serio *, unsigned char); 37 38 int (*open)(struct serio *); ··· 41 40 void (*stop)(struct serio *); 42 41 43 42 struct serio *parent; 44 - struct list_head child_node; /* Entry in parent->children list */ 43 + /* Entry in parent->children list */ 44 + struct list_head child_node; 45 45 struct list_head children; 46 - unsigned int depth; /* level of nesting in serio hierarchy */ 46 + /* Level of nesting in serio hierarchy */ 47 + unsigned int depth; 47 48 48 - struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */ 49 - struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ 49 + /* 50 + * serio->drv is accessed from interrupt handlers; when modifying 51 + * caller should acquire serio->drv_mutex and serio->lock. 52 + */ 53 + struct serio_driver *drv; 54 + /* Protects serio->drv so attributes can pin current driver */ 55 + struct mutex drv_mutex; 50 56 51 57 struct device dev; 52 58 53 59 struct list_head node; 60 + 61 + /* 62 + * For use by PS/2 layer when several ports share hardware and 63 + * may get indigestion when exposed to concurrent access (i8042). 64 + */ 65 + struct mutex *ps2_cmd_mutex; 54 66 }; 55 67 #define to_serio_port(d) container_of(d, struct serio, dev) 56 68