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