19c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2c6d81bd7SHeiko Stübner /* 3c6d81bd7SHeiko Stübner * Copyright (C) 2012-2013 MundoReader S.L. 4c6d81bd7SHeiko Stübner * Author: Heiko Stuebner <heiko@sntech.de> 5c6d81bd7SHeiko Stübner * 6c6d81bd7SHeiko Stübner * based in parts on Nook zforce driver 7c6d81bd7SHeiko Stübner * 8c6d81bd7SHeiko Stübner * Copyright (C) 2010 Barnes & Noble, Inc. 9c6d81bd7SHeiko Stübner * Author: Pieter Truter<ptruter@intrinsyc.com> 10c6d81bd7SHeiko Stübner */ 11c6d81bd7SHeiko Stübner 12c6d81bd7SHeiko Stübner #include <linux/module.h> 13c6d81bd7SHeiko Stübner #include <linux/hrtimer.h> 14c6d81bd7SHeiko Stübner #include <linux/slab.h> 15c6d81bd7SHeiko Stübner #include <linux/input.h> 16c6d81bd7SHeiko Stübner #include <linux/interrupt.h> 17c6d81bd7SHeiko Stübner #include <linux/i2c.h> 18c6d81bd7SHeiko Stübner #include <linux/delay.h> 192d538095SDirk Behme #include <linux/gpio/consumer.h> 20c6d81bd7SHeiko Stübner #include <linux/device.h> 21c6d81bd7SHeiko Stübner #include <linux/sysfs.h> 22c6d81bd7SHeiko Stübner #include <linux/input/mt.h> 23c6d81bd7SHeiko Stübner #include <linux/platform_data/zforce_ts.h> 2439740370SHeiko Stuebner #include <linux/regulator/consumer.h> 256f2e6c9bSHeiko Stübner #include <linux/of.h> 26c6d81bd7SHeiko Stübner 27c6d81bd7SHeiko Stübner #define WAIT_TIMEOUT msecs_to_jiffies(1000) 28c6d81bd7SHeiko Stübner 29c6d81bd7SHeiko Stübner #define FRAME_START 0xee 30d333b606SLuis Ortega #define FRAME_MAXSIZE 257 31c6d81bd7SHeiko Stübner 32c6d81bd7SHeiko Stübner /* Offsets of the different parts of the payload the controller sends */ 33c6d81bd7SHeiko Stübner #define PAYLOAD_HEADER 0 34c6d81bd7SHeiko Stübner #define PAYLOAD_LENGTH 1 35c6d81bd7SHeiko Stübner #define PAYLOAD_BODY 2 36c6d81bd7SHeiko Stübner 37c6d81bd7SHeiko Stübner /* Response offsets */ 38c6d81bd7SHeiko Stübner #define RESPONSE_ID 0 39c6d81bd7SHeiko Stübner #define RESPONSE_DATA 1 40c6d81bd7SHeiko Stübner 41c6d81bd7SHeiko Stübner /* Commands */ 42c6d81bd7SHeiko Stübner #define COMMAND_DEACTIVATE 0x00 43c6d81bd7SHeiko Stübner #define COMMAND_INITIALIZE 0x01 44c6d81bd7SHeiko Stübner #define COMMAND_RESOLUTION 0x02 45c6d81bd7SHeiko Stübner #define COMMAND_SETCONFIG 0x03 46c6d81bd7SHeiko Stübner #define COMMAND_DATAREQUEST 0x04 47c6d81bd7SHeiko Stübner #define COMMAND_SCANFREQ 0x08 48c6d81bd7SHeiko Stübner #define COMMAND_STATUS 0X1e 49c6d81bd7SHeiko Stübner 50c6d81bd7SHeiko Stübner /* 51c6d81bd7SHeiko Stübner * Responses the controller sends as a result of 52c6d81bd7SHeiko Stübner * command requests 53c6d81bd7SHeiko Stübner */ 54c6d81bd7SHeiko Stübner #define RESPONSE_DEACTIVATE 0x00 55c6d81bd7SHeiko Stübner #define RESPONSE_INITIALIZE 0x01 56c6d81bd7SHeiko Stübner #define RESPONSE_RESOLUTION 0x02 57c6d81bd7SHeiko Stübner #define RESPONSE_SETCONFIG 0x03 58c6d81bd7SHeiko Stübner #define RESPONSE_SCANFREQ 0x08 59c6d81bd7SHeiko Stübner #define RESPONSE_STATUS 0X1e 60c6d81bd7SHeiko Stübner 61c6d81bd7SHeiko Stübner /* 62deb49819SLuis Ortega * Notifications are sent by the touch controller without 63c6d81bd7SHeiko Stübner * being requested by the driver and include for example 64c6d81bd7SHeiko Stübner * touch indications 65c6d81bd7SHeiko Stübner */ 66c6d81bd7SHeiko Stübner #define NOTIFICATION_TOUCH 0x04 67c6d81bd7SHeiko Stübner #define NOTIFICATION_BOOTCOMPLETE 0x07 68c6d81bd7SHeiko Stübner #define NOTIFICATION_OVERRUN 0x25 69c6d81bd7SHeiko Stübner #define NOTIFICATION_PROXIMITY 0x26 70c6d81bd7SHeiko Stübner #define NOTIFICATION_INVALID_COMMAND 0xfe 71c6d81bd7SHeiko Stübner 72c6d81bd7SHeiko Stübner #define ZFORCE_REPORT_POINTS 2 73c6d81bd7SHeiko Stübner #define ZFORCE_MAX_AREA 0xff 74c6d81bd7SHeiko Stübner 75c6d81bd7SHeiko Stübner #define STATE_DOWN 0 76c6d81bd7SHeiko Stübner #define STATE_MOVE 1 77c6d81bd7SHeiko Stübner #define STATE_UP 2 78c6d81bd7SHeiko Stübner 79c6d81bd7SHeiko Stübner #define SETCONFIG_DUALTOUCH (1 << 0) 80c6d81bd7SHeiko Stübner 81c6d81bd7SHeiko Stübner struct zforce_point { 82c6d81bd7SHeiko Stübner int coord_x; 83c6d81bd7SHeiko Stübner int coord_y; 84c6d81bd7SHeiko Stübner int state; 85c6d81bd7SHeiko Stübner int id; 86c6d81bd7SHeiko Stübner int area_major; 87c6d81bd7SHeiko Stübner int area_minor; 88c6d81bd7SHeiko Stübner int orientation; 89c6d81bd7SHeiko Stübner int pressure; 90c6d81bd7SHeiko Stübner int prblty; 91c6d81bd7SHeiko Stübner }; 92c6d81bd7SHeiko Stübner 93c6d81bd7SHeiko Stübner /* 94c6d81bd7SHeiko Stübner * @client the i2c_client 95c6d81bd7SHeiko Stübner * @input the input device 96c6d81bd7SHeiko Stübner * @suspending in the process of going to suspend (don't emit wakeup 97c6d81bd7SHeiko Stübner * events for commands executed to suspend the device) 98c6d81bd7SHeiko Stübner * @suspended device suspended 99c6d81bd7SHeiko Stübner * @access_mutex serialize i2c-access, to keep multipart reads together 100c6d81bd7SHeiko Stübner * @command_done completion to wait for the command result 101deb49819SLuis Ortega * @command_mutex serialize commands sent to the ic 102deb49819SLuis Ortega * @command_waiting the id of the command that is currently waiting 103c6d81bd7SHeiko Stübner * for a result 104c6d81bd7SHeiko Stübner * @command_result returned result of the command 105c6d81bd7SHeiko Stübner */ 106c6d81bd7SHeiko Stübner struct zforce_ts { 107c6d81bd7SHeiko Stübner struct i2c_client *client; 108c6d81bd7SHeiko Stübner struct input_dev *input; 109c6d81bd7SHeiko Stübner const struct zforce_ts_platdata *pdata; 110c6d81bd7SHeiko Stübner char phys[32]; 111c6d81bd7SHeiko Stübner 11239740370SHeiko Stuebner struct regulator *reg_vdd; 11339740370SHeiko Stuebner 1142d538095SDirk Behme struct gpio_desc *gpio_int; 1152d538095SDirk Behme struct gpio_desc *gpio_rst; 1162d538095SDirk Behme 117c6d81bd7SHeiko Stübner bool suspending; 118c6d81bd7SHeiko Stübner bool suspended; 119c6d81bd7SHeiko Stübner bool boot_complete; 120c6d81bd7SHeiko Stübner 121c6d81bd7SHeiko Stübner /* Firmware version information */ 122c6d81bd7SHeiko Stübner u16 version_major; 123c6d81bd7SHeiko Stübner u16 version_minor; 124c6d81bd7SHeiko Stübner u16 version_build; 125c6d81bd7SHeiko Stübner u16 version_rev; 126c6d81bd7SHeiko Stübner 127c6d81bd7SHeiko Stübner struct mutex access_mutex; 128c6d81bd7SHeiko Stübner 129c6d81bd7SHeiko Stübner struct completion command_done; 130c6d81bd7SHeiko Stübner struct mutex command_mutex; 131c6d81bd7SHeiko Stübner int command_waiting; 132c6d81bd7SHeiko Stübner int command_result; 133c6d81bd7SHeiko Stübner }; 134c6d81bd7SHeiko Stübner 135c6d81bd7SHeiko Stübner static int zforce_command(struct zforce_ts *ts, u8 cmd) 136c6d81bd7SHeiko Stübner { 137c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 138c6d81bd7SHeiko Stübner char buf[3]; 139c6d81bd7SHeiko Stübner int ret; 140c6d81bd7SHeiko Stübner 141c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "%s: 0x%x\n", __func__, cmd); 142c6d81bd7SHeiko Stübner 143c6d81bd7SHeiko Stübner buf[0] = FRAME_START; 144c6d81bd7SHeiko Stübner buf[1] = 1; /* data size, command only */ 145c6d81bd7SHeiko Stübner buf[2] = cmd; 146c6d81bd7SHeiko Stübner 147c6d81bd7SHeiko Stübner mutex_lock(&ts->access_mutex); 148c6d81bd7SHeiko Stübner ret = i2c_master_send(client, &buf[0], ARRAY_SIZE(buf)); 149c6d81bd7SHeiko Stübner mutex_unlock(&ts->access_mutex); 150c6d81bd7SHeiko Stübner if (ret < 0) { 151c6d81bd7SHeiko Stübner dev_err(&client->dev, "i2c send data request error: %d\n", ret); 152c6d81bd7SHeiko Stübner return ret; 153c6d81bd7SHeiko Stübner } 154c6d81bd7SHeiko Stübner 155c6d81bd7SHeiko Stübner return 0; 156c6d81bd7SHeiko Stübner } 157c6d81bd7SHeiko Stübner 1582d538095SDirk Behme static void zforce_reset_assert(struct zforce_ts *ts) 1592d538095SDirk Behme { 1602d538095SDirk Behme gpiod_set_value_cansleep(ts->gpio_rst, 1); 1612d538095SDirk Behme } 1622d538095SDirk Behme 1632d538095SDirk Behme static void zforce_reset_deassert(struct zforce_ts *ts) 1642d538095SDirk Behme { 1652d538095SDirk Behme gpiod_set_value_cansleep(ts->gpio_rst, 0); 1662d538095SDirk Behme } 1672d538095SDirk Behme 168c6d81bd7SHeiko Stübner static int zforce_send_wait(struct zforce_ts *ts, const char *buf, int len) 169c6d81bd7SHeiko Stübner { 170c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 171c6d81bd7SHeiko Stübner int ret; 172c6d81bd7SHeiko Stübner 173c6d81bd7SHeiko Stübner ret = mutex_trylock(&ts->command_mutex); 174c6d81bd7SHeiko Stübner if (!ret) { 175c6d81bd7SHeiko Stübner dev_err(&client->dev, "already waiting for a command\n"); 176c6d81bd7SHeiko Stübner return -EBUSY; 177c6d81bd7SHeiko Stübner } 178c6d81bd7SHeiko Stübner 179c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "sending %d bytes for command 0x%x\n", 180c6d81bd7SHeiko Stübner buf[1], buf[2]); 181c6d81bd7SHeiko Stübner 182c6d81bd7SHeiko Stübner ts->command_waiting = buf[2]; 183c6d81bd7SHeiko Stübner 184c6d81bd7SHeiko Stübner mutex_lock(&ts->access_mutex); 185c6d81bd7SHeiko Stübner ret = i2c_master_send(client, buf, len); 186c6d81bd7SHeiko Stübner mutex_unlock(&ts->access_mutex); 187c6d81bd7SHeiko Stübner if (ret < 0) { 188c6d81bd7SHeiko Stübner dev_err(&client->dev, "i2c send data request error: %d\n", ret); 189c6d81bd7SHeiko Stübner goto unlock; 190c6d81bd7SHeiko Stübner } 191c6d81bd7SHeiko Stübner 192c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "waiting for result for command 0x%x\n", buf[2]); 193c6d81bd7SHeiko Stübner 194c6d81bd7SHeiko Stübner if (wait_for_completion_timeout(&ts->command_done, WAIT_TIMEOUT) == 0) { 195c6d81bd7SHeiko Stübner ret = -ETIME; 196c6d81bd7SHeiko Stübner goto unlock; 197c6d81bd7SHeiko Stübner } 198c6d81bd7SHeiko Stübner 199c6d81bd7SHeiko Stübner ret = ts->command_result; 200c6d81bd7SHeiko Stübner 201c6d81bd7SHeiko Stübner unlock: 202c6d81bd7SHeiko Stübner mutex_unlock(&ts->command_mutex); 203c6d81bd7SHeiko Stübner return ret; 204c6d81bd7SHeiko Stübner } 205c6d81bd7SHeiko Stübner 206c6d81bd7SHeiko Stübner static int zforce_command_wait(struct zforce_ts *ts, u8 cmd) 207c6d81bd7SHeiko Stübner { 208c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 209c6d81bd7SHeiko Stübner char buf[3]; 210c6d81bd7SHeiko Stübner int ret; 211c6d81bd7SHeiko Stübner 212c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "%s: 0x%x\n", __func__, cmd); 213c6d81bd7SHeiko Stübner 214c6d81bd7SHeiko Stübner buf[0] = FRAME_START; 215c6d81bd7SHeiko Stübner buf[1] = 1; /* data size, command only */ 216c6d81bd7SHeiko Stübner buf[2] = cmd; 217c6d81bd7SHeiko Stübner 218c6d81bd7SHeiko Stübner ret = zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf)); 219c6d81bd7SHeiko Stübner if (ret < 0) { 220c6d81bd7SHeiko Stübner dev_err(&client->dev, "i2c send data request error: %d\n", ret); 221c6d81bd7SHeiko Stübner return ret; 222c6d81bd7SHeiko Stübner } 223c6d81bd7SHeiko Stübner 224c6d81bd7SHeiko Stübner return 0; 225c6d81bd7SHeiko Stübner } 226c6d81bd7SHeiko Stübner 227c6d81bd7SHeiko Stübner static int zforce_resolution(struct zforce_ts *ts, u16 x, u16 y) 228c6d81bd7SHeiko Stübner { 229c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 230c6d81bd7SHeiko Stübner char buf[7] = { FRAME_START, 5, COMMAND_RESOLUTION, 231c6d81bd7SHeiko Stübner (x & 0xff), ((x >> 8) & 0xff), 232c6d81bd7SHeiko Stübner (y & 0xff), ((y >> 8) & 0xff) }; 233c6d81bd7SHeiko Stübner 234c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "set resolution to (%d,%d)\n", x, y); 235c6d81bd7SHeiko Stübner 236c6d81bd7SHeiko Stübner return zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf)); 237c6d81bd7SHeiko Stübner } 238c6d81bd7SHeiko Stübner 239c6d81bd7SHeiko Stübner static int zforce_scan_frequency(struct zforce_ts *ts, u16 idle, u16 finger, 240c6d81bd7SHeiko Stübner u16 stylus) 241c6d81bd7SHeiko Stübner { 242c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 243c6d81bd7SHeiko Stübner char buf[9] = { FRAME_START, 7, COMMAND_SCANFREQ, 244c6d81bd7SHeiko Stübner (idle & 0xff), ((idle >> 8) & 0xff), 245c6d81bd7SHeiko Stübner (finger & 0xff), ((finger >> 8) & 0xff), 246c6d81bd7SHeiko Stübner (stylus & 0xff), ((stylus >> 8) & 0xff) }; 247c6d81bd7SHeiko Stübner 248ad697b96SLuis Ortega dev_dbg(&client->dev, 249ad697b96SLuis Ortega "set scan frequency to (idle: %d, finger: %d, stylus: %d)\n", 250c6d81bd7SHeiko Stübner idle, finger, stylus); 251c6d81bd7SHeiko Stübner 252c6d81bd7SHeiko Stübner return zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf)); 253c6d81bd7SHeiko Stübner } 254c6d81bd7SHeiko Stübner 255c6d81bd7SHeiko Stübner static int zforce_setconfig(struct zforce_ts *ts, char b1) 256c6d81bd7SHeiko Stübner { 257c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 258c6d81bd7SHeiko Stübner char buf[7] = { FRAME_START, 5, COMMAND_SETCONFIG, 259c6d81bd7SHeiko Stübner b1, 0, 0, 0 }; 260c6d81bd7SHeiko Stübner 261c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "set config to (%d)\n", b1); 262c6d81bd7SHeiko Stübner 263c6d81bd7SHeiko Stübner return zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf)); 264c6d81bd7SHeiko Stübner } 265c6d81bd7SHeiko Stübner 266c6d81bd7SHeiko Stübner static int zforce_start(struct zforce_ts *ts) 267c6d81bd7SHeiko Stübner { 268c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 26987273364SHeiko Stübner const struct zforce_ts_platdata *pdata = ts->pdata; 270c6d81bd7SHeiko Stübner int ret; 271c6d81bd7SHeiko Stübner 272c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "starting device\n"); 273c6d81bd7SHeiko Stübner 274c6d81bd7SHeiko Stübner ret = zforce_command_wait(ts, COMMAND_INITIALIZE); 275c6d81bd7SHeiko Stübner if (ret) { 276c6d81bd7SHeiko Stübner dev_err(&client->dev, "Unable to initialize, %d\n", ret); 277c6d81bd7SHeiko Stübner return ret; 278c6d81bd7SHeiko Stübner } 279c6d81bd7SHeiko Stübner 280c6d81bd7SHeiko Stübner ret = zforce_resolution(ts, pdata->x_max, pdata->y_max); 281c6d81bd7SHeiko Stübner if (ret) { 282c6d81bd7SHeiko Stübner dev_err(&client->dev, "Unable to set resolution, %d\n", ret); 283c6d81bd7SHeiko Stübner goto error; 284c6d81bd7SHeiko Stübner } 285c6d81bd7SHeiko Stübner 286c6d81bd7SHeiko Stübner ret = zforce_scan_frequency(ts, 10, 50, 50); 287c6d81bd7SHeiko Stübner if (ret) { 288c6d81bd7SHeiko Stübner dev_err(&client->dev, "Unable to set scan frequency, %d\n", 289c6d81bd7SHeiko Stübner ret); 290c6d81bd7SHeiko Stübner goto error; 291c6d81bd7SHeiko Stübner } 292c6d81bd7SHeiko Stübner 2933c4396b4SWei Yongjun ret = zforce_setconfig(ts, SETCONFIG_DUALTOUCH); 2943c4396b4SWei Yongjun if (ret) { 295c6d81bd7SHeiko Stübner dev_err(&client->dev, "Unable to set config\n"); 296c6d81bd7SHeiko Stübner goto error; 297c6d81bd7SHeiko Stübner } 298c6d81bd7SHeiko Stübner 299c6d81bd7SHeiko Stübner /* start sending touch events */ 300c6d81bd7SHeiko Stübner ret = zforce_command(ts, COMMAND_DATAREQUEST); 301c6d81bd7SHeiko Stübner if (ret) { 302c6d81bd7SHeiko Stübner dev_err(&client->dev, "Unable to request data\n"); 303c6d81bd7SHeiko Stübner goto error; 304c6d81bd7SHeiko Stübner } 305c6d81bd7SHeiko Stübner 306c6d81bd7SHeiko Stübner /* 307c6d81bd7SHeiko Stübner * Per NN, initial cal. take max. of 200msec. 308c6d81bd7SHeiko Stübner * Allow time to complete this calibration 309c6d81bd7SHeiko Stübner */ 310c6d81bd7SHeiko Stübner msleep(200); 311c6d81bd7SHeiko Stübner 312c6d81bd7SHeiko Stübner return 0; 313c6d81bd7SHeiko Stübner 314c6d81bd7SHeiko Stübner error: 315c6d81bd7SHeiko Stübner zforce_command_wait(ts, COMMAND_DEACTIVATE); 316c6d81bd7SHeiko Stübner return ret; 317c6d81bd7SHeiko Stübner } 318c6d81bd7SHeiko Stübner 319c6d81bd7SHeiko Stübner static int zforce_stop(struct zforce_ts *ts) 320c6d81bd7SHeiko Stübner { 321c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 322c6d81bd7SHeiko Stübner int ret; 323c6d81bd7SHeiko Stübner 324c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "stopping device\n"); 325c6d81bd7SHeiko Stübner 326c6d81bd7SHeiko Stübner /* Deactivates touch sensing and puts the device into sleep. */ 327c6d81bd7SHeiko Stübner ret = zforce_command_wait(ts, COMMAND_DEACTIVATE); 328c6d81bd7SHeiko Stübner if (ret != 0) { 329c6d81bd7SHeiko Stübner dev_err(&client->dev, "could not deactivate device, %d\n", 330c6d81bd7SHeiko Stübner ret); 331c6d81bd7SHeiko Stübner return ret; 332c6d81bd7SHeiko Stübner } 333c6d81bd7SHeiko Stübner 334c6d81bd7SHeiko Stübner return 0; 335c6d81bd7SHeiko Stübner } 336c6d81bd7SHeiko Stübner 337c6d81bd7SHeiko Stübner static int zforce_touch_event(struct zforce_ts *ts, u8 *payload) 338c6d81bd7SHeiko Stübner { 339c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 34087273364SHeiko Stübner const struct zforce_ts_platdata *pdata = ts->pdata; 341c6d81bd7SHeiko Stübner struct zforce_point point; 342c6d81bd7SHeiko Stübner int count, i, num = 0; 343c6d81bd7SHeiko Stübner 344c6d81bd7SHeiko Stübner count = payload[0]; 345c6d81bd7SHeiko Stübner if (count > ZFORCE_REPORT_POINTS) { 346ad697b96SLuis Ortega dev_warn(&client->dev, 347ad697b96SLuis Ortega "too many coordinates %d, expected max %d\n", 348c6d81bd7SHeiko Stübner count, ZFORCE_REPORT_POINTS); 349c6d81bd7SHeiko Stübner count = ZFORCE_REPORT_POINTS; 350c6d81bd7SHeiko Stübner } 351c6d81bd7SHeiko Stübner 352c6d81bd7SHeiko Stübner for (i = 0; i < count; i++) { 353c6d81bd7SHeiko Stübner point.coord_x = 354c6d81bd7SHeiko Stübner payload[9 * i + 2] << 8 | payload[9 * i + 1]; 355c6d81bd7SHeiko Stübner point.coord_y = 356c6d81bd7SHeiko Stübner payload[9 * i + 4] << 8 | payload[9 * i + 3]; 357c6d81bd7SHeiko Stübner 358c6d81bd7SHeiko Stübner if (point.coord_x > pdata->x_max || 359c6d81bd7SHeiko Stübner point.coord_y > pdata->y_max) { 360c6d81bd7SHeiko Stübner dev_warn(&client->dev, "coordinates (%d,%d) invalid\n", 361c6d81bd7SHeiko Stübner point.coord_x, point.coord_y); 362c6d81bd7SHeiko Stübner point.coord_x = point.coord_y = 0; 363c6d81bd7SHeiko Stübner } 364c6d81bd7SHeiko Stübner 3656984ab1aSKnut Wohlrab point.state = payload[9 * i + 5] & 0x0f; 3666984ab1aSKnut Wohlrab point.id = (payload[9 * i + 5] & 0xf0) >> 4; 367c6d81bd7SHeiko Stübner 368c6d81bd7SHeiko Stübner /* determine touch major, minor and orientation */ 369c6d81bd7SHeiko Stübner point.area_major = max(payload[9 * i + 6], 370c6d81bd7SHeiko Stübner payload[9 * i + 7]); 371c6d81bd7SHeiko Stübner point.area_minor = min(payload[9 * i + 6], 372c6d81bd7SHeiko Stübner payload[9 * i + 7]); 373c6d81bd7SHeiko Stübner point.orientation = payload[9 * i + 6] > payload[9 * i + 7]; 374c6d81bd7SHeiko Stübner 375c6d81bd7SHeiko Stübner point.pressure = payload[9 * i + 8]; 376c6d81bd7SHeiko Stübner point.prblty = payload[9 * i + 9]; 377c6d81bd7SHeiko Stübner 378c6d81bd7SHeiko Stübner dev_dbg(&client->dev, 379c6d81bd7SHeiko Stübner "point %d/%d: state %d, id %d, pressure %d, prblty %d, x %d, y %d, amajor %d, aminor %d, ori %d\n", 380c6d81bd7SHeiko Stübner i, count, point.state, point.id, 381c6d81bd7SHeiko Stübner point.pressure, point.prblty, 382c6d81bd7SHeiko Stübner point.coord_x, point.coord_y, 383c6d81bd7SHeiko Stübner point.area_major, point.area_minor, 384c6d81bd7SHeiko Stübner point.orientation); 385c6d81bd7SHeiko Stübner 386c6d81bd7SHeiko Stübner /* the zforce id starts with "1", so needs to be decreased */ 387c6d81bd7SHeiko Stübner input_mt_slot(ts->input, point.id - 1); 388c6d81bd7SHeiko Stübner 389c6d81bd7SHeiko Stübner input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, 390c6d81bd7SHeiko Stübner point.state != STATE_UP); 391c6d81bd7SHeiko Stübner 392c6d81bd7SHeiko Stübner if (point.state != STATE_UP) { 393c6d81bd7SHeiko Stübner input_report_abs(ts->input, ABS_MT_POSITION_X, 394c6d81bd7SHeiko Stübner point.coord_x); 395c6d81bd7SHeiko Stübner input_report_abs(ts->input, ABS_MT_POSITION_Y, 396c6d81bd7SHeiko Stübner point.coord_y); 397c6d81bd7SHeiko Stübner input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 398c6d81bd7SHeiko Stübner point.area_major); 399c6d81bd7SHeiko Stübner input_report_abs(ts->input, ABS_MT_TOUCH_MINOR, 400c6d81bd7SHeiko Stübner point.area_minor); 401c6d81bd7SHeiko Stübner input_report_abs(ts->input, ABS_MT_ORIENTATION, 402c6d81bd7SHeiko Stübner point.orientation); 403c6d81bd7SHeiko Stübner num++; 404c6d81bd7SHeiko Stübner } 405c6d81bd7SHeiko Stübner } 406c6d81bd7SHeiko Stübner 407c6d81bd7SHeiko Stübner input_mt_sync_frame(ts->input); 408c6d81bd7SHeiko Stübner 409c6d81bd7SHeiko Stübner input_mt_report_finger_count(ts->input, num); 410c6d81bd7SHeiko Stübner 411c6d81bd7SHeiko Stübner input_sync(ts->input); 412c6d81bd7SHeiko Stübner 413c6d81bd7SHeiko Stübner return 0; 414c6d81bd7SHeiko Stübner } 415c6d81bd7SHeiko Stübner 416c6d81bd7SHeiko Stübner static int zforce_read_packet(struct zforce_ts *ts, u8 *buf) 417c6d81bd7SHeiko Stübner { 418c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 419c6d81bd7SHeiko Stübner int ret; 420c6d81bd7SHeiko Stübner 421c6d81bd7SHeiko Stübner mutex_lock(&ts->access_mutex); 422c6d81bd7SHeiko Stübner 423c6d81bd7SHeiko Stübner /* read 2 byte message header */ 424c6d81bd7SHeiko Stübner ret = i2c_master_recv(client, buf, 2); 425c6d81bd7SHeiko Stübner if (ret < 0) { 426c6d81bd7SHeiko Stübner dev_err(&client->dev, "error reading header: %d\n", ret); 427c6d81bd7SHeiko Stübner goto unlock; 428c6d81bd7SHeiko Stübner } 429c6d81bd7SHeiko Stübner 430c6d81bd7SHeiko Stübner if (buf[PAYLOAD_HEADER] != FRAME_START) { 431c6d81bd7SHeiko Stübner dev_err(&client->dev, "invalid frame start: %d\n", buf[0]); 432c6d81bd7SHeiko Stübner ret = -EIO; 433c6d81bd7SHeiko Stübner goto unlock; 434c6d81bd7SHeiko Stübner } 435c6d81bd7SHeiko Stübner 4365aee41a6SLuis Ortega if (buf[PAYLOAD_LENGTH] == 0) { 437c6d81bd7SHeiko Stübner dev_err(&client->dev, "invalid payload length: %d\n", 438c6d81bd7SHeiko Stübner buf[PAYLOAD_LENGTH]); 439c6d81bd7SHeiko Stübner ret = -EIO; 440c6d81bd7SHeiko Stübner goto unlock; 441c6d81bd7SHeiko Stübner } 442c6d81bd7SHeiko Stübner 443c6d81bd7SHeiko Stübner /* read the message */ 444c6d81bd7SHeiko Stübner ret = i2c_master_recv(client, &buf[PAYLOAD_BODY], buf[PAYLOAD_LENGTH]); 445c6d81bd7SHeiko Stübner if (ret < 0) { 446c6d81bd7SHeiko Stübner dev_err(&client->dev, "error reading payload: %d\n", ret); 447c6d81bd7SHeiko Stübner goto unlock; 448c6d81bd7SHeiko Stübner } 449c6d81bd7SHeiko Stübner 450c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "read %d bytes for response command 0x%x\n", 451c6d81bd7SHeiko Stübner buf[PAYLOAD_LENGTH], buf[PAYLOAD_BODY]); 452c6d81bd7SHeiko Stübner 453c6d81bd7SHeiko Stübner unlock: 454c6d81bd7SHeiko Stübner mutex_unlock(&ts->access_mutex); 455c6d81bd7SHeiko Stübner return ret; 456c6d81bd7SHeiko Stübner } 457c6d81bd7SHeiko Stübner 458c6d81bd7SHeiko Stübner static void zforce_complete(struct zforce_ts *ts, int cmd, int result) 459c6d81bd7SHeiko Stübner { 460c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 461c6d81bd7SHeiko Stübner 462c6d81bd7SHeiko Stübner if (ts->command_waiting == cmd) { 463c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "completing command 0x%x\n", cmd); 464c6d81bd7SHeiko Stübner ts->command_result = result; 465c6d81bd7SHeiko Stübner complete(&ts->command_done); 466c6d81bd7SHeiko Stübner } else { 467c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "command %d not for us\n", cmd); 468c6d81bd7SHeiko Stübner } 469c6d81bd7SHeiko Stübner } 470c6d81bd7SHeiko Stübner 471499e6127SHeiko Stübner static irqreturn_t zforce_irq(int irq, void *dev_id) 472499e6127SHeiko Stübner { 473499e6127SHeiko Stübner struct zforce_ts *ts = dev_id; 474499e6127SHeiko Stübner struct i2c_client *client = ts->client; 475499e6127SHeiko Stübner 476499e6127SHeiko Stübner if (ts->suspended && device_may_wakeup(&client->dev)) 477499e6127SHeiko Stübner pm_wakeup_event(&client->dev, 500); 478499e6127SHeiko Stübner 479499e6127SHeiko Stübner return IRQ_WAKE_THREAD; 480499e6127SHeiko Stübner } 481499e6127SHeiko Stübner 482499e6127SHeiko Stübner static irqreturn_t zforce_irq_thread(int irq, void *dev_id) 483c6d81bd7SHeiko Stübner { 484c6d81bd7SHeiko Stübner struct zforce_ts *ts = dev_id; 485c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 486c6d81bd7SHeiko Stübner int ret; 487d333b606SLuis Ortega u8 payload_buffer[FRAME_MAXSIZE]; 488c6d81bd7SHeiko Stübner u8 *payload; 489c6d81bd7SHeiko Stübner 490c6d81bd7SHeiko Stübner /* 491499e6127SHeiko Stübner * When still suspended, return. 492c6d81bd7SHeiko Stübner * Due to the level-interrupt we will get re-triggered later. 493c6d81bd7SHeiko Stübner */ 494c6d81bd7SHeiko Stübner if (ts->suspended) { 495c6d81bd7SHeiko Stübner msleep(20); 496c6d81bd7SHeiko Stübner return IRQ_HANDLED; 497c6d81bd7SHeiko Stübner } 498c6d81bd7SHeiko Stübner 499c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "handling interrupt\n"); 500c6d81bd7SHeiko Stübner 501c6d81bd7SHeiko Stübner /* Don't emit wakeup events from commands run by zforce_suspend */ 502c6d81bd7SHeiko Stübner if (!ts->suspending && device_may_wakeup(&client->dev)) 503c6d81bd7SHeiko Stübner pm_stay_awake(&client->dev); 504c6d81bd7SHeiko Stübner 50562f46669SDirk Behme /* 50662f46669SDirk Behme * Run at least once and exit the loop if 50762f46669SDirk Behme * - the optional interrupt GPIO isn't specified 50862f46669SDirk Behme * (there is only one packet read per ISR invocation, then) 50962f46669SDirk Behme * or 51062f46669SDirk Behme * - the GPIO isn't active any more 51162f46669SDirk Behme * (packet read until the level GPIO indicates that there is 51262f46669SDirk Behme * no IRQ any more) 51362f46669SDirk Behme */ 51462f46669SDirk Behme do { 515c6d81bd7SHeiko Stübner ret = zforce_read_packet(ts, payload_buffer); 516c6d81bd7SHeiko Stübner if (ret < 0) { 517ad697b96SLuis Ortega dev_err(&client->dev, 518ad697b96SLuis Ortega "could not read packet, ret: %d\n", ret); 519c6d81bd7SHeiko Stübner break; 520c6d81bd7SHeiko Stübner } 521c6d81bd7SHeiko Stübner 522c6d81bd7SHeiko Stübner payload = &payload_buffer[PAYLOAD_BODY]; 523c6d81bd7SHeiko Stübner 524c6d81bd7SHeiko Stübner switch (payload[RESPONSE_ID]) { 525c6d81bd7SHeiko Stübner case NOTIFICATION_TOUCH: 526c6d81bd7SHeiko Stübner /* 527c6d81bd7SHeiko Stübner * Always report touch-events received while 528c6d81bd7SHeiko Stübner * suspending, when being a wakeup source 529c6d81bd7SHeiko Stübner */ 530c6d81bd7SHeiko Stübner if (ts->suspending && device_may_wakeup(&client->dev)) 531c6d81bd7SHeiko Stübner pm_wakeup_event(&client->dev, 500); 532c6d81bd7SHeiko Stübner zforce_touch_event(ts, &payload[RESPONSE_DATA]); 533c6d81bd7SHeiko Stübner break; 534c6d81bd7SHeiko Stübner 535c6d81bd7SHeiko Stübner case NOTIFICATION_BOOTCOMPLETE: 536c6d81bd7SHeiko Stübner ts->boot_complete = payload[RESPONSE_DATA]; 537c6d81bd7SHeiko Stübner zforce_complete(ts, payload[RESPONSE_ID], 0); 538c6d81bd7SHeiko Stübner break; 539c6d81bd7SHeiko Stübner 540c6d81bd7SHeiko Stübner case RESPONSE_INITIALIZE: 541c6d81bd7SHeiko Stübner case RESPONSE_DEACTIVATE: 542c6d81bd7SHeiko Stübner case RESPONSE_SETCONFIG: 543c6d81bd7SHeiko Stübner case RESPONSE_RESOLUTION: 544c6d81bd7SHeiko Stübner case RESPONSE_SCANFREQ: 545c6d81bd7SHeiko Stübner zforce_complete(ts, payload[RESPONSE_ID], 546c6d81bd7SHeiko Stübner payload[RESPONSE_DATA]); 547c6d81bd7SHeiko Stübner break; 548c6d81bd7SHeiko Stübner 549c6d81bd7SHeiko Stübner case RESPONSE_STATUS: 550c6d81bd7SHeiko Stübner /* 551c6d81bd7SHeiko Stübner * Version Payload Results 552c6d81bd7SHeiko Stübner * [2:major] [2:minor] [2:build] [2:rev] 553c6d81bd7SHeiko Stübner */ 554c6d81bd7SHeiko Stübner ts->version_major = (payload[RESPONSE_DATA + 1] << 8) | 555c6d81bd7SHeiko Stübner payload[RESPONSE_DATA]; 556c6d81bd7SHeiko Stübner ts->version_minor = (payload[RESPONSE_DATA + 3] << 8) | 557c6d81bd7SHeiko Stübner payload[RESPONSE_DATA + 2]; 558c6d81bd7SHeiko Stübner ts->version_build = (payload[RESPONSE_DATA + 5] << 8) | 559c6d81bd7SHeiko Stübner payload[RESPONSE_DATA + 4]; 560c6d81bd7SHeiko Stübner ts->version_rev = (payload[RESPONSE_DATA + 7] << 8) | 561c6d81bd7SHeiko Stübner payload[RESPONSE_DATA + 6]; 562ad697b96SLuis Ortega dev_dbg(&ts->client->dev, 563ad697b96SLuis Ortega "Firmware Version %04x:%04x %04x:%04x\n", 564c6d81bd7SHeiko Stübner ts->version_major, ts->version_minor, 565c6d81bd7SHeiko Stübner ts->version_build, ts->version_rev); 566c6d81bd7SHeiko Stübner 567c6d81bd7SHeiko Stübner zforce_complete(ts, payload[RESPONSE_ID], 0); 568c6d81bd7SHeiko Stübner break; 569c6d81bd7SHeiko Stübner 570c6d81bd7SHeiko Stübner case NOTIFICATION_INVALID_COMMAND: 571c6d81bd7SHeiko Stübner dev_err(&ts->client->dev, "invalid command: 0x%x\n", 572c6d81bd7SHeiko Stübner payload[RESPONSE_DATA]); 573c6d81bd7SHeiko Stübner break; 574c6d81bd7SHeiko Stübner 575c6d81bd7SHeiko Stübner default: 576ad697b96SLuis Ortega dev_err(&ts->client->dev, 577ad697b96SLuis Ortega "unrecognized response id: 0x%x\n", 578c6d81bd7SHeiko Stübner payload[RESPONSE_ID]); 579c6d81bd7SHeiko Stübner break; 580c6d81bd7SHeiko Stübner } 58162f46669SDirk Behme } while (gpiod_get_value_cansleep(ts->gpio_int)); 582c6d81bd7SHeiko Stübner 583c6d81bd7SHeiko Stübner if (!ts->suspending && device_may_wakeup(&client->dev)) 584c6d81bd7SHeiko Stübner pm_relax(&client->dev); 585c6d81bd7SHeiko Stübner 586c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "finished interrupt\n"); 587c6d81bd7SHeiko Stübner 588c6d81bd7SHeiko Stübner return IRQ_HANDLED; 589c6d81bd7SHeiko Stübner } 590c6d81bd7SHeiko Stübner 591c6d81bd7SHeiko Stübner static int zforce_input_open(struct input_dev *dev) 592c6d81bd7SHeiko Stübner { 593c6d81bd7SHeiko Stübner struct zforce_ts *ts = input_get_drvdata(dev); 594c6d81bd7SHeiko Stübner 595a47fcbc2SJavier Martinez Canillas return zforce_start(ts); 596c6d81bd7SHeiko Stübner } 597c6d81bd7SHeiko Stübner 598c6d81bd7SHeiko Stübner static void zforce_input_close(struct input_dev *dev) 599c6d81bd7SHeiko Stübner { 600c6d81bd7SHeiko Stübner struct zforce_ts *ts = input_get_drvdata(dev); 601c6d81bd7SHeiko Stübner struct i2c_client *client = ts->client; 602c6d81bd7SHeiko Stübner int ret; 603c6d81bd7SHeiko Stübner 604c6d81bd7SHeiko Stübner ret = zforce_stop(ts); 605c6d81bd7SHeiko Stübner if (ret) 606c6d81bd7SHeiko Stübner dev_warn(&client->dev, "stopping zforce failed\n"); 607c6d81bd7SHeiko Stübner 608c6d81bd7SHeiko Stübner return; 609c6d81bd7SHeiko Stübner } 610c6d81bd7SHeiko Stübner 611*dc69e98aSJonathan Cameron static int zforce_suspend(struct device *dev) 612c6d81bd7SHeiko Stübner { 613c6d81bd7SHeiko Stübner struct i2c_client *client = to_i2c_client(dev); 614c6d81bd7SHeiko Stübner struct zforce_ts *ts = i2c_get_clientdata(client); 615c6d81bd7SHeiko Stübner struct input_dev *input = ts->input; 616c6d81bd7SHeiko Stübner int ret = 0; 617c6d81bd7SHeiko Stübner 618c6d81bd7SHeiko Stübner mutex_lock(&input->mutex); 619c6d81bd7SHeiko Stübner ts->suspending = true; 620c6d81bd7SHeiko Stübner 621c6d81bd7SHeiko Stübner /* 622c6d81bd7SHeiko Stübner * When configured as a wakeup source device should always wake 623c6d81bd7SHeiko Stübner * the system, therefore start device if necessary. 624c6d81bd7SHeiko Stübner */ 625c6d81bd7SHeiko Stübner if (device_may_wakeup(&client->dev)) { 626c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "suspend while being a wakeup source\n"); 627c6d81bd7SHeiko Stübner 628c6d81bd7SHeiko Stübner /* Need to start device, if not open, to be a wakeup source. */ 629d69f0a43SAndrzej Pietrasiewicz if (!input_device_enabled(input)) { 630c6d81bd7SHeiko Stübner ret = zforce_start(ts); 631c6d81bd7SHeiko Stübner if (ret) 632c6d81bd7SHeiko Stübner goto unlock; 633c6d81bd7SHeiko Stübner } 634c6d81bd7SHeiko Stübner 635c6d81bd7SHeiko Stübner enable_irq_wake(client->irq); 636d69f0a43SAndrzej Pietrasiewicz } else if (input_device_enabled(input)) { 637ad697b96SLuis Ortega dev_dbg(&client->dev, 638ad697b96SLuis Ortega "suspend without being a wakeup source\n"); 639c6d81bd7SHeiko Stübner 640c6d81bd7SHeiko Stübner ret = zforce_stop(ts); 641c6d81bd7SHeiko Stübner if (ret) 642c6d81bd7SHeiko Stübner goto unlock; 643c6d81bd7SHeiko Stübner 644c6d81bd7SHeiko Stübner disable_irq(client->irq); 645c6d81bd7SHeiko Stübner } 646c6d81bd7SHeiko Stübner 647c6d81bd7SHeiko Stübner ts->suspended = true; 648c6d81bd7SHeiko Stübner 649c6d81bd7SHeiko Stübner unlock: 650c6d81bd7SHeiko Stübner ts->suspending = false; 651c6d81bd7SHeiko Stübner mutex_unlock(&input->mutex); 652c6d81bd7SHeiko Stübner 653c6d81bd7SHeiko Stübner return ret; 654c6d81bd7SHeiko Stübner } 655c6d81bd7SHeiko Stübner 656*dc69e98aSJonathan Cameron static int zforce_resume(struct device *dev) 657c6d81bd7SHeiko Stübner { 658c6d81bd7SHeiko Stübner struct i2c_client *client = to_i2c_client(dev); 659c6d81bd7SHeiko Stübner struct zforce_ts *ts = i2c_get_clientdata(client); 660c6d81bd7SHeiko Stübner struct input_dev *input = ts->input; 661c6d81bd7SHeiko Stübner int ret = 0; 662c6d81bd7SHeiko Stübner 663c6d81bd7SHeiko Stübner mutex_lock(&input->mutex); 664c6d81bd7SHeiko Stübner 665c6d81bd7SHeiko Stübner ts->suspended = false; 666c6d81bd7SHeiko Stübner 667c6d81bd7SHeiko Stübner if (device_may_wakeup(&client->dev)) { 668c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "resume from being a wakeup source\n"); 669c6d81bd7SHeiko Stübner 670c6d81bd7SHeiko Stübner disable_irq_wake(client->irq); 671c6d81bd7SHeiko Stübner 672c6d81bd7SHeiko Stübner /* need to stop device if it was not open on suspend */ 673d69f0a43SAndrzej Pietrasiewicz if (!input_device_enabled(input)) { 674c6d81bd7SHeiko Stübner ret = zforce_stop(ts); 675c6d81bd7SHeiko Stübner if (ret) 676c6d81bd7SHeiko Stübner goto unlock; 677c6d81bd7SHeiko Stübner } 678d69f0a43SAndrzej Pietrasiewicz } else if (input_device_enabled(input)) { 679c6d81bd7SHeiko Stübner dev_dbg(&client->dev, "resume without being a wakeup source\n"); 680c6d81bd7SHeiko Stübner 681c6d81bd7SHeiko Stübner enable_irq(client->irq); 682c6d81bd7SHeiko Stübner 683c6d81bd7SHeiko Stübner ret = zforce_start(ts); 684c6d81bd7SHeiko Stübner if (ret < 0) 685c6d81bd7SHeiko Stübner goto unlock; 686c6d81bd7SHeiko Stübner } 687c6d81bd7SHeiko Stübner 688c6d81bd7SHeiko Stübner unlock: 689c6d81bd7SHeiko Stübner mutex_unlock(&input->mutex); 690c6d81bd7SHeiko Stübner 691c6d81bd7SHeiko Stübner return ret; 692c6d81bd7SHeiko Stübner } 693c6d81bd7SHeiko Stübner 694*dc69e98aSJonathan Cameron static DEFINE_SIMPLE_DEV_PM_OPS(zforce_pm_ops, zforce_suspend, zforce_resume); 695c6d81bd7SHeiko Stübner 696c6d81bd7SHeiko Stübner static void zforce_reset(void *data) 697c6d81bd7SHeiko Stübner { 698c6d81bd7SHeiko Stübner struct zforce_ts *ts = data; 699c6d81bd7SHeiko Stübner 7002d538095SDirk Behme zforce_reset_assert(ts); 70139740370SHeiko Stuebner 70239740370SHeiko Stuebner udelay(10); 70339740370SHeiko Stuebner 70439740370SHeiko Stuebner if (!IS_ERR(ts->reg_vdd)) 70539740370SHeiko Stuebner regulator_disable(ts->reg_vdd); 706c6d81bd7SHeiko Stübner } 707c6d81bd7SHeiko Stübner 7086f2e6c9bSHeiko Stübner static struct zforce_ts_platdata *zforce_parse_dt(struct device *dev) 7096f2e6c9bSHeiko Stübner { 7106f2e6c9bSHeiko Stübner struct zforce_ts_platdata *pdata; 7116f2e6c9bSHeiko Stübner struct device_node *np = dev->of_node; 7126f2e6c9bSHeiko Stübner 7136f2e6c9bSHeiko Stübner if (!np) 7146f2e6c9bSHeiko Stübner return ERR_PTR(-ENOENT); 7156f2e6c9bSHeiko Stübner 7166f2e6c9bSHeiko Stübner pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 7176f2e6c9bSHeiko Stübner if (!pdata) { 7186f2e6c9bSHeiko Stübner dev_err(dev, "failed to allocate platform data\n"); 7196f2e6c9bSHeiko Stübner return ERR_PTR(-ENOMEM); 7206f2e6c9bSHeiko Stübner } 7216f2e6c9bSHeiko Stübner 7226f2e6c9bSHeiko Stübner if (of_property_read_u32(np, "x-size", &pdata->x_max)) { 7236f2e6c9bSHeiko Stübner dev_err(dev, "failed to get x-size property\n"); 7246f2e6c9bSHeiko Stübner return ERR_PTR(-EINVAL); 7256f2e6c9bSHeiko Stübner } 7266f2e6c9bSHeiko Stübner 7276f2e6c9bSHeiko Stübner if (of_property_read_u32(np, "y-size", &pdata->y_max)) { 7286f2e6c9bSHeiko Stübner dev_err(dev, "failed to get y-size property\n"); 7296f2e6c9bSHeiko Stübner return ERR_PTR(-EINVAL); 7306f2e6c9bSHeiko Stübner } 7316f2e6c9bSHeiko Stübner 7326f2e6c9bSHeiko Stübner return pdata; 7336f2e6c9bSHeiko Stübner } 7346f2e6c9bSHeiko Stübner 73556232e93SUwe Kleine-König static int zforce_probe(struct i2c_client *client) 736c6d81bd7SHeiko Stübner { 737c6d81bd7SHeiko Stübner const struct zforce_ts_platdata *pdata = dev_get_platdata(&client->dev); 738c6d81bd7SHeiko Stübner struct zforce_ts *ts; 739c6d81bd7SHeiko Stübner struct input_dev *input_dev; 740c6d81bd7SHeiko Stübner int ret; 741c6d81bd7SHeiko Stübner 7426f2e6c9bSHeiko Stübner if (!pdata) { 7436f2e6c9bSHeiko Stübner pdata = zforce_parse_dt(&client->dev); 7446f2e6c9bSHeiko Stübner if (IS_ERR(pdata)) 7456f2e6c9bSHeiko Stübner return PTR_ERR(pdata); 7466f2e6c9bSHeiko Stübner } 747c6d81bd7SHeiko Stübner 748c6d81bd7SHeiko Stübner ts = devm_kzalloc(&client->dev, sizeof(struct zforce_ts), GFP_KERNEL); 749c6d81bd7SHeiko Stübner if (!ts) 750c6d81bd7SHeiko Stübner return -ENOMEM; 751c6d81bd7SHeiko Stübner 75262f46669SDirk Behme ts->gpio_rst = devm_gpiod_get_optional(&client->dev, "reset", 75362f46669SDirk Behme GPIOD_OUT_HIGH); 75462f46669SDirk Behme if (IS_ERR(ts->gpio_rst)) { 75562f46669SDirk Behme ret = PTR_ERR(ts->gpio_rst); 75662f46669SDirk Behme dev_err(&client->dev, 75762f46669SDirk Behme "failed to request reset GPIO: %d\n", ret); 75862f46669SDirk Behme return ret; 75962f46669SDirk Behme } 76062f46669SDirk Behme 76162f46669SDirk Behme if (ts->gpio_rst) { 76262f46669SDirk Behme ts->gpio_int = devm_gpiod_get_optional(&client->dev, "irq", 76362f46669SDirk Behme GPIOD_IN); 76462f46669SDirk Behme if (IS_ERR(ts->gpio_int)) { 76562f46669SDirk Behme ret = PTR_ERR(ts->gpio_int); 76662f46669SDirk Behme dev_err(&client->dev, 76762f46669SDirk Behme "failed to request interrupt GPIO: %d\n", ret); 76862f46669SDirk Behme return ret; 76962f46669SDirk Behme } 77062f46669SDirk Behme } else { 77162f46669SDirk Behme /* 77262f46669SDirk Behme * Deprecated GPIO handling for compatibility 77362f46669SDirk Behme * with legacy binding. 77462f46669SDirk Behme */ 77562f46669SDirk Behme 7762d538095SDirk Behme /* INT GPIO */ 77762f46669SDirk Behme ts->gpio_int = devm_gpiod_get_index(&client->dev, NULL, 0, 77862f46669SDirk Behme GPIOD_IN); 7792d538095SDirk Behme if (IS_ERR(ts->gpio_int)) { 7802d538095SDirk Behme ret = PTR_ERR(ts->gpio_int); 7812d538095SDirk Behme dev_err(&client->dev, 7822d538095SDirk Behme "failed to request interrupt GPIO: %d\n", ret); 783c6d81bd7SHeiko Stübner return ret; 784c6d81bd7SHeiko Stübner } 785c6d81bd7SHeiko Stübner 7862d538095SDirk Behme /* RST GPIO */ 7872d538095SDirk Behme ts->gpio_rst = devm_gpiod_get_index(&client->dev, NULL, 1, 7882d538095SDirk Behme GPIOD_OUT_HIGH); 7892d538095SDirk Behme if (IS_ERR(ts->gpio_rst)) { 7902d538095SDirk Behme ret = PTR_ERR(ts->gpio_rst); 7912d538095SDirk Behme dev_err(&client->dev, 7922d538095SDirk Behme "failed to request reset GPIO: %d\n", ret); 793c6d81bd7SHeiko Stübner return ret; 794c6d81bd7SHeiko Stübner } 79562f46669SDirk Behme } 796c6d81bd7SHeiko Stübner 79739740370SHeiko Stuebner ts->reg_vdd = devm_regulator_get_optional(&client->dev, "vdd"); 79839740370SHeiko Stuebner if (IS_ERR(ts->reg_vdd)) { 79939740370SHeiko Stuebner ret = PTR_ERR(ts->reg_vdd); 80039740370SHeiko Stuebner if (ret == -EPROBE_DEFER) 80139740370SHeiko Stuebner return ret; 80239740370SHeiko Stuebner } else { 80339740370SHeiko Stuebner ret = regulator_enable(ts->reg_vdd); 80439740370SHeiko Stuebner if (ret) 80539740370SHeiko Stuebner return ret; 80639740370SHeiko Stuebner 80739740370SHeiko Stuebner /* 80839740370SHeiko Stuebner * according to datasheet add 100us grace time after regular 80939740370SHeiko Stuebner * regulator enable delay. 81039740370SHeiko Stuebner */ 81139740370SHeiko Stuebner udelay(100); 81239740370SHeiko Stuebner } 81339740370SHeiko Stuebner 814c6d81bd7SHeiko Stübner ret = devm_add_action(&client->dev, zforce_reset, ts); 815c6d81bd7SHeiko Stübner if (ret) { 816c6d81bd7SHeiko Stübner dev_err(&client->dev, "failed to register reset action, %d\n", 817c6d81bd7SHeiko Stübner ret); 81839740370SHeiko Stuebner 81939740370SHeiko Stuebner /* hereafter the regulator will be disabled by the action */ 82039740370SHeiko Stuebner if (!IS_ERR(ts->reg_vdd)) 82139740370SHeiko Stuebner regulator_disable(ts->reg_vdd); 82239740370SHeiko Stuebner 823c6d81bd7SHeiko Stübner return ret; 824c6d81bd7SHeiko Stübner } 825c6d81bd7SHeiko Stübner 826c6d81bd7SHeiko Stübner snprintf(ts->phys, sizeof(ts->phys), 827c6d81bd7SHeiko Stübner "%s/input0", dev_name(&client->dev)); 828c6d81bd7SHeiko Stübner 829c6d81bd7SHeiko Stübner input_dev = devm_input_allocate_device(&client->dev); 830c6d81bd7SHeiko Stübner if (!input_dev) { 831c6d81bd7SHeiko Stübner dev_err(&client->dev, "could not allocate input device\n"); 832c6d81bd7SHeiko Stübner return -ENOMEM; 833c6d81bd7SHeiko Stübner } 834c6d81bd7SHeiko Stübner 835c6d81bd7SHeiko Stübner mutex_init(&ts->access_mutex); 836c6d81bd7SHeiko Stübner mutex_init(&ts->command_mutex); 837c6d81bd7SHeiko Stübner 838c6d81bd7SHeiko Stübner ts->pdata = pdata; 839c6d81bd7SHeiko Stübner ts->client = client; 840c6d81bd7SHeiko Stübner ts->input = input_dev; 841c6d81bd7SHeiko Stübner 842c6d81bd7SHeiko Stübner input_dev->name = "Neonode zForce touchscreen"; 843c6d81bd7SHeiko Stübner input_dev->phys = ts->phys; 844c6d81bd7SHeiko Stübner input_dev->id.bustype = BUS_I2C; 845c6d81bd7SHeiko Stübner 846c6d81bd7SHeiko Stübner input_dev->open = zforce_input_open; 847c6d81bd7SHeiko Stübner input_dev->close = zforce_input_close; 848c6d81bd7SHeiko Stübner 849c6d81bd7SHeiko Stübner __set_bit(EV_KEY, input_dev->evbit); 850c6d81bd7SHeiko Stübner __set_bit(EV_SYN, input_dev->evbit); 851c6d81bd7SHeiko Stübner __set_bit(EV_ABS, input_dev->evbit); 852c6d81bd7SHeiko Stübner 853c6d81bd7SHeiko Stübner /* For multi touch */ 854c6d81bd7SHeiko Stübner input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 855c6d81bd7SHeiko Stübner pdata->x_max, 0, 0); 856c6d81bd7SHeiko Stübner input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 857c6d81bd7SHeiko Stübner pdata->y_max, 0, 0); 858c6d81bd7SHeiko Stübner 859c6d81bd7SHeiko Stübner input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 860c6d81bd7SHeiko Stübner ZFORCE_MAX_AREA, 0, 0); 861c6d81bd7SHeiko Stübner input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, 862c6d81bd7SHeiko Stübner ZFORCE_MAX_AREA, 0, 0); 863c6d81bd7SHeiko Stübner input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); 864c6d81bd7SHeiko Stübner input_mt_init_slots(input_dev, ZFORCE_REPORT_POINTS, INPUT_MT_DIRECT); 865c6d81bd7SHeiko Stübner 866c6d81bd7SHeiko Stübner input_set_drvdata(ts->input, ts); 867c6d81bd7SHeiko Stübner 868c6d81bd7SHeiko Stübner init_completion(&ts->command_done); 869c6d81bd7SHeiko Stübner 870c6d81bd7SHeiko Stübner /* 871c6d81bd7SHeiko Stübner * The zforce pulls the interrupt low when it has data ready. 872c6d81bd7SHeiko Stübner * After it is triggered the isr thread runs until all the available 873c6d81bd7SHeiko Stübner * packets have been read and the interrupt is high again. 874c6d81bd7SHeiko Stübner * Therefore we can trigger the interrupt anytime it is low and do 875c6d81bd7SHeiko Stübner * not need to limit it to the interrupt edge. 876c6d81bd7SHeiko Stübner */ 877499e6127SHeiko Stübner ret = devm_request_threaded_irq(&client->dev, client->irq, 878499e6127SHeiko Stübner zforce_irq, zforce_irq_thread, 879c6d81bd7SHeiko Stübner IRQF_TRIGGER_LOW | IRQF_ONESHOT, 880c6d81bd7SHeiko Stübner input_dev->name, ts); 881c6d81bd7SHeiko Stübner if (ret) { 882c6d81bd7SHeiko Stübner dev_err(&client->dev, "irq %d request failed\n", client->irq); 883c6d81bd7SHeiko Stübner return ret; 884c6d81bd7SHeiko Stübner } 885c6d81bd7SHeiko Stübner 886c6d81bd7SHeiko Stübner i2c_set_clientdata(client, ts); 887c6d81bd7SHeiko Stübner 888c6d81bd7SHeiko Stübner /* let the controller boot */ 8892d538095SDirk Behme zforce_reset_deassert(ts); 890c6d81bd7SHeiko Stübner 891c6d81bd7SHeiko Stübner ts->command_waiting = NOTIFICATION_BOOTCOMPLETE; 892c6d81bd7SHeiko Stübner if (wait_for_completion_timeout(&ts->command_done, WAIT_TIMEOUT) == 0) 893c6d81bd7SHeiko Stübner dev_warn(&client->dev, "bootcomplete timed out\n"); 894c6d81bd7SHeiko Stübner 895c6d81bd7SHeiko Stübner /* need to start device to get version information */ 896c6d81bd7SHeiko Stübner ret = zforce_command_wait(ts, COMMAND_INITIALIZE); 897c6d81bd7SHeiko Stübner if (ret) { 898c6d81bd7SHeiko Stübner dev_err(&client->dev, "unable to initialize, %d\n", ret); 899c6d81bd7SHeiko Stübner return ret; 900c6d81bd7SHeiko Stübner } 901c6d81bd7SHeiko Stübner 902deb49819SLuis Ortega /* this gets the firmware version among other information */ 903c6d81bd7SHeiko Stübner ret = zforce_command_wait(ts, COMMAND_STATUS); 904c6d81bd7SHeiko Stübner if (ret < 0) { 905c6d81bd7SHeiko Stübner dev_err(&client->dev, "couldn't get status, %d\n", ret); 906c6d81bd7SHeiko Stübner zforce_stop(ts); 907c6d81bd7SHeiko Stübner return ret; 908c6d81bd7SHeiko Stübner } 909c6d81bd7SHeiko Stübner 910c6d81bd7SHeiko Stübner /* stop device and put it into sleep until it is opened */ 911c6d81bd7SHeiko Stübner ret = zforce_stop(ts); 912c6d81bd7SHeiko Stübner if (ret < 0) 913c6d81bd7SHeiko Stübner return ret; 914c6d81bd7SHeiko Stübner 915c6d81bd7SHeiko Stübner device_set_wakeup_capable(&client->dev, true); 916c6d81bd7SHeiko Stübner 917c6d81bd7SHeiko Stübner ret = input_register_device(input_dev); 918c6d81bd7SHeiko Stübner if (ret) { 919c6d81bd7SHeiko Stübner dev_err(&client->dev, "could not register input device, %d\n", 920c6d81bd7SHeiko Stübner ret); 921c6d81bd7SHeiko Stübner return ret; 922c6d81bd7SHeiko Stübner } 923c6d81bd7SHeiko Stübner 924c6d81bd7SHeiko Stübner return 0; 925c6d81bd7SHeiko Stübner } 926c6d81bd7SHeiko Stübner 927c6d81bd7SHeiko Stübner static struct i2c_device_id zforce_idtable[] = { 928c6d81bd7SHeiko Stübner { "zforce-ts", 0 }, 929c6d81bd7SHeiko Stübner { } 930c6d81bd7SHeiko Stübner }; 931c6d81bd7SHeiko Stübner MODULE_DEVICE_TABLE(i2c, zforce_idtable); 932c6d81bd7SHeiko Stübner 9336f2e6c9bSHeiko Stübner #ifdef CONFIG_OF 934f3f63193SJingoo Han static const struct of_device_id zforce_dt_idtable[] = { 9356f2e6c9bSHeiko Stübner { .compatible = "neonode,zforce" }, 9366f2e6c9bSHeiko Stübner {}, 9376f2e6c9bSHeiko Stübner }; 9386f2e6c9bSHeiko Stübner MODULE_DEVICE_TABLE(of, zforce_dt_idtable); 9396f2e6c9bSHeiko Stübner #endif 9406f2e6c9bSHeiko Stübner 941c6d81bd7SHeiko Stübner static struct i2c_driver zforce_driver = { 942c6d81bd7SHeiko Stübner .driver = { 943c6d81bd7SHeiko Stübner .name = "zforce-ts", 944*dc69e98aSJonathan Cameron .pm = pm_sleep_ptr(&zforce_pm_ops), 9456f2e6c9bSHeiko Stübner .of_match_table = of_match_ptr(zforce_dt_idtable), 946c6d81bd7SHeiko Stübner }, 94756232e93SUwe Kleine-König .probe_new = zforce_probe, 948c6d81bd7SHeiko Stübner .id_table = zforce_idtable, 949c6d81bd7SHeiko Stübner }; 950c6d81bd7SHeiko Stübner 951c6d81bd7SHeiko Stübner module_i2c_driver(zforce_driver); 952c6d81bd7SHeiko Stübner 953c6d81bd7SHeiko Stübner MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 954c6d81bd7SHeiko Stübner MODULE_DESCRIPTION("zForce TouchScreen Driver"); 955c6d81bd7SHeiko Stübner MODULE_LICENSE("GPL"); 956