1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for EETI eGalax Multiple Touch Controller 4 * 5 * Copyright (C) 2011 Freescale Semiconductor, Inc. 6 * 7 * based on max11801_ts.c 8 */ 9 10 /* EETI eGalax serial touch screen controller is a I2C based multiple 11 * touch screen controller, it supports 5 point multiple touch. */ 12 13 /* TODO: 14 - auto idle mode support 15 */ 16 17 #include <linux/err.h> 18 #include <linux/module.h> 19 #include <linux/i2c.h> 20 #include <linux/interrupt.h> 21 #include <linux/input.h> 22 #include <linux/irq.h> 23 #include <linux/gpio/consumer.h> 24 #include <linux/delay.h> 25 #include <linux/slab.h> 26 #include <linux/bitops.h> 27 #include <linux/input/mt.h> 28 29 /* 30 * Mouse Mode: some panel may configure the controller to mouse mode, 31 * which can only report one point at a given time. 32 * This driver will ignore events in this mode. 33 */ 34 #define REPORT_MODE_MOUSE 0x1 35 /* 36 * Vendor Mode: this mode is used to transfer some vendor specific 37 * messages. 38 * This driver will ignore events in this mode. 39 */ 40 #define REPORT_MODE_VENDOR 0x3 41 /* Multiple Touch Mode */ 42 #define REPORT_MODE_MTTOUCH 0x4 43 44 #define MAX_SUPPORT_POINTS 5 45 46 #define EVENT_VALID_OFFSET 7 47 #define EVENT_VALID_MASK (0x1 << EVENT_VALID_OFFSET) 48 #define EVENT_ID_OFFSET 2 49 #define EVENT_ID_MASK (0xf << EVENT_ID_OFFSET) 50 #define EVENT_IN_RANGE (0x1 << 1) 51 #define EVENT_DOWN_UP (0X1 << 0) 52 53 #define MAX_I2C_DATA_LEN 10 54 55 #define EGALAX_MAX_X 32760 56 #define EGALAX_MAX_Y 32760 57 #define EGALAX_MAX_TRIES 100 58 59 struct egalax_ts { 60 struct i2c_client *client; 61 struct input_dev *input_dev; 62 }; 63 64 static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) 65 { 66 struct egalax_ts *ts = dev_id; 67 struct input_dev *input_dev = ts->input_dev; 68 struct i2c_client *client = ts->client; 69 u8 buf[MAX_I2C_DATA_LEN]; 70 int id, ret, x, y, z; 71 int tries = 0; 72 bool down, valid; 73 u8 state; 74 75 do { 76 ret = i2c_master_recv(client, buf, MAX_I2C_DATA_LEN); 77 } while (ret == -EAGAIN && tries++ < EGALAX_MAX_TRIES); 78 79 if (ret < 0) 80 return IRQ_HANDLED; 81 82 if (buf[0] != REPORT_MODE_MTTOUCH) { 83 /* ignore mouse events and vendor events */ 84 return IRQ_HANDLED; 85 } 86 87 state = buf[1]; 88 x = (buf[3] << 8) | buf[2]; 89 y = (buf[5] << 8) | buf[4]; 90 z = (buf[7] << 8) | buf[6]; 91 92 valid = state & EVENT_VALID_MASK; 93 id = (state & EVENT_ID_MASK) >> EVENT_ID_OFFSET; 94 down = state & EVENT_DOWN_UP; 95 96 if (!valid || id > MAX_SUPPORT_POINTS) { 97 dev_dbg(&client->dev, "point invalid\n"); 98 return IRQ_HANDLED; 99 } 100 101 input_mt_slot(input_dev, id); 102 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, down); 103 104 dev_dbg(&client->dev, "%s id:%d x:%d y:%d z:%d", 105 down ? "down" : "up", id, x, y, z); 106 107 if (down) { 108 input_report_abs(input_dev, ABS_MT_POSITION_X, x); 109 input_report_abs(input_dev, ABS_MT_POSITION_Y, y); 110 input_report_abs(input_dev, ABS_MT_PRESSURE, z); 111 } 112 113 input_mt_report_pointer_emulation(input_dev, true); 114 input_sync(input_dev); 115 116 return IRQ_HANDLED; 117 } 118 119 /* wake up controller by an falling edge of interrupt gpio. */ 120 static int egalax_wake_up_device(struct i2c_client *client) 121 { 122 struct gpio_desc *gpio; 123 int ret; 124 125 /* wake up controller via an falling edge on IRQ gpio. */ 126 gpio = gpiod_get(&client->dev, "wakeup", GPIOD_OUT_HIGH); 127 ret = PTR_ERR_OR_ZERO(gpio); 128 if (ret) { 129 if (ret != -EPROBE_DEFER) 130 dev_err(&client->dev, 131 "failed to request wakeup gpio, cannot wake up controller: %d\n", 132 ret); 133 return ret; 134 } 135 136 /* release the line */ 137 gpiod_set_value_cansleep(gpio, 0); 138 139 /* controller should be woken up, return irq. */ 140 gpiod_direction_input(gpio); 141 gpiod_put(gpio); 142 143 return 0; 144 } 145 146 static int egalax_firmware_version(struct i2c_client *client) 147 { 148 static const u8 cmd[MAX_I2C_DATA_LEN] = { 0x03, 0x03, 0xa, 0x01, 0x41 }; 149 int ret; 150 151 ret = i2c_master_send(client, cmd, MAX_I2C_DATA_LEN); 152 if (ret < 0) 153 return ret; 154 155 return 0; 156 } 157 158 static int egalax_ts_probe(struct i2c_client *client) 159 { 160 struct egalax_ts *ts; 161 struct input_dev *input_dev; 162 int error; 163 164 ts = devm_kzalloc(&client->dev, sizeof(struct egalax_ts), GFP_KERNEL); 165 if (!ts) { 166 dev_err(&client->dev, "Failed to allocate memory\n"); 167 return -ENOMEM; 168 } 169 170 input_dev = devm_input_allocate_device(&client->dev); 171 if (!input_dev) { 172 dev_err(&client->dev, "Failed to allocate memory\n"); 173 return -ENOMEM; 174 } 175 176 ts->client = client; 177 ts->input_dev = input_dev; 178 179 /* controller may be in sleep, wake it up. */ 180 error = egalax_wake_up_device(client); 181 if (error) 182 return error; 183 184 error = egalax_firmware_version(client); 185 if (error < 0) { 186 dev_err(&client->dev, "Failed to read firmware version\n"); 187 return error; 188 } 189 190 input_dev->name = "EETI eGalax Touch Screen"; 191 input_dev->id.bustype = BUS_I2C; 192 193 __set_bit(EV_ABS, input_dev->evbit); 194 __set_bit(EV_KEY, input_dev->evbit); 195 __set_bit(BTN_TOUCH, input_dev->keybit); 196 197 input_set_abs_params(input_dev, ABS_X, 0, EGALAX_MAX_X, 0, 0); 198 input_set_abs_params(input_dev, ABS_Y, 0, EGALAX_MAX_Y, 0, 0); 199 input_set_abs_params(input_dev, 200 ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0); 201 input_set_abs_params(input_dev, 202 ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0); 203 input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0); 204 205 error = devm_request_threaded_irq(&client->dev, client->irq, 206 NULL, egalax_ts_interrupt, 207 IRQF_ONESHOT, "egalax_ts", ts); 208 if (error < 0) { 209 dev_err(&client->dev, "Failed to register interrupt\n"); 210 return error; 211 } 212 213 error = input_register_device(ts->input_dev); 214 if (error) 215 return error; 216 217 return 0; 218 } 219 220 static const struct i2c_device_id egalax_ts_id[] = { 221 { "egalax_ts", 0 }, 222 { } 223 }; 224 MODULE_DEVICE_TABLE(i2c, egalax_ts_id); 225 226 static int __maybe_unused egalax_ts_suspend(struct device *dev) 227 { 228 static const u8 suspend_cmd[MAX_I2C_DATA_LEN] = { 229 0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0 230 }; 231 struct i2c_client *client = to_i2c_client(dev); 232 int ret; 233 234 if (device_may_wakeup(dev)) 235 return enable_irq_wake(client->irq); 236 237 ret = i2c_master_send(client, suspend_cmd, MAX_I2C_DATA_LEN); 238 return ret > 0 ? 0 : ret; 239 } 240 241 static int __maybe_unused egalax_ts_resume(struct device *dev) 242 { 243 struct i2c_client *client = to_i2c_client(dev); 244 245 if (device_may_wakeup(dev)) 246 return disable_irq_wake(client->irq); 247 248 return egalax_wake_up_device(client); 249 } 250 251 static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); 252 253 static const struct of_device_id egalax_ts_dt_ids[] = { 254 { .compatible = "eeti,egalax_ts" }, 255 { /* sentinel */ } 256 }; 257 MODULE_DEVICE_TABLE(of, egalax_ts_dt_ids); 258 259 static struct i2c_driver egalax_ts_driver = { 260 .driver = { 261 .name = "egalax_ts", 262 .pm = &egalax_ts_pm_ops, 263 .of_match_table = egalax_ts_dt_ids, 264 }, 265 .id_table = egalax_ts_id, 266 .probe_new = egalax_ts_probe, 267 }; 268 269 module_i2c_driver(egalax_ts_driver); 270 271 MODULE_AUTHOR("Freescale Semiconductor, Inc."); 272 MODULE_DESCRIPTION("Touchscreen driver for EETI eGalax touch controller"); 273 MODULE_LICENSE("GPL"); 274