Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Driver for I2C connected EETI EXC3000 multiple touch controller
0004  *
0005  * Copyright (C) 2017 Ahmet Inan <inan@distec.de>
0006  *
0007  * minimal implementation based on egalax_ts.c and egalax_i2c.c
0008  */
0009 
0010 #include <linux/bitops.h>
0011 #include <linux/delay.h>
0012 #include <linux/device.h>
0013 #include <linux/gpio/consumer.h>
0014 #include <linux/i2c.h>
0015 #include <linux/input.h>
0016 #include <linux/input/mt.h>
0017 #include <linux/input/touchscreen.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/module.h>
0020 #include <linux/of.h>
0021 #include <linux/sizes.h>
0022 #include <linux/timer.h>
0023 #include <asm/unaligned.h>
0024 
0025 #define EXC3000_NUM_SLOTS       10
0026 #define EXC3000_SLOTS_PER_FRAME     5
0027 #define EXC3000_LEN_FRAME       66
0028 #define EXC3000_LEN_VENDOR_REQUEST  68
0029 #define EXC3000_LEN_POINT       10
0030 
0031 #define EXC3000_LEN_MODEL_NAME      16
0032 #define EXC3000_LEN_FW_VERSION      16
0033 
0034 #define EXC3000_VENDOR_EVENT        0x03
0035 #define EXC3000_MT1_EVENT       0x06
0036 #define EXC3000_MT2_EVENT       0x18
0037 
0038 #define EXC3000_TIMEOUT_MS      100
0039 
0040 #define EXC3000_RESET_MS        10
0041 #define EXC3000_READY_MS        100
0042 
0043 static const struct i2c_device_id exc3000_id[];
0044 
0045 struct eeti_dev_info {
0046     const char *name;
0047     int max_xy;
0048 };
0049 
0050 enum eeti_dev_id {
0051     EETI_EXC3000,
0052     EETI_EXC80H60,
0053     EETI_EXC80H84,
0054 };
0055 
0056 static struct eeti_dev_info exc3000_info[] = {
0057     [EETI_EXC3000] = {
0058         .name = "EETI EXC3000 Touch Screen",
0059         .max_xy = SZ_4K - 1,
0060     },
0061     [EETI_EXC80H60] = {
0062         .name = "EETI EXC80H60 Touch Screen",
0063         .max_xy = SZ_16K - 1,
0064     },
0065     [EETI_EXC80H84] = {
0066         .name = "EETI EXC80H84 Touch Screen",
0067         .max_xy = SZ_16K - 1,
0068     },
0069 };
0070 
0071 struct exc3000_data {
0072     struct i2c_client *client;
0073     const struct eeti_dev_info *info;
0074     struct input_dev *input;
0075     struct touchscreen_properties prop;
0076     struct gpio_desc *reset;
0077     struct timer_list timer;
0078     u8 buf[2 * EXC3000_LEN_FRAME];
0079     struct completion wait_event;
0080     struct mutex query_lock;
0081 };
0082 
0083 static void exc3000_report_slots(struct input_dev *input,
0084                  struct touchscreen_properties *prop,
0085                  const u8 *buf, int num)
0086 {
0087     for (; num--; buf += EXC3000_LEN_POINT) {
0088         if (buf[0] & BIT(0)) {
0089             input_mt_slot(input, buf[1]);
0090             input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
0091             touchscreen_report_pos(input, prop,
0092                            get_unaligned_le16(buf + 2),
0093                            get_unaligned_le16(buf + 4),
0094                            true);
0095         }
0096     }
0097 }
0098 
0099 static void exc3000_timer(struct timer_list *t)
0100 {
0101     struct exc3000_data *data = from_timer(data, t, timer);
0102 
0103     input_mt_sync_frame(data->input);
0104     input_sync(data->input);
0105 }
0106 
0107 static inline void exc3000_schedule_timer(struct exc3000_data *data)
0108 {
0109     mod_timer(&data->timer, jiffies + msecs_to_jiffies(EXC3000_TIMEOUT_MS));
0110 }
0111 
0112 static int exc3000_read_frame(struct exc3000_data *data, u8 *buf)
0113 {
0114     struct i2c_client *client = data->client;
0115     int ret;
0116 
0117     ret = i2c_master_send(client, "'", 2);
0118     if (ret < 0)
0119         return ret;
0120 
0121     if (ret != 2)
0122         return -EIO;
0123 
0124     ret = i2c_master_recv(client, buf, EXC3000_LEN_FRAME);
0125     if (ret < 0)
0126         return ret;
0127 
0128     if (ret != EXC3000_LEN_FRAME)
0129         return -EIO;
0130 
0131     if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME)
0132         return -EINVAL;
0133 
0134     return 0;
0135 }
0136 
0137 static int exc3000_handle_mt_event(struct exc3000_data *data)
0138 {
0139     struct input_dev *input = data->input;
0140     int ret, total_slots;
0141     u8 *buf = data->buf;
0142 
0143     total_slots = buf[3];
0144     if (!total_slots || total_slots > EXC3000_NUM_SLOTS) {
0145         ret = -EINVAL;
0146         goto out_fail;
0147     }
0148 
0149     if (total_slots > EXC3000_SLOTS_PER_FRAME) {
0150         /* Read 2nd frame to get the rest of the contacts. */
0151         ret = exc3000_read_frame(data, buf + EXC3000_LEN_FRAME);
0152         if (ret)
0153             goto out_fail;
0154 
0155         /* 2nd chunk must have number of contacts set to 0. */
0156         if (buf[EXC3000_LEN_FRAME + 3] != 0) {
0157             ret = -EINVAL;
0158             goto out_fail;
0159         }
0160     }
0161 
0162     /*
0163      * We read full state successfully, no contacts will be "stuck".
0164      */
0165     del_timer_sync(&data->timer);
0166 
0167     while (total_slots > 0) {
0168         int slots = min(total_slots, EXC3000_SLOTS_PER_FRAME);
0169 
0170         exc3000_report_slots(input, &data->prop, buf + 4, slots);
0171         total_slots -= slots;
0172         buf += EXC3000_LEN_FRAME;
0173     }
0174 
0175     input_mt_sync_frame(input);
0176     input_sync(input);
0177 
0178     return 0;
0179 
0180 out_fail:
0181     /* Schedule a timer to release "stuck" contacts */
0182     exc3000_schedule_timer(data);
0183 
0184     return ret;
0185 }
0186 
0187 static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
0188 {
0189     struct exc3000_data *data = dev_id;
0190     u8 *buf = data->buf;
0191     int ret;
0192 
0193     ret = exc3000_read_frame(data, buf);
0194     if (ret) {
0195         /* Schedule a timer to release "stuck" contacts */
0196         exc3000_schedule_timer(data);
0197         goto out;
0198     }
0199 
0200     switch (buf[2]) {
0201     case EXC3000_VENDOR_EVENT:
0202         complete(&data->wait_event);
0203         break;
0204 
0205     case EXC3000_MT1_EVENT:
0206     case EXC3000_MT2_EVENT:
0207         exc3000_handle_mt_event(data);
0208         break;
0209 
0210     default:
0211         break;
0212     }
0213 
0214 out:
0215     return IRQ_HANDLED;
0216 }
0217 
0218 static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
0219                        u8 request_len, u8 *response, int timeout)
0220 {
0221     u8 buf[EXC3000_LEN_VENDOR_REQUEST] = { 0x67, 0x00, 0x42, 0x00, 0x03 };
0222     int ret;
0223     unsigned long time_left;
0224 
0225     mutex_lock(&data->query_lock);
0226 
0227     reinit_completion(&data->wait_event);
0228 
0229     buf[5] = request_len;
0230     memcpy(&buf[6], request, request_len);
0231 
0232     ret = i2c_master_send(data->client, buf, EXC3000_LEN_VENDOR_REQUEST);
0233     if (ret < 0)
0234         goto out_unlock;
0235 
0236     if (response) {
0237         time_left = wait_for_completion_timeout(&data->wait_event,
0238                             timeout * HZ);
0239         if (time_left == 0) {
0240             ret = -ETIMEDOUT;
0241             goto out_unlock;
0242         }
0243 
0244         if (data->buf[3] >= EXC3000_LEN_FRAME) {
0245             ret = -ENOSPC;
0246             goto out_unlock;
0247         }
0248 
0249         memcpy(response, &data->buf[4], data->buf[3]);
0250         ret = data->buf[3];
0251     }
0252 
0253 out_unlock:
0254     mutex_unlock(&data->query_lock);
0255 
0256     return ret;
0257 }
0258 
0259 static ssize_t fw_version_show(struct device *dev,
0260                    struct device_attribute *attr, char *buf)
0261 {
0262     struct i2c_client *client = to_i2c_client(dev);
0263     struct exc3000_data *data = i2c_get_clientdata(client);
0264     u8 response[EXC3000_LEN_FRAME];
0265     int ret;
0266 
0267     /* query bootloader info */
0268     ret = exc3000_vendor_data_request(data,
0269                       (u8[]){0x39, 0x02}, 2, response, 1);
0270     if (ret < 0)
0271         return ret;
0272 
0273     /*
0274      * If the bootloader version is non-zero then the device is in
0275      * bootloader mode and won't answer a query for the application FW
0276      * version, so we just use the bootloader version info.
0277      */
0278     if (response[2] || response[3])
0279         return sprintf(buf, "%d.%d\n", response[2], response[3]);
0280 
0281     ret = exc3000_vendor_data_request(data, (u8[]){'D'}, 1, response, 1);
0282     if (ret < 0)
0283         return ret;
0284 
0285     return sprintf(buf, "%s\n", &response[1]);
0286 }
0287 static DEVICE_ATTR_RO(fw_version);
0288 
0289 static ssize_t model_show(struct device *dev,
0290               struct device_attribute *attr, char *buf)
0291 {
0292     struct i2c_client *client = to_i2c_client(dev);
0293     struct exc3000_data *data = i2c_get_clientdata(client);
0294     u8 response[EXC3000_LEN_FRAME];
0295     int ret;
0296 
0297     ret = exc3000_vendor_data_request(data, (u8[]){'E'}, 1, response, 1);
0298     if (ret < 0)
0299         return ret;
0300 
0301     return sprintf(buf, "%s\n", &response[1]);
0302 }
0303 static DEVICE_ATTR_RO(model);
0304 
0305 static ssize_t type_show(struct device *dev,
0306               struct device_attribute *attr, char *buf)
0307 {
0308     struct i2c_client *client = to_i2c_client(dev);
0309     struct exc3000_data *data = i2c_get_clientdata(client);
0310     u8 response[EXC3000_LEN_FRAME];
0311     int ret;
0312 
0313     ret = exc3000_vendor_data_request(data, (u8[]){'F'}, 1, response, 1);
0314     if (ret < 0)
0315         return ret;
0316 
0317     return sprintf(buf, "%s\n", &response[1]);
0318 }
0319 static DEVICE_ATTR_RO(type);
0320 
0321 static struct attribute *sysfs_attrs[] = {
0322     &dev_attr_fw_version.attr,
0323     &dev_attr_model.attr,
0324     &dev_attr_type.attr,
0325     NULL
0326 };
0327 
0328 static struct attribute_group exc3000_attribute_group = {
0329     .attrs = sysfs_attrs
0330 };
0331 
0332 static int exc3000_probe(struct i2c_client *client)
0333 {
0334     struct exc3000_data *data;
0335     struct input_dev *input;
0336     int error, max_xy, retry;
0337 
0338     data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
0339     if (!data)
0340         return -ENOMEM;
0341 
0342     data->client = client;
0343     data->info = device_get_match_data(&client->dev);
0344     if (!data->info) {
0345         enum eeti_dev_id eeti_dev_id =
0346             i2c_match_id(exc3000_id, client)->driver_data;
0347         data->info = &exc3000_info[eeti_dev_id];
0348     }
0349     timer_setup(&data->timer, exc3000_timer, 0);
0350     init_completion(&data->wait_event);
0351     mutex_init(&data->query_lock);
0352 
0353     data->reset = devm_gpiod_get_optional(&client->dev, "reset",
0354                           GPIOD_OUT_HIGH);
0355     if (IS_ERR(data->reset))
0356         return PTR_ERR(data->reset);
0357 
0358     if (data->reset) {
0359         msleep(EXC3000_RESET_MS);
0360         gpiod_set_value_cansleep(data->reset, 0);
0361         msleep(EXC3000_READY_MS);
0362     }
0363 
0364     input = devm_input_allocate_device(&client->dev);
0365     if (!input)
0366         return -ENOMEM;
0367 
0368     data->input = input;
0369     input_set_drvdata(input, data);
0370 
0371     input->name = data->info->name;
0372     input->id.bustype = BUS_I2C;
0373 
0374     max_xy = data->info->max_xy;
0375     input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0);
0376     input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0);
0377 
0378     touchscreen_parse_properties(input, true, &data->prop);
0379 
0380     error = input_mt_init_slots(input, EXC3000_NUM_SLOTS,
0381                     INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
0382     if (error)
0383         return error;
0384 
0385     error = input_register_device(input);
0386     if (error)
0387         return error;
0388 
0389     error = devm_request_threaded_irq(&client->dev, client->irq,
0390                       NULL, exc3000_interrupt, IRQF_ONESHOT,
0391                       client->name, data);
0392     if (error)
0393         return error;
0394 
0395     /*
0396      * I²C does not have built-in recovery, so retry on failure. This
0397      * ensures, that the device probe will not fail for temporary issues
0398      * on the bus.  This is not needed for the sysfs calls (userspace
0399      * will receive the error code and can start another query) and
0400      * cannot be done for touch events (but that only means loosing one
0401      * or two touch events anyways).
0402      */
0403     for (retry = 0; retry < 3; retry++) {
0404         u8 response[EXC3000_LEN_FRAME];
0405 
0406         error = exc3000_vendor_data_request(data, (u8[]){'E'}, 1,
0407                             response, 1);
0408         if (error > 0) {
0409             dev_dbg(&client->dev, "TS Model: %s", &response[1]);
0410             error = 0;
0411             break;
0412         }
0413         dev_warn(&client->dev, "Retry %d get EETI EXC3000 model: %d\n",
0414              retry + 1, error);
0415     }
0416 
0417     if (error)
0418         return error;
0419 
0420     i2c_set_clientdata(client, data);
0421 
0422     error = devm_device_add_group(&client->dev, &exc3000_attribute_group);
0423     if (error)
0424         return error;
0425 
0426     return 0;
0427 }
0428 
0429 static const struct i2c_device_id exc3000_id[] = {
0430     { "exc3000", EETI_EXC3000 },
0431     { "exc80h60", EETI_EXC80H60 },
0432     { "exc80h84", EETI_EXC80H84 },
0433     { }
0434 };
0435 MODULE_DEVICE_TABLE(i2c, exc3000_id);
0436 
0437 #ifdef CONFIG_OF
0438 static const struct of_device_id exc3000_of_match[] = {
0439     { .compatible = "eeti,exc3000", .data = &exc3000_info[EETI_EXC3000] },
0440     { .compatible = "eeti,exc80h60", .data = &exc3000_info[EETI_EXC80H60] },
0441     { .compatible = "eeti,exc80h84", .data = &exc3000_info[EETI_EXC80H84] },
0442     { }
0443 };
0444 MODULE_DEVICE_TABLE(of, exc3000_of_match);
0445 #endif
0446 
0447 static struct i2c_driver exc3000_driver = {
0448     .driver = {
0449         .name   = "exc3000",
0450         .of_match_table = of_match_ptr(exc3000_of_match),
0451     },
0452     .id_table   = exc3000_id,
0453     .probe_new  = exc3000_probe,
0454 };
0455 
0456 module_i2c_driver(exc3000_driver);
0457 
0458 MODULE_AUTHOR("Ahmet Inan <inan@distec.de>");
0459 MODULE_DESCRIPTION("I2C connected EETI EXC3000 multiple touch controller driver");
0460 MODULE_LICENSE("GPL v2");