0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/crc-itu-t.h>
0010 #include <linux/delay.h>
0011 #include <linux/i2c.h>
0012 #include <linux/input.h>
0013 #include <linux/input/mt.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/gpio/consumer.h>
0016 #include <linux/module.h>
0017 #include <linux/slab.h>
0018 #include <asm/unaligned.h>
0019
0020 #define SIS_I2C_NAME "sis_i2c_ts"
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 #define SIS_MAX_PACKET_SIZE 64
0047
0048 #define SIS_PKT_LEN_OFFSET 0
0049 #define SIS_PKT_REPORT_OFFSET 2
0050 #define SIS_PKT_CONTACT_OFFSET 3
0051
0052 #define SIS_SCAN_TIME_LEN 2
0053
0054
0055 #define SIS_ALL_IN_ONE_PACKAGE 0x10
0056 #define SIS_PKT_IS_TOUCH(x) (((x) & 0x0f) == 0x01)
0057 #define SIS_PKT_IS_HIDI2C(x) (((x) & 0x0f) == 0x06)
0058
0059
0060 #define SIS_PKT_HAS_AREA(x) ((x) & BIT(4))
0061 #define SIS_PKT_HAS_PRESSURE(x) ((x) & BIT(5))
0062 #define SIS_PKT_HAS_SCANTIME(x) ((x) & BIT(6))
0063
0064
0065 #define SIS_BASE_LEN_PER_CONTACT 6
0066 #define SIS_AREA_LEN_PER_CONTACT 2
0067 #define SIS_PRESSURE_LEN_PER_CONTACT 1
0068
0069
0070 #define SIS_CONTACT_STATUS_OFFSET 0
0071 #define SIS_CONTACT_ID_OFFSET 1
0072 #define SIS_CONTACT_X_OFFSET 2
0073 #define SIS_CONTACT_Y_OFFSET 4
0074 #define SIS_CONTACT_WIDTH_OFFSET 6
0075 #define SIS_CONTACT_HEIGHT_OFFSET 7
0076 #define SIS_CONTACT_PRESSURE_OFFSET(id) (SIS_PKT_HAS_AREA(id) ? 8 : 6)
0077
0078
0079 #define SIS_STATUS_UP 0x0
0080 #define SIS_STATUS_DOWN 0x3
0081
0082
0083 #define SIS_MAX_FINGERS 10
0084 #define SIS_MAX_X 4095
0085 #define SIS_MAX_Y 4095
0086 #define SIS_MAX_PRESSURE 255
0087
0088
0089 #define SIS_AREA_LENGTH_LONGER 5792
0090
0091 #define SIS_AREA_LENGTH_SHORT 5792
0092 #define SIS_AREA_UNIT (5792 / 32)
0093
0094 struct sis_ts_data {
0095 struct i2c_client *client;
0096 struct input_dev *input;
0097
0098 struct gpio_desc *attn_gpio;
0099 struct gpio_desc *reset_gpio;
0100
0101 u8 packet[SIS_MAX_PACKET_SIZE];
0102 };
0103
0104 static int sis_read_packet(struct i2c_client *client, u8 *buf,
0105 unsigned int *num_contacts,
0106 unsigned int *contact_size)
0107 {
0108 int count_idx;
0109 int ret;
0110 u16 len;
0111 u16 crc, pkg_crc;
0112 u8 report_id;
0113
0114 ret = i2c_master_recv(client, buf, SIS_MAX_PACKET_SIZE);
0115 if (ret <= 0)
0116 return -EIO;
0117
0118 len = get_unaligned_le16(&buf[SIS_PKT_LEN_OFFSET]);
0119 if (len > SIS_MAX_PACKET_SIZE) {
0120 dev_err(&client->dev,
0121 "%s: invalid packet length (%d vs %d)\n",
0122 __func__, len, SIS_MAX_PACKET_SIZE);
0123 return -E2BIG;
0124 }
0125
0126 if (len < 10)
0127 return -EINVAL;
0128
0129 report_id = buf[SIS_PKT_REPORT_OFFSET];
0130 count_idx = len - 1;
0131 *contact_size = SIS_BASE_LEN_PER_CONTACT;
0132
0133 if (report_id != SIS_ALL_IN_ONE_PACKAGE) {
0134 if (SIS_PKT_IS_TOUCH(report_id)) {
0135
0136
0137
0138
0139
0140 crc = crc_itu_t(0, buf + 2, len - 2 - 2);
0141 pkg_crc = get_unaligned_le16(&buf[len - 2]);
0142
0143 if (crc != pkg_crc) {
0144 dev_err(&client->dev,
0145 "%s: CRC Error (%d vs %d)\n",
0146 __func__, crc, pkg_crc);
0147 return -EINVAL;
0148 }
0149
0150 count_idx -= 2;
0151
0152 } else if (!SIS_PKT_IS_HIDI2C(report_id)) {
0153 dev_err(&client->dev,
0154 "%s: invalid packet ID %#02x\n",
0155 __func__, report_id);
0156 return -EINVAL;
0157 }
0158
0159 if (SIS_PKT_HAS_SCANTIME(report_id))
0160 count_idx -= SIS_SCAN_TIME_LEN;
0161
0162 if (SIS_PKT_HAS_AREA(report_id))
0163 *contact_size += SIS_AREA_LEN_PER_CONTACT;
0164 if (SIS_PKT_HAS_PRESSURE(report_id))
0165 *contact_size += SIS_PRESSURE_LEN_PER_CONTACT;
0166 }
0167
0168 *num_contacts = buf[count_idx];
0169 return 0;
0170 }
0171
0172 static int sis_ts_report_contact(struct sis_ts_data *ts, const u8 *data, u8 id)
0173 {
0174 struct input_dev *input = ts->input;
0175 int slot;
0176 u8 status = data[SIS_CONTACT_STATUS_OFFSET];
0177 u8 pressure;
0178 u8 height, width;
0179 u16 x, y;
0180
0181 if (status != SIS_STATUS_DOWN && status != SIS_STATUS_UP) {
0182 dev_err(&ts->client->dev, "Unexpected touch status: %#02x\n",
0183 data[SIS_CONTACT_STATUS_OFFSET]);
0184 return -EINVAL;
0185 }
0186
0187 slot = input_mt_get_slot_by_key(input, data[SIS_CONTACT_ID_OFFSET]);
0188 if (slot < 0)
0189 return -ENOENT;
0190
0191 input_mt_slot(input, slot);
0192 input_mt_report_slot_state(input, MT_TOOL_FINGER,
0193 status == SIS_STATUS_DOWN);
0194
0195 if (status == SIS_STATUS_DOWN) {
0196 pressure = height = width = 1;
0197 if (id != SIS_ALL_IN_ONE_PACKAGE) {
0198 if (SIS_PKT_HAS_AREA(id)) {
0199 width = data[SIS_CONTACT_WIDTH_OFFSET];
0200 height = data[SIS_CONTACT_HEIGHT_OFFSET];
0201 }
0202
0203 if (SIS_PKT_HAS_PRESSURE(id))
0204 pressure =
0205 data[SIS_CONTACT_PRESSURE_OFFSET(id)];
0206 }
0207
0208 x = get_unaligned_le16(&data[SIS_CONTACT_X_OFFSET]);
0209 y = get_unaligned_le16(&data[SIS_CONTACT_Y_OFFSET]);
0210
0211 input_report_abs(input, ABS_MT_TOUCH_MAJOR,
0212 width * SIS_AREA_UNIT);
0213 input_report_abs(input, ABS_MT_TOUCH_MINOR,
0214 height * SIS_AREA_UNIT);
0215 input_report_abs(input, ABS_MT_PRESSURE, pressure);
0216 input_report_abs(input, ABS_MT_POSITION_X, x);
0217 input_report_abs(input, ABS_MT_POSITION_Y, y);
0218 }
0219
0220 return 0;
0221 }
0222
0223 static void sis_ts_handle_packet(struct sis_ts_data *ts)
0224 {
0225 const u8 *contact;
0226 unsigned int num_to_report = 0;
0227 unsigned int num_contacts;
0228 unsigned int num_reported;
0229 unsigned int contact_size;
0230 int error;
0231 u8 report_id;
0232
0233 do {
0234 error = sis_read_packet(ts->client, ts->packet,
0235 &num_contacts, &contact_size);
0236 if (error)
0237 break;
0238
0239 if (num_to_report == 0) {
0240 num_to_report = num_contacts;
0241 } else if (num_contacts != 0) {
0242 dev_err(&ts->client->dev,
0243 "%s: nonzero (%d) point count in tail packet\n",
0244 __func__, num_contacts);
0245 break;
0246 }
0247
0248 report_id = ts->packet[SIS_PKT_REPORT_OFFSET];
0249 contact = &ts->packet[SIS_PKT_CONTACT_OFFSET];
0250 num_reported = 0;
0251
0252 while (num_to_report > 0) {
0253 error = sis_ts_report_contact(ts, contact, report_id);
0254 if (error)
0255 break;
0256
0257 contact += contact_size;
0258 num_to_report--;
0259 num_reported++;
0260
0261 if (report_id != SIS_ALL_IN_ONE_PACKAGE &&
0262 num_reported >= 5) {
0263
0264
0265
0266
0267 break;
0268 }
0269 }
0270 } while (num_to_report > 0);
0271
0272 input_mt_sync_frame(ts->input);
0273 input_sync(ts->input);
0274 }
0275
0276 static irqreturn_t sis_ts_irq_handler(int irq, void *dev_id)
0277 {
0278 struct sis_ts_data *ts = dev_id;
0279
0280 do {
0281 sis_ts_handle_packet(ts);
0282 } while (ts->attn_gpio && gpiod_get_value_cansleep(ts->attn_gpio));
0283
0284 return IRQ_HANDLED;
0285 }
0286
0287 static void sis_ts_reset(struct sis_ts_data *ts)
0288 {
0289 if (ts->reset_gpio) {
0290
0291 usleep_range(1000, 2000);
0292 gpiod_set_value(ts->reset_gpio, 1);
0293 usleep_range(1000, 2000);
0294 gpiod_set_value(ts->reset_gpio, 0);
0295 msleep(100);
0296 }
0297 }
0298
0299 static int sis_ts_probe(struct i2c_client *client,
0300 const struct i2c_device_id *id)
0301 {
0302 struct sis_ts_data *ts;
0303 struct input_dev *input;
0304 int error;
0305
0306 ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
0307 if (!ts)
0308 return -ENOMEM;
0309
0310 ts->client = client;
0311
0312 ts->attn_gpio = devm_gpiod_get_optional(&client->dev,
0313 "attn", GPIOD_IN);
0314 if (IS_ERR(ts->attn_gpio)) {
0315 error = PTR_ERR(ts->attn_gpio);
0316 if (error != -EPROBE_DEFER)
0317 dev_err(&client->dev,
0318 "Failed to get attention GPIO: %d\n", error);
0319 return error;
0320 }
0321
0322 ts->reset_gpio = devm_gpiod_get_optional(&client->dev,
0323 "reset", GPIOD_OUT_LOW);
0324 if (IS_ERR(ts->reset_gpio)) {
0325 error = PTR_ERR(ts->reset_gpio);
0326 if (error != -EPROBE_DEFER)
0327 dev_err(&client->dev,
0328 "Failed to get reset GPIO: %d\n", error);
0329 return error;
0330 }
0331
0332 sis_ts_reset(ts);
0333
0334 ts->input = input = devm_input_allocate_device(&client->dev);
0335 if (!input) {
0336 dev_err(&client->dev, "Failed to allocate input device\n");
0337 return -ENOMEM;
0338 }
0339
0340 input->name = "SiS Touchscreen";
0341 input->id.bustype = BUS_I2C;
0342
0343 input_set_abs_params(input, ABS_MT_POSITION_X, 0, SIS_MAX_X, 0, 0);
0344 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, SIS_MAX_Y, 0, 0);
0345 input_set_abs_params(input, ABS_MT_PRESSURE, 0, SIS_MAX_PRESSURE, 0, 0);
0346 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
0347 0, SIS_AREA_LENGTH_LONGER, 0, 0);
0348 input_set_abs_params(input, ABS_MT_TOUCH_MINOR,
0349 0, SIS_AREA_LENGTH_SHORT, 0, 0);
0350
0351 error = input_mt_init_slots(input, SIS_MAX_FINGERS, INPUT_MT_DIRECT);
0352 if (error) {
0353 dev_err(&client->dev,
0354 "Failed to initialize MT slots: %d\n", error);
0355 return error;
0356 }
0357
0358 error = devm_request_threaded_irq(&client->dev, client->irq,
0359 NULL, sis_ts_irq_handler,
0360 IRQF_ONESHOT,
0361 client->name, ts);
0362 if (error) {
0363 dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
0364 return error;
0365 }
0366
0367 error = input_register_device(ts->input);
0368 if (error) {
0369 dev_err(&client->dev,
0370 "Failed to register input device: %d\n", error);
0371 return error;
0372 }
0373
0374 return 0;
0375 }
0376
0377 #ifdef CONFIG_OF
0378 static const struct of_device_id sis_ts_dt_ids[] = {
0379 { .compatible = "sis,9200-ts" },
0380 { }
0381 };
0382 MODULE_DEVICE_TABLE(of, sis_ts_dt_ids);
0383 #endif
0384
0385 static const struct i2c_device_id sis_ts_id[] = {
0386 { SIS_I2C_NAME, 0 },
0387 { "9200-ts", 0 },
0388 { }
0389 };
0390 MODULE_DEVICE_TABLE(i2c, sis_ts_id);
0391
0392 static struct i2c_driver sis_ts_driver = {
0393 .driver = {
0394 .name = SIS_I2C_NAME,
0395 .of_match_table = of_match_ptr(sis_ts_dt_ids),
0396 },
0397 .probe = sis_ts_probe,
0398 .id_table = sis_ts_id,
0399 };
0400 module_i2c_driver(sis_ts_driver);
0401
0402 MODULE_DESCRIPTION("SiS 9200 Family Touchscreen Driver");
0403 MODULE_LICENSE("GPL v2");
0404 MODULE_AUTHOR("Mika Penttilä <mika.penttila@nextfour.com>");