linux/drivers/input/touchscreen/exc3000.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Driver for I2C connected EETI EXC3000 multiple touch controller
   4 *
   5 * Copyright (C) 2017 Ahmet Inan <inan@distec.de>
   6 *
   7 * minimal implementation based on egalax_ts.c and egalax_i2c.c
   8 */
   9
  10#include <linux/bitops.h>
  11#include <linux/delay.h>
  12#include <linux/device.h>
  13#include <linux/gpio/consumer.h>
  14#include <linux/i2c.h>
  15#include <linux/input.h>
  16#include <linux/input/mt.h>
  17#include <linux/input/touchscreen.h>
  18#include <linux/interrupt.h>
  19#include <linux/module.h>
  20#include <linux/of.h>
  21#include <linux/sizes.h>
  22#include <linux/timer.h>
  23#include <asm/unaligned.h>
  24
  25#define EXC3000_NUM_SLOTS               10
  26#define EXC3000_SLOTS_PER_FRAME         5
  27#define EXC3000_LEN_FRAME               66
  28#define EXC3000_LEN_VENDOR_REQUEST      68
  29#define EXC3000_LEN_POINT               10
  30
  31#define EXC3000_LEN_MODEL_NAME          16
  32#define EXC3000_LEN_FW_VERSION          16
  33
  34#define EXC3000_VENDOR_EVENT            0x03
  35#define EXC3000_MT1_EVENT               0x06
  36#define EXC3000_MT2_EVENT               0x18
  37
  38#define EXC3000_TIMEOUT_MS              100
  39
  40#define EXC3000_RESET_MS                10
  41#define EXC3000_READY_MS                100
  42
  43static const struct i2c_device_id exc3000_id[];
  44
  45struct eeti_dev_info {
  46        const char *name;
  47        int max_xy;
  48};
  49
  50enum eeti_dev_id {
  51        EETI_EXC3000,
  52        EETI_EXC80H60,
  53        EETI_EXC80H84,
  54};
  55
  56static struct eeti_dev_info exc3000_info[] = {
  57        [EETI_EXC3000] = {
  58                .name = "EETI EXC3000 Touch Screen",
  59                .max_xy = SZ_4K - 1,
  60        },
  61        [EETI_EXC80H60] = {
  62                .name = "EETI EXC80H60 Touch Screen",
  63                .max_xy = SZ_16K - 1,
  64        },
  65        [EETI_EXC80H84] = {
  66                .name = "EETI EXC80H84 Touch Screen",
  67                .max_xy = SZ_16K - 1,
  68        },
  69};
  70
  71struct exc3000_data {
  72        struct i2c_client *client;
  73        const struct eeti_dev_info *info;
  74        struct input_dev *input;
  75        struct touchscreen_properties prop;
  76        struct gpio_desc *reset;
  77        struct timer_list timer;
  78        u8 buf[2 * EXC3000_LEN_FRAME];
  79        struct completion wait_event;
  80        struct mutex query_lock;
  81};
  82
  83static void exc3000_report_slots(struct input_dev *input,
  84                                 struct touchscreen_properties *prop,
  85                                 const u8 *buf, int num)
  86{
  87        for (; num--; buf += EXC3000_LEN_POINT) {
  88                if (buf[0] & BIT(0)) {
  89                        input_mt_slot(input, buf[1]);
  90                        input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
  91                        touchscreen_report_pos(input, prop,
  92                                               get_unaligned_le16(buf + 2),
  93                                               get_unaligned_le16(buf + 4),
  94                                               true);
  95                }
  96        }
  97}
  98
  99static void exc3000_timer(struct timer_list *t)
 100{
 101        struct exc3000_data *data = from_timer(data, t, timer);
 102
 103        input_mt_sync_frame(data->input);
 104        input_sync(data->input);
 105}
 106
 107static inline void exc3000_schedule_timer(struct exc3000_data *data)
 108{
 109        mod_timer(&data->timer, jiffies + msecs_to_jiffies(EXC3000_TIMEOUT_MS));
 110}
 111
 112static int exc3000_read_frame(struct exc3000_data *data, u8 *buf)
 113{
 114        struct i2c_client *client = data->client;
 115        int ret;
 116
 117        ret = i2c_master_send(client, "'", 2);
 118        if (ret < 0)
 119                return ret;
 120
 121        if (ret != 2)
 122                return -EIO;
 123
 124        ret = i2c_master_recv(client, buf, EXC3000_LEN_FRAME);
 125        if (ret < 0)
 126                return ret;
 127
 128        if (ret != EXC3000_LEN_FRAME)
 129                return -EIO;
 130
 131        if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME)
 132                return -EINVAL;
 133
 134        return 0;
 135}
 136
 137static int exc3000_handle_mt_event(struct exc3000_data *data)
 138{
 139        struct input_dev *input = data->input;
 140        int ret, total_slots;
 141        u8 *buf = data->buf;
 142
 143        total_slots = buf[3];
 144        if (!total_slots || total_slots > EXC3000_NUM_SLOTS) {
 145                ret = -EINVAL;
 146                goto out_fail;
 147        }
 148
 149        if (total_slots > EXC3000_SLOTS_PER_FRAME) {
 150                /* Read 2nd frame to get the rest of the contacts. */
 151                ret = exc3000_read_frame(data, buf + EXC3000_LEN_FRAME);
 152                if (ret)
 153                        goto out_fail;
 154
 155                /* 2nd chunk must have number of contacts set to 0. */
 156                if (buf[EXC3000_LEN_FRAME + 3] != 0) {
 157                        ret = -EINVAL;
 158                        goto out_fail;
 159                }
 160        }
 161
 162        /*
 163         * We read full state successfully, no contacts will be "stuck".
 164         */
 165        del_timer_sync(&data->timer);
 166
 167        while (total_slots > 0) {
 168                int slots = min(total_slots, EXC3000_SLOTS_PER_FRAME);
 169
 170                exc3000_report_slots(input, &data->prop, buf + 4, slots);
 171                total_slots -= slots;
 172                buf += EXC3000_LEN_FRAME;
 173        }
 174
 175        input_mt_sync_frame(input);
 176        input_sync(input);
 177
 178        return 0;
 179
 180out_fail:
 181        /* Schedule a timer to release "stuck" contacts */
 182        exc3000_schedule_timer(data);
 183
 184        return ret;
 185}
 186
 187static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
 188{
 189        struct exc3000_data *data = dev_id;
 190        u8 *buf = data->buf;
 191        int ret;
 192
 193        ret = exc3000_read_frame(data, buf);
 194        if (ret) {
 195                /* Schedule a timer to release "stuck" contacts */
 196                exc3000_schedule_timer(data);
 197                goto out;
 198        }
 199
 200        switch (buf[2]) {
 201        case EXC3000_VENDOR_EVENT:
 202                complete(&data->wait_event);
 203                break;
 204
 205        case EXC3000_MT1_EVENT:
 206        case EXC3000_MT2_EVENT:
 207                exc3000_handle_mt_event(data);
 208                break;
 209
 210        default:
 211                break;
 212        }
 213
 214out:
 215        return IRQ_HANDLED;
 216}
 217
 218static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
 219                                       u8 request_len, u8 *response, int timeout)
 220{
 221        u8 buf[EXC3000_LEN_VENDOR_REQUEST] = { 0x67, 0x00, 0x42, 0x00, 0x03 };
 222        int ret;
 223
 224        mutex_lock(&data->query_lock);
 225
 226        reinit_completion(&data->wait_event);
 227
 228        buf[5] = request_len;
 229        memcpy(&buf[6], request, request_len);
 230
 231        ret = i2c_master_send(data->client, buf, EXC3000_LEN_VENDOR_REQUEST);
 232        if (ret < 0)
 233                goto out_unlock;
 234
 235        if (response) {
 236                ret = wait_for_completion_timeout(&data->wait_event,
 237                                                  timeout * HZ);
 238                if (ret <= 0) {
 239                        ret = -ETIMEDOUT;
 240                        goto out_unlock;
 241                }
 242
 243                if (data->buf[3] >= EXC3000_LEN_FRAME) {
 244                        ret = -ENOSPC;
 245                        goto out_unlock;
 246                }
 247
 248                memcpy(response, &data->buf[4], data->buf[3]);
 249                ret = data->buf[3];
 250        }
 251
 252out_unlock:
 253        mutex_unlock(&data->query_lock);
 254
 255        return ret;
 256}
 257
 258static ssize_t fw_version_show(struct device *dev,
 259                               struct device_attribute *attr, char *buf)
 260{
 261        struct i2c_client *client = to_i2c_client(dev);
 262        struct exc3000_data *data = i2c_get_clientdata(client);
 263        u8 response[EXC3000_LEN_FRAME];
 264        int ret;
 265
 266        /* query bootloader info */
 267        ret = exc3000_vendor_data_request(data,
 268                                          (u8[]){0x39, 0x02}, 2, response, 1);
 269        if (ret < 0)
 270                return ret;
 271
 272        /*
 273         * If the bootloader version is non-zero then the device is in
 274         * bootloader mode and won't answer a query for the application FW
 275         * version, so we just use the bootloader version info.
 276         */
 277        if (response[2] || response[3])
 278                return sprintf(buf, "%d.%d\n", response[2], response[3]);
 279
 280        ret = exc3000_vendor_data_request(data, (u8[]){'D'}, 1, response, 1);
 281        if (ret < 0)
 282                return ret;
 283
 284        return sprintf(buf, "%s\n", &response[1]);
 285}
 286static DEVICE_ATTR_RO(fw_version);
 287
 288static ssize_t model_show(struct device *dev,
 289                          struct device_attribute *attr, char *buf)
 290{
 291        struct i2c_client *client = to_i2c_client(dev);
 292        struct exc3000_data *data = i2c_get_clientdata(client);
 293        u8 response[EXC3000_LEN_FRAME];
 294        int ret;
 295
 296        ret = exc3000_vendor_data_request(data, (u8[]){'E'}, 1, response, 1);
 297        if (ret < 0)
 298                return ret;
 299
 300        return sprintf(buf, "%s\n", &response[1]);
 301}
 302static DEVICE_ATTR_RO(model);
 303
 304static ssize_t type_show(struct device *dev,
 305                          struct device_attribute *attr, char *buf)
 306{
 307        struct i2c_client *client = to_i2c_client(dev);
 308        struct exc3000_data *data = i2c_get_clientdata(client);
 309        u8 response[EXC3000_LEN_FRAME];
 310        int ret;
 311
 312        ret = exc3000_vendor_data_request(data, (u8[]){'F'}, 1, response, 1);
 313        if (ret < 0)
 314                return ret;
 315
 316        return sprintf(buf, "%s\n", &response[1]);
 317}
 318static DEVICE_ATTR_RO(type);
 319
 320static struct attribute *sysfs_attrs[] = {
 321        &dev_attr_fw_version.attr,
 322        &dev_attr_model.attr,
 323        &dev_attr_type.attr,
 324        NULL
 325};
 326
 327static struct attribute_group exc3000_attribute_group = {
 328        .attrs = sysfs_attrs
 329};
 330
 331static int exc3000_probe(struct i2c_client *client)
 332{
 333        struct exc3000_data *data;
 334        struct input_dev *input;
 335        int error, max_xy, retry;
 336
 337        data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
 338        if (!data)
 339                return -ENOMEM;
 340
 341        data->client = client;
 342        data->info = device_get_match_data(&client->dev);
 343        if (!data->info) {
 344                enum eeti_dev_id eeti_dev_id =
 345                        i2c_match_id(exc3000_id, client)->driver_data;
 346                data->info = &exc3000_info[eeti_dev_id];
 347        }
 348        timer_setup(&data->timer, exc3000_timer, 0);
 349        init_completion(&data->wait_event);
 350        mutex_init(&data->query_lock);
 351
 352        data->reset = devm_gpiod_get_optional(&client->dev, "reset",
 353                                              GPIOD_OUT_HIGH);
 354        if (IS_ERR(data->reset))
 355                return PTR_ERR(data->reset);
 356
 357        if (data->reset) {
 358                msleep(EXC3000_RESET_MS);
 359                gpiod_set_value_cansleep(data->reset, 0);
 360                msleep(EXC3000_READY_MS);
 361        }
 362
 363        input = devm_input_allocate_device(&client->dev);
 364        if (!input)
 365                return -ENOMEM;
 366
 367        data->input = input;
 368        input_set_drvdata(input, data);
 369
 370        input->name = data->info->name;
 371        input->id.bustype = BUS_I2C;
 372
 373        max_xy = data->info->max_xy;
 374        input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0);
 375        input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0);
 376
 377        touchscreen_parse_properties(input, true, &data->prop);
 378
 379        error = input_mt_init_slots(input, EXC3000_NUM_SLOTS,
 380                                    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
 381        if (error)
 382                return error;
 383
 384        error = input_register_device(input);
 385        if (error)
 386                return error;
 387
 388        error = devm_request_threaded_irq(&client->dev, client->irq,
 389                                          NULL, exc3000_interrupt, IRQF_ONESHOT,
 390                                          client->name, data);
 391        if (error)
 392                return error;
 393
 394        /*
 395         * I²C does not have built-in recovery, so retry on failure. This
 396         * ensures, that the device probe will not fail for temporary issues
 397         * on the bus.  This is not needed for the sysfs calls (userspace
 398         * will receive the error code and can start another query) and
 399         * cannot be done for touch events (but that only means loosing one
 400         * or two touch events anyways).
 401         */
 402        for (retry = 0; retry < 3; retry++) {
 403                u8 response[EXC3000_LEN_FRAME];
 404
 405                error = exc3000_vendor_data_request(data, (u8[]){'E'}, 1,
 406                                                    response, 1);
 407                if (error > 0) {
 408                        dev_dbg(&client->dev, "TS Model: %s", &response[1]);
 409                        error = 0;
 410                        break;
 411                }
 412                dev_warn(&client->dev, "Retry %d get EETI EXC3000 model: %d\n",
 413                         retry + 1, error);
 414        }
 415
 416        if (error)
 417                return error;
 418
 419        i2c_set_clientdata(client, data);
 420
 421        error = devm_device_add_group(&client->dev, &exc3000_attribute_group);
 422        if (error)
 423                return error;
 424
 425        return 0;
 426}
 427
 428static const struct i2c_device_id exc3000_id[] = {
 429        { "exc3000", EETI_EXC3000 },
 430        { "exc80h60", EETI_EXC80H60 },
 431        { "exc80h84", EETI_EXC80H84 },
 432        { }
 433};
 434MODULE_DEVICE_TABLE(i2c, exc3000_id);
 435
 436#ifdef CONFIG_OF
 437static const struct of_device_id exc3000_of_match[] = {
 438        { .compatible = "eeti,exc3000", .data = &exc3000_info[EETI_EXC3000] },
 439        { .compatible = "eeti,exc80h60", .data = &exc3000_info[EETI_EXC80H60] },
 440        { .compatible = "eeti,exc80h84", .data = &exc3000_info[EETI_EXC80H84] },
 441        { }
 442};
 443MODULE_DEVICE_TABLE(of, exc3000_of_match);
 444#endif
 445
 446static struct i2c_driver exc3000_driver = {
 447        .driver = {
 448                .name   = "exc3000",
 449                .of_match_table = of_match_ptr(exc3000_of_match),
 450        },
 451        .id_table       = exc3000_id,
 452        .probe_new      = exc3000_probe,
 453};
 454
 455module_i2c_driver(exc3000_driver);
 456
 457MODULE_AUTHOR("Ahmet Inan <inan@distec.de>");
 458MODULE_DESCRIPTION("I2C connected EETI EXC3000 multiple touch controller driver");
 459MODULE_LICENSE("GPL v2");
 460