1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Driver for cypress touch screen controller 4 * 5 * Copyright (c) 2009 Aava Mobile 6 * 7 * Some cleanups by Alan Cox <alan@linux.intel.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/kernel.h> 12 #include <linux/input.h> 13 #include <linux/slab.h> 14 #include <linux/interrupt.h> 15 #include <linux/io.h> 16 #include <linux/i2c.h> 17 #include <linux/gpio.h> 18 #include <linux/input/cy8ctmg110_pdata.h> 19 20 #define CY8CTMG110_DRIVER_NAME "cy8ctmg110" 21 22 /* Touch coordinates */ 23 #define CY8CTMG110_X_MIN 0 24 #define CY8CTMG110_Y_MIN 0 25 #define CY8CTMG110_X_MAX 759 26 #define CY8CTMG110_Y_MAX 465 27 28 29 /* cy8ctmg110 register definitions */ 30 #define CY8CTMG110_TOUCH_WAKEUP_TIME 0 31 #define CY8CTMG110_TOUCH_SLEEP_TIME 2 32 #define CY8CTMG110_TOUCH_X1 3 33 #define CY8CTMG110_TOUCH_Y1 5 34 #define CY8CTMG110_TOUCH_X2 7 35 #define CY8CTMG110_TOUCH_Y2 9 36 #define CY8CTMG110_FINGERS 11 37 #define CY8CTMG110_GESTURE 12 38 #define CY8CTMG110_REG_MAX 13 39 40 41 /* 42 * The touch driver structure. 43 */ 44 struct cy8ctmg110 { 45 struct input_dev *input; 46 char phys[32]; 47 struct i2c_client *client; 48 int reset_pin; 49 int irq_pin; 50 }; 51 52 /* 53 * cy8ctmg110_power is the routine that is called when touch hardware 54 * will powered off or on. 55 */ 56 static void cy8ctmg110_power(struct cy8ctmg110 *ts, bool poweron) 57 { 58 if (ts->reset_pin) 59 gpio_direction_output(ts->reset_pin, 1 - poweron); 60 } 61 62 static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg, 63 unsigned char len, unsigned char *value) 64 { 65 struct i2c_client *client = tsc->client; 66 int ret; 67 unsigned char i2c_data[6]; 68 69 BUG_ON(len > 5); 70 71 i2c_data[0] = reg; 72 memcpy(i2c_data + 1, value, len); 73 74 ret = i2c_master_send(client, i2c_data, len + 1); 75 if (ret != len + 1) { 76 dev_err(&client->dev, "i2c write data cmd failed\n"); 77 return ret < 0 ? ret : -EIO; 78 } 79 80 return 0; 81 } 82 83 static int cy8ctmg110_read_regs(struct cy8ctmg110 *tsc, 84 unsigned char *data, unsigned char len, unsigned char cmd) 85 { 86 struct i2c_client *client = tsc->client; 87 int ret; 88 struct i2c_msg msg[2] = { 89 /* first write slave position to i2c devices */ 90 { 91 .addr = client->addr, 92 .len = 1, 93 .buf = &cmd 94 }, 95 /* Second read data from position */ 96 { 97 .addr = client->addr, 98 .flags = I2C_M_RD, 99 .len = len, 100 .buf = data 101 } 102 }; 103 104 ret = i2c_transfer(client->adapter, msg, 2); 105 if (ret < 0) 106 return ret; 107 108 return 0; 109 } 110 111 static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc) 112 { 113 struct input_dev *input = tsc->input; 114 unsigned char reg_p[CY8CTMG110_REG_MAX]; 115 int x, y; 116 117 memset(reg_p, 0, CY8CTMG110_REG_MAX); 118 119 /* Reading coordinates */ 120 if (cy8ctmg110_read_regs(tsc, reg_p, 9, CY8CTMG110_TOUCH_X1) != 0) 121 return -EIO; 122 123 y = reg_p[2] << 8 | reg_p[3]; 124 x = reg_p[0] << 8 | reg_p[1]; 125 126 /* Number of touch */ 127 if (reg_p[8] == 0) { 128 input_report_key(input, BTN_TOUCH, 0); 129 } else { 130 input_report_key(input, BTN_TOUCH, 1); 131 input_report_abs(input, ABS_X, x); 132 input_report_abs(input, ABS_Y, y); 133 } 134 135 input_sync(input); 136 137 return 0; 138 } 139 140 static int cy8ctmg110_set_sleepmode(struct cy8ctmg110 *ts, bool sleep) 141 { 142 unsigned char reg_p[3]; 143 144 if (sleep) { 145 reg_p[0] = 0x00; 146 reg_p[1] = 0xff; 147 reg_p[2] = 5; 148 } else { 149 reg_p[0] = 0x10; 150 reg_p[1] = 0xff; 151 reg_p[2] = 0; 152 } 153 154 return cy8ctmg110_write_regs(ts, CY8CTMG110_TOUCH_WAKEUP_TIME, 3, reg_p); 155 } 156 157 static irqreturn_t cy8ctmg110_irq_thread(int irq, void *dev_id) 158 { 159 struct cy8ctmg110 *tsc = dev_id; 160 161 cy8ctmg110_touch_pos(tsc); 162 163 return IRQ_HANDLED; 164 } 165 166 static int cy8ctmg110_probe(struct i2c_client *client, 167 const struct i2c_device_id *id) 168 { 169 const struct cy8ctmg110_pdata *pdata = dev_get_platdata(&client->dev); 170 struct cy8ctmg110 *ts; 171 struct input_dev *input_dev; 172 int err; 173 174 /* No pdata no way forward */ 175 if (pdata == NULL) { 176 dev_err(&client->dev, "no pdata\n"); 177 return -ENODEV; 178 } 179 180 if (!i2c_check_functionality(client->adapter, 181 I2C_FUNC_SMBUS_READ_WORD_DATA)) 182 return -EIO; 183 184 ts = kzalloc(sizeof(struct cy8ctmg110), GFP_KERNEL); 185 input_dev = input_allocate_device(); 186 if (!ts || !input_dev) { 187 err = -ENOMEM; 188 goto err_free_mem; 189 } 190 191 ts->client = client; 192 ts->input = input_dev; 193 ts->reset_pin = pdata->reset_pin; 194 ts->irq_pin = pdata->irq_pin; 195 196 snprintf(ts->phys, sizeof(ts->phys), 197 "%s/input0", dev_name(&client->dev)); 198 199 input_dev->name = CY8CTMG110_DRIVER_NAME " Touchscreen"; 200 input_dev->phys = ts->phys; 201 input_dev->id.bustype = BUS_I2C; 202 input_dev->dev.parent = &client->dev; 203 204 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 205 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 206 207 input_set_abs_params(input_dev, ABS_X, 208 CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0); 209 input_set_abs_params(input_dev, ABS_Y, 210 CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0); 211 212 if (ts->reset_pin) { 213 err = gpio_request(ts->reset_pin, NULL); 214 if (err) { 215 dev_err(&client->dev, 216 "Unable to request GPIO pin %d.\n", 217 ts->reset_pin); 218 goto err_free_mem; 219 } 220 } 221 222 cy8ctmg110_power(ts, true); 223 cy8ctmg110_set_sleepmode(ts, false); 224 225 err = gpio_request(ts->irq_pin, "touch_irq_key"); 226 if (err < 0) { 227 dev_err(&client->dev, 228 "Failed to request GPIO %d, error %d\n", 229 ts->irq_pin, err); 230 goto err_shutoff_device; 231 } 232 233 err = gpio_direction_input(ts->irq_pin); 234 if (err < 0) { 235 dev_err(&client->dev, 236 "Failed to configure input direction for GPIO %d, error %d\n", 237 ts->irq_pin, err); 238 goto err_free_irq_gpio; 239 } 240 241 client->irq = gpio_to_irq(ts->irq_pin); 242 if (client->irq < 0) { 243 err = client->irq; 244 dev_err(&client->dev, 245 "Unable to get irq number for GPIO %d, error %d\n", 246 ts->irq_pin, err); 247 goto err_free_irq_gpio; 248 } 249 250 err = request_threaded_irq(client->irq, NULL, cy8ctmg110_irq_thread, 251 IRQF_TRIGGER_RISING | IRQF_ONESHOT, 252 "touch_reset_key", ts); 253 if (err < 0) { 254 dev_err(&client->dev, 255 "irq %d busy? error %d\n", client->irq, err); 256 goto err_free_irq_gpio; 257 } 258 259 err = input_register_device(input_dev); 260 if (err) 261 goto err_free_irq; 262 263 i2c_set_clientdata(client, ts); 264 device_init_wakeup(&client->dev, 1); 265 return 0; 266 267 err_free_irq: 268 free_irq(client->irq, ts); 269 err_free_irq_gpio: 270 gpio_free(ts->irq_pin); 271 err_shutoff_device: 272 cy8ctmg110_set_sleepmode(ts, true); 273 cy8ctmg110_power(ts, false); 274 if (ts->reset_pin) 275 gpio_free(ts->reset_pin); 276 err_free_mem: 277 input_free_device(input_dev); 278 kfree(ts); 279 return err; 280 } 281 282 static int __maybe_unused cy8ctmg110_suspend(struct device *dev) 283 { 284 struct i2c_client *client = to_i2c_client(dev); 285 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 286 287 if (device_may_wakeup(&client->dev)) 288 enable_irq_wake(client->irq); 289 else { 290 cy8ctmg110_set_sleepmode(ts, true); 291 cy8ctmg110_power(ts, false); 292 } 293 return 0; 294 } 295 296 static int __maybe_unused cy8ctmg110_resume(struct device *dev) 297 { 298 struct i2c_client *client = to_i2c_client(dev); 299 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 300 301 if (device_may_wakeup(&client->dev)) 302 disable_irq_wake(client->irq); 303 else { 304 cy8ctmg110_power(ts, true); 305 cy8ctmg110_set_sleepmode(ts, false); 306 } 307 return 0; 308 } 309 310 static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); 311 312 static int cy8ctmg110_remove(struct i2c_client *client) 313 { 314 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 315 316 cy8ctmg110_set_sleepmode(ts, true); 317 cy8ctmg110_power(ts, false); 318 319 free_irq(client->irq, ts); 320 input_unregister_device(ts->input); 321 gpio_free(ts->irq_pin); 322 if (ts->reset_pin) 323 gpio_free(ts->reset_pin); 324 kfree(ts); 325 326 return 0; 327 } 328 329 static const struct i2c_device_id cy8ctmg110_idtable[] = { 330 { CY8CTMG110_DRIVER_NAME, 1 }, 331 { } 332 }; 333 334 MODULE_DEVICE_TABLE(i2c, cy8ctmg110_idtable); 335 336 static struct i2c_driver cy8ctmg110_driver = { 337 .driver = { 338 .name = CY8CTMG110_DRIVER_NAME, 339 .pm = &cy8ctmg110_pm, 340 }, 341 .id_table = cy8ctmg110_idtable, 342 .probe = cy8ctmg110_probe, 343 .remove = cy8ctmg110_remove, 344 }; 345 346 module_i2c_driver(cy8ctmg110_driver); 347 348 MODULE_AUTHOR("Samuli Konttila <samuli.konttila@aavamobile.com>"); 349 MODULE_DESCRIPTION("cy8ctmg110 TouchScreen Driver"); 350 MODULE_LICENSE("GPL v2"); 351