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 320 ts->attn_gpio = devm_gpiod_get_optional(&client->dev, 321 "attn", GPIOD_IN); 322 if (IS_ERR(ts->attn_gpio)) { 323 error = PTR_ERR(ts->attn_gpio); 324 if (error != -EPROBE_DEFER) 325 dev_err(&client->dev, 326 "Failed to get attention GPIO: %d\n", error); 327 return error; 328 } 329 330 ts->reset_gpio = devm_gpiod_get_optional(&client->dev, 331 "reset", GPIOD_OUT_LOW); 332 if (IS_ERR(ts->reset_gpio)) { 333 error = PTR_ERR(ts->reset_gpio); 334 if (error != -EPROBE_DEFER) 335 dev_err(&client->dev, 336 "Failed to get reset GPIO: %d\n", error); 337 return error; 338 } 339 340 sis_ts_reset(ts); 341 342 ts->input = input = devm_input_allocate_device(&client->dev); 343 if (!input) { 344 dev_err(&client->dev, "Failed to allocate input device\n"); 345 return -ENOMEM; 346 } 347 348 input->name = "SiS Touchscreen"; 349 input->id.bustype = BUS_I2C; 350 351 input_set_abs_params(input, ABS_MT_POSITION_X, 0, SIS_MAX_X, 0, 0); 352 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, SIS_MAX_Y, 0, 0); 353 input_set_abs_params(input, ABS_MT_PRESSURE, 0, SIS_MAX_PRESSURE, 0, 0); 354 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 355 0, SIS_AREA_LENGTH_LONGER, 0, 0); 356 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 357 0, SIS_AREA_LENGTH_SHORT, 0, 0); 358 359 error = input_mt_init_slots(input, SIS_MAX_FINGERS, INPUT_MT_DIRECT); 360 if (error) { 361 dev_err(&client->dev, 362 "Failed to initialize MT slots: %d\n", error); 363 return error; 364 } 365 366 error = devm_request_threaded_irq(&client->dev, client->irq, 367 NULL, sis_ts_irq_handler, 368 IRQF_ONESHOT, 369 client->name, ts); 370 if (error) { 371 dev_err(&client->dev, "Failed to request IRQ: %d\n", error); 372 return error; 373 } 374 375 error = input_register_device(ts->input); 376 if (error) { 377 dev_err(&client->dev, 378 "Failed to register input device: %d\n", error); 379 return error; 380 } 381 382 return 0; 383 } 384 385 #ifdef CONFIG_OF 386 static const struct of_device_id sis_ts_dt_ids[] = { 387 { .compatible = "sis,9200-ts" }, 388 { /* sentinel */ } 389 }; 390 MODULE_DEVICE_TABLE(of, sis_ts_dt_ids); 391 #endif 392 393 static const struct i2c_device_id sis_ts_id[] = { 394 { SIS_I2C_NAME, 0 }, 395 { "9200-ts", 0 }, 396 { /* sentinel */ } 397 }; 398 MODULE_DEVICE_TABLE(i2c, sis_ts_id); 399 400 static struct i2c_driver sis_ts_driver = { 401 .driver = { 402 .name = SIS_I2C_NAME, 403 .of_match_table = of_match_ptr(sis_ts_dt_ids), 404 }, 405 .probe = sis_ts_probe, 406 .id_table = sis_ts_id, 407 }; 408 module_i2c_driver(sis_ts_driver); 409 410 MODULE_DESCRIPTION("SiS 9200 Family Touchscreen Driver"); 411 MODULE_LICENSE("GPL v2"); 412 MODULE_AUTHOR("Mika Penttilä <mika.penttila@nextfour.com>"); 413