/* drivers/input/touchscreen/it7258_ts_i2c.c * * Copyright (C) 2014 ITE Tech. Inc. * Copyright (c) 2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_BUFFER_SIZE 144 #define DEVICE_NAME "IT7260" #define SCREEN_X_RESOLUTION 320 #define SCREEN_Y_RESOLUTION 320 #define DEBUGFS_DIR_NAME "ts_debug" #define FW_NAME "it7260_fw.bin" #define CFG_NAME "it7260_cfg.bin" #define VER_BUFFER_SIZE 4 #define IT_FW_CHECK(x, y) \ (((x)[0] < (y)->data[8]) || ((x)[1] < (y)->data[9]) || \ ((x)[2] < (y)->data[10]) || ((x)[3] < (y)->data[11])) #define IT_CFG_CHECK(x, y) \ (((x)[0] < (y)->data[(y)->size - 8]) || \ ((x)[1] < (y)->data[(y)->size - 7]) || \ ((x)[2] < (y)->data[(y)->size - 6]) || \ ((x)[3] < (y)->data[(y)->size - 5])) #define IT7260_COORDS_ARR_SIZE 4 /* all commands writes go to this idx */ #define BUF_COMMAND 0x20 #define BUF_SYS_COMMAND 0x40 /* * "device ready?" and "wake up please" and "read touch data" reads * go to this idx */ #define BUF_QUERY 0x80 /* most command response reads go to this idx */ #define BUF_RESPONSE 0xA0 #define BUF_SYS_RESPONSE 0xC0 /* reads of "point" go through here and produce 14 bytes of data */ #define BUF_POINT_INFO 0xE0 /* * commands and their subcommands. when no subcommands exist, a zero * is send as the second byte */ #define CMD_IDENT_CHIP 0x00 /* VERSION_LENGTH bytes of data in response */ #define CMD_READ_VERSIONS 0x01 #define SUB_CMD_READ_FIRMWARE_VERSION 0x00 #define SUB_CMD_READ_CONFIG_VERSION 0x06 #define VERSION_LENGTH 10 /* subcommand is zero, next byte is power mode */ #define CMD_PWR_CTL 0x04 /* active mode */ #define PWR_CTL_ACTIVE_MODE 0x00 /* idle mode */ #define PWR_CTL_LOW_POWER_MODE 0x01 /* sleep mode */ #define PWR_CTL_SLEEP_MODE 0x02 #define WAIT_CHANGE_MODE 20 /* command is not documented in the datasheet v1.0.0.7 */ #define CMD_UNKNOWN_7 0x07 #define CMD_FIRMWARE_REINIT_C 0x0C /* needs to be followed by 4 bytes of zeroes */ #define CMD_CALIBRATE 0x13 #define CMD_FIRMWARE_UPGRADE 0x60 #define SUB_CMD_ENTER_FW_UPGRADE_MODE 0x00 #define SUB_CMD_EXIT_FW_UPGRADE_MODE 0x80 /* address for FW read/write */ #define CMD_SET_START_OFFSET 0x61 /* subcommand is number of bytes to write */ #define CMD_FW_WRITE 0x62 /* subcommand is number of bytes to read */ #define CMD_FW_READ 0x63 #define CMD_FIRMWARE_REINIT_6F 0x6F #define FW_WRITE_CHUNK_SIZE 128 #define FW_WRITE_RETRY_COUNT 4 #define CHIP_FLASH_SIZE 0x8000 #define DEVICE_READY_MAX_WAIT 10 /* result of reading with BUF_QUERY bits */ #define CMD_STATUS_BITS 0x07 #define CMD_STATUS_DONE 0x00 #define CMD_STATUS_BUSY 0x01 #define CMD_STATUS_ERROR 0x02 #define PT_INFO_BITS 0xF8 #define BT_INFO_NONE 0x00 #define PT_INFO_YES 0x80 /* no new data but finder(s) still down */ #define BT_INFO_NONE_BUT_DOWN 0x08 #define PD_FLAGS_DATA_TYPE_BITS 0xF0 /* other types (like chip-detected gestures) exist but we do not care */ #define PD_FLAGS_DATA_TYPE_TOUCH 0x00 /* a bit for each finger data that is valid (from lsb to msb) */ #define PD_FLAGS_HAVE_FINGERS 0x07 #define PD_PALM_FLAG_BIT 0x01 #define FD_PRESSURE_BITS 0x0F #define FD_PRESSURE_NONE 0x00 #define FD_PRESSURE_LIGHT 0x02 #define IT_VTG_MIN_UV 1800000 #define IT_VTG_MAX_UV 1800000 #define IT_ACTIVE_LOAD_UA 15000 #define IT_I2C_VTG_MIN_UV 2600000 #define IT_I2C_VTG_MAX_UV 3300000 #define IT_I2C_ACTIVE_LOAD_UA 10000 #define PINCTRL_STATE_ACTIVE "pmx_ts_active" #define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" #define PINCTRL_STATE_RELEASE "pmx_ts_release" #define IT_I2C_WAIT 1000 struct FingerData { uint8_t xLo; uint8_t hi; uint8_t yLo; uint8_t pressure; } __packed; struct PointData { uint8_t flags; uint8_t palm; struct FingerData fd[3]; } __packed; struct IT7260_ts_platform_data { u32 irq_gpio; u32 irq_gpio_flags; u32 reset_gpio; u32 reset_gpio_flags; bool wakeup; bool palm_detect_en; u16 palm_detect_keycode; const char *fw_name; const char *cfg_name; unsigned int panel_minx; unsigned int panel_miny; unsigned int panel_maxx; unsigned int panel_maxy; unsigned int disp_minx; unsigned int disp_miny; unsigned int disp_maxx; unsigned int disp_maxy; unsigned num_of_fingers; unsigned int reset_delay; bool low_reset; }; struct IT7260_ts_data { struct i2c_client *client; struct input_dev *input_dev; const struct IT7260_ts_platform_data *pdata; struct regulator *vdd; struct regulator *avdd; bool device_needs_wakeup; bool suspended; bool fw_upgrade_result; bool cfg_upgrade_result; bool fw_cfg_uploading; struct work_struct work_pm_relax; bool calibration_success; bool had_finger_down; char fw_name[MAX_BUFFER_SIZE]; char cfg_name[MAX_BUFFER_SIZE]; struct mutex fw_cfg_mutex; u8 fw_ver[VER_BUFFER_SIZE]; u8 cfg_ver[VER_BUFFER_SIZE]; #ifdef CONFIG_FB struct notifier_block fb_notif; #endif struct dentry *dir; struct pinctrl *ts_pinctrl; struct pinctrl_state *pinctrl_state_active; struct pinctrl_state *pinctrl_state_suspend; struct pinctrl_state *pinctrl_state_release; }; /* Function declarations */ static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); static int IT7260_ts_resume(struct device *dev); static int IT7260_ts_suspend(struct device *dev); static struct IT7260_ts_data *gl_ts; static int IT7260_debug_suspend_set(void *_data, u64 val) { if (val) IT7260_ts_suspend(&gl_ts->client->dev); else IT7260_ts_resume(&gl_ts->client->dev); return 0; } static int IT7260_debug_suspend_get(void *_data, u64 *val) { *val = gl_ts->suspended; return 0; } DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, IT7260_debug_suspend_get, IT7260_debug_suspend_set, "%lld\n"); /* internal use func - does not make sure chip is ready before read */ static bool IT7260_i2cReadNoReadyCheck(uint8_t buf_index, uint8_t *buffer, uint16_t buf_len) { struct i2c_msg msgs[2] = { { .addr = gl_ts->client->addr, .flags = I2C_M_NOSTART, .len = 1, .buf = &buf_index }, { .addr = gl_ts->client->addr, .flags = I2C_M_RD, .len = buf_len, .buf = buffer } }; memset(buffer, 0xFF, buf_len); return i2c_transfer(gl_ts->client->adapter, msgs, 2); } static bool IT7260_i2cWriteNoReadyCheck(uint8_t buf_index, const uint8_t *buffer, uint16_t buf_len) { uint8_t txbuf[257]; struct i2c_msg msg = { .addr = gl_ts->client->addr, .flags = 0, .len = buf_len + 1, .buf = txbuf }; /* just to be careful */ if (buf_len > sizeof(txbuf) - 1) { dev_err(&gl_ts->client->dev, "buf length is out of limit\n"); return false; } txbuf[0] = buf_index; memcpy(txbuf + 1, buffer, buf_len); return i2c_transfer(gl_ts->client->adapter, &msg, 1); } /* * Device is apparently always ready for i2c but not for actual * register reads/writes. This function ascertains it is ready * for that too. the results of this call often were ignored. */ static bool IT7260_waitDeviceReady(bool forever, bool slowly) { uint8_t query; uint32_t count = DEVICE_READY_MAX_WAIT; do { if (!IT7260_i2cReadNoReadyCheck(BUF_QUERY, &query, sizeof(query))) query = CMD_STATUS_BUSY; if (slowly) msleep(IT_I2C_WAIT); if (!forever) count--; } while ((query & CMD_STATUS_BUSY) && count); return !query; } static bool IT7260_i2cRead(uint8_t buf_index, uint8_t *buffer, uint16_t buf_len) { IT7260_waitDeviceReady(false, false); return IT7260_i2cReadNoReadyCheck(buf_index, buffer, buf_len); } static bool IT7260_i2cWrite(uint8_t buf_index, const uint8_t *buffer, uint16_t buf_len) { IT7260_waitDeviceReady(false, false); return IT7260_i2cWriteNoReadyCheck(buf_index, buffer, buf_len); } static bool IT7260_firmware_reinitialize(u8 command) { uint8_t cmd[] = {command}; uint8_t rsp[2]; if (!IT7260_i2cWrite(BUF_COMMAND, cmd, sizeof(cmd))) return false; if (!IT7260_i2cRead(BUF_RESPONSE, rsp, sizeof(rsp))) return false; /* a reply of two zero bytes signifies success */ return !rsp[0] && !rsp[1]; } static bool IT7260_enter_exit_fw_ugrade_mode(bool enter) { uint8_t cmd[] = {CMD_FIRMWARE_UPGRADE, 0, 'I', 'T', '7', '2', '6', '0', 0x55, 0xAA}; uint8_t resp[2]; cmd[1] = enter ? SUB_CMD_ENTER_FW_UPGRADE_MODE : SUB_CMD_EXIT_FW_UPGRADE_MODE; if (!IT7260_i2cWrite(BUF_COMMAND, cmd, sizeof(cmd))) return false; if (!IT7260_i2cRead(BUF_RESPONSE, resp, sizeof(resp))) return false; /* a reply of two zero bytes signifies success */ return !resp[0] && !resp[1]; } static bool IT7260_chipSetStartOffset(uint16_t offset) { uint8_t cmd[] = {CMD_SET_START_OFFSET, 0, ((uint8_t)(offset)), ((uint8_t)((offset) >> 8))}; uint8_t resp[2]; if (!IT7260_i2cWrite(BUF_COMMAND, cmd, 4)) return false; if (!IT7260_i2cRead(BUF_RESPONSE, resp, sizeof(resp))) return false; /* a reply of two zero bytes signifies success */ return !resp[0] && !resp[1]; } /* write fw_length bytes from fw_data at chip offset wr_start_offset */ static bool IT7260_fw_flash_write_verify(unsigned int fw_length, const uint8_t *fw_data, uint16_t wr_start_offset) { uint32_t cur_data_off; for (cur_data_off = 0; cur_data_off < fw_length; cur_data_off += FW_WRITE_CHUNK_SIZE) { uint8_t cmd_write[2 + FW_WRITE_CHUNK_SIZE] = {CMD_FW_WRITE}; uint8_t buf_read[FW_WRITE_CHUNK_SIZE]; uint8_t cmd_read[2] = {CMD_FW_READ}; unsigned i, retries; uint32_t cur_wr_size; /* figure out how much to write */ cur_wr_size = fw_length - cur_data_off; if (cur_wr_size > FW_WRITE_CHUNK_SIZE) cur_wr_size = FW_WRITE_CHUNK_SIZE; /* prepare the write command */ cmd_write[1] = cur_wr_size; for (i = 0; i < cur_wr_size; i++) cmd_write[i + 2] = fw_data[cur_data_off + i]; /* prepare the read command */ cmd_read[1] = cur_wr_size; for (retries = 0; retries < FW_WRITE_RETRY_COUNT; retries++) { /* set write offset and write the data */ IT7260_chipSetStartOffset( wr_start_offset + cur_data_off); IT7260_i2cWrite(BUF_COMMAND, cmd_write, cur_wr_size + 2); /* set offset and read the data back */ IT7260_chipSetStartOffset( wr_start_offset + cur_data_off); IT7260_i2cWrite(BUF_COMMAND, cmd_read, sizeof(cmd_read)); IT7260_i2cRead(BUF_RESPONSE, buf_read, cur_wr_size); /* verify. If success break out of retry loop */ i = 0; while (i < cur_wr_size && buf_read[i] == cmd_write[i + 2]) i++; if (i == cur_wr_size) break; } /* if we've failed after all the retries, tell the caller */ if (retries == FW_WRITE_RETRY_COUNT) { dev_err(&gl_ts->client->dev, "write of data offset %u failed on try %u at byte %u/%u\n", cur_data_off, retries, i, cur_wr_size); return false; } } return true; } /* * this code to get versions from the chip via i2c transactions, and save * them in driver data structure. */ static void IT7260_get_chip_versions(struct device *dev) { static const u8 cmd_read_fw_ver[] = {CMD_READ_VERSIONS, SUB_CMD_READ_FIRMWARE_VERSION}; static const u8 cmd_read_cfg_ver[] = {CMD_READ_VERSIONS, SUB_CMD_READ_CONFIG_VERSION}; u8 ver_fw[VERSION_LENGTH], ver_cfg[VERSION_LENGTH]; bool ret = true; ret = IT7260_i2cWrite(BUF_COMMAND, cmd_read_fw_ver, sizeof(cmd_read_fw_ver)); if (ret) { ret = IT7260_i2cRead(BUF_RESPONSE, ver_fw, VERSION_LENGTH); if (ret) memcpy(gl_ts->fw_ver, ver_fw + (5 * sizeof(u8)), VER_BUFFER_SIZE * sizeof(u8)); } if (!ret) dev_err(dev, "failed to read fw version from chip\n"); ret = IT7260_i2cWrite(BUF_COMMAND, cmd_read_cfg_ver, sizeof(cmd_read_cfg_ver)); if (ret) { ret = IT7260_i2cRead(BUF_RESPONSE, ver_cfg, VERSION_LENGTH) && ret; if (ret) memcpy(gl_ts->cfg_ver, ver_cfg + (1 * sizeof(u8)), VER_BUFFER_SIZE * sizeof(u8)); } if (!ret) dev_err(dev, "failed to read cfg version from chip\n"); dev_info(dev, "Current fw{%X.%X.%X.%X} cfg{%X.%X.%X.%X}\n", gl_ts->fw_ver[0], gl_ts->fw_ver[1], gl_ts->fw_ver[2], gl_ts->fw_ver[3], gl_ts->cfg_ver[0], gl_ts->cfg_ver[1], gl_ts->cfg_ver[2], gl_ts->cfg_ver[3]); } static int IT7260_cfg_upload(struct device *dev, bool force) { const struct firmware *cfg = NULL; int ret; bool success, cfg_upgrade = false; ret = request_firmware(&cfg, gl_ts->cfg_name, dev); if (ret) { dev_err(dev, "failed to get config data %s for it7260 %d\n", gl_ts->cfg_name, ret); return ret; } /* * This compares the cfg version number from chip and the cfg * data file. IT flashes only when version of cfg data file is * greater than that of chip or if it is set for force cfg upgrade. */ if (force) cfg_upgrade = true; else if (IT_CFG_CHECK(gl_ts->cfg_ver, cfg)) cfg_upgrade = true; if (!cfg_upgrade) { dev_err(dev, "CFG upgrade no required ...\n"); ret = -EFAULT; goto out; } else { dev_info(dev, "Config upgrading...\n"); disable_irq(gl_ts->client->irq); /* enter cfg upload mode */ success = IT7260_enter_exit_fw_ugrade_mode(true); if (!success) { dev_err(dev, "Can't enter cfg upgrade mode\n"); ret = -EIO; goto out; } /* flash config data if requested */ success = IT7260_fw_flash_write_verify(cfg->size, cfg->data, CHIP_FLASH_SIZE - cfg->size); if (!success) { dev_err(dev, "failed to upgrade touch cfg data\n"); IT7260_enter_exit_fw_ugrade_mode(false); IT7260_firmware_reinitialize(CMD_FIRMWARE_REINIT_6F); ret = -EIO; goto out; } else { memcpy(gl_ts->cfg_ver, cfg->data + (cfg->size - 8 * sizeof(u8)), VER_BUFFER_SIZE * sizeof(u8)); dev_info(dev, "CFG upgrade is success. New cfg ver: %X.%X.%X.%X\n", gl_ts->cfg_ver[0], gl_ts->cfg_ver[1], gl_ts->cfg_ver[2], gl_ts->cfg_ver[3]); } enable_irq(gl_ts->client->irq); } out: release_firmware(cfg); return ret; } static int IT7260_fw_upload(struct device *dev, bool force) { const struct firmware *fw = NULL; int ret; bool success, fw_upgrade = false; ret = request_firmware(&fw, gl_ts->fw_name, dev); if (ret) { dev_err(dev, "failed to get firmware %s for it7260 %d\n", gl_ts->fw_name, ret); return ret; } /* * This compares the fw version number from chip and the fw data * file. It flashes only when version of fw data file is greater * than that of chip or it it is set for force fw upgrade. */ if (force) fw_upgrade = true; else if (IT_FW_CHECK(gl_ts->fw_ver, fw)) fw_upgrade = true; if (!fw_upgrade) { dev_err(dev, "FW upgrade not required ...\n"); ret = -EFAULT; goto out; } else { dev_info(dev, "Firmware upgrading...\n"); disable_irq(gl_ts->client->irq); /* enter fw upload mode */ success = IT7260_enter_exit_fw_ugrade_mode(true); if (!success) { dev_err(dev, "Can't enter fw upgrade mode\n"); ret = -EIO; goto out; } /* flash the firmware if requested */ success = IT7260_fw_flash_write_verify(fw->size, fw->data, 0); if (!success) { dev_err(dev, "failed to upgrade touch firmware\n"); IT7260_enter_exit_fw_ugrade_mode(false); IT7260_firmware_reinitialize(CMD_FIRMWARE_REINIT_6F); ret = -EIO; goto out; } else { memcpy(gl_ts->fw_ver, fw->data + (8 * sizeof(u8)), VER_BUFFER_SIZE * sizeof(u8)); dev_info(dev, "FW upgrade is success. New fw ver: %X.%X.%X.%X\n", gl_ts->fw_ver[0], gl_ts->fw_ver[1], gl_ts->fw_ver[2], gl_ts->fw_ver[3]); } enable_irq(gl_ts->client->irq); } out: release_firmware(fw); return ret; } static int IT7260_ts_chipLowPowerMode(const u8 sleep_type) { const uint8_t cmd_sleep[] = {CMD_PWR_CTL, 0x00, sleep_type}; uint8_t dummy; if (sleep_type) IT7260_i2cWriteNoReadyCheck(BUF_COMMAND, cmd_sleep, sizeof(cmd_sleep)); else IT7260_i2cReadNoReadyCheck(BUF_QUERY, &dummy, sizeof(dummy)); msleep(WAIT_CHANGE_MODE); return 0; } static ssize_t sysfs_fw_upgrade_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int mode = 0, ret; if (gl_ts->suspended) { dev_err(dev, "Device is suspended, can't flash fw!!!\n"); return -EBUSY; } ret = kstrtoint(buf, 10, &mode); if (!ret) { dev_err(dev, "failed to read input for sysfs\n"); return -EINVAL; } mutex_lock(&gl_ts->fw_cfg_mutex); if (mode == 1) { gl_ts->fw_cfg_uploading = true; ret = IT7260_fw_upload(dev, false); if (ret) { dev_err(dev, "Failed to flash fw: %d", ret); gl_ts->fw_upgrade_result = false; } else { gl_ts->fw_upgrade_result = true; } gl_ts->fw_cfg_uploading = false; } mutex_unlock(&gl_ts->fw_cfg_mutex); return count; } static ssize_t sysfs_cfg_upgrade_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int mode = 0, ret; if (gl_ts->suspended) { dev_err(dev, "Device is suspended, can't flash cfg!!!\n"); return -EBUSY; } ret = kstrtoint(buf, 10, &mode); if (!ret) { dev_err(dev, "failed to read input for sysfs\n"); return -EINVAL; } mutex_lock(&gl_ts->fw_cfg_mutex); if (mode == 1) { gl_ts->fw_cfg_uploading = true; ret = IT7260_cfg_upload(dev, false); if (ret) { dev_err(dev, "Failed to flash cfg: %d", ret); gl_ts->cfg_upgrade_result = false; } else { gl_ts->cfg_upgrade_result = true; } gl_ts->fw_cfg_uploading = false; } mutex_unlock(&gl_ts->fw_cfg_mutex); return count; } static ssize_t sysfs_fw_upgrade_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, MAX_BUFFER_SIZE, "%d\n", gl_ts->fw_upgrade_result); } static ssize_t sysfs_cfg_upgrade_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, MAX_BUFFER_SIZE, "%d\n", gl_ts->cfg_upgrade_result); } static ssize_t sysfs_force_fw_upgrade_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int mode = 0, ret; if (gl_ts->suspended) { dev_err(dev, "Device is suspended, can't flash fw!!!\n"); return -EBUSY; } ret = kstrtoint(buf, 10, &mode); if (!ret) { dev_err(dev, "failed to read input for sysfs\n"); return -EINVAL; } mutex_lock(&gl_ts->fw_cfg_mutex); if (mode == 1) { gl_ts->fw_cfg_uploading = true; ret = IT7260_fw_upload(dev, true); if (ret) { dev_err(dev, "Failed to force flash fw: %d", ret); gl_ts->fw_upgrade_result = false; } else { gl_ts->fw_upgrade_result = true; } gl_ts->fw_cfg_uploading = false; } mutex_unlock(&gl_ts->fw_cfg_mutex); return count; } static ssize_t sysfs_force_cfg_upgrade_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int mode = 0, ret; if (gl_ts->suspended) { dev_err(dev, "Device is suspended, can't flash cfg!!!\n"); return -EBUSY; } ret = kstrtoint(buf, 10, &mode); if (!ret) { dev_err(dev, "failed to read input for sysfs\n"); return -EINVAL; } mutex_lock(&gl_ts->fw_cfg_mutex); if (mode == 1) { gl_ts->fw_cfg_uploading = true; ret = IT7260_cfg_upload(dev, true); if (ret) { dev_err(dev, "Failed to force flash cfg: %d", ret); gl_ts->cfg_upgrade_result = false; } else { gl_ts->cfg_upgrade_result = true; } gl_ts->fw_cfg_uploading = false; } mutex_unlock(&gl_ts->fw_cfg_mutex); return count; } static ssize_t sysfs_force_fw_upgrade_show(struct device *dev, struct device_attribute *attr, char *buf) { return snprintf(buf, MAX_BUFFER_SIZE, "%d", gl_ts->fw_upgrade_result); } static ssize_t sysfs_force_cfg_upgrade_show(struct device *dev, struct device_attribute *attr, char *buf) { return snprintf(buf, MAX_BUFFER_SIZE, "%d", gl_ts->cfg_upgrade_result); } static ssize_t sysfs_calibration_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, MAX_BUFFER_SIZE, "%d\n", gl_ts->calibration_success); } static bool IT7260_chipSendCalibrationCmd(bool auto_tune_on) { uint8_t cmd_calibrate[] = {CMD_CALIBRATE, 0, auto_tune_on ? 1 : 0, 0, 0}; return IT7260_i2cWrite(BUF_COMMAND, cmd_calibrate, sizeof(cmd_calibrate)); } static ssize_t sysfs_calibration_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { uint8_t resp; if (!IT7260_chipSendCalibrationCmd(false)) { dev_err(dev, "failed to send calibration command\n"); } else { gl_ts->calibration_success = IT7260_i2cRead(BUF_RESPONSE, &resp, sizeof(resp)); /* * previous logic that was here never called * IT7260_firmware_reinitialize() due to checking a * guaranteed-not-null value against null. We now * call it. Hopefully this is OK */ if (!resp) dev_dbg(dev, "IT7260_firmware_reinitialize-> %s\n", IT7260_firmware_reinitialize(CMD_FIRMWARE_REINIT_6F) ? "success" : "fail"); } return count; } static ssize_t sysfs_point_show(struct device *dev, struct device_attribute *attr, char *buf) { uint8_t point_data[sizeof(struct PointData)]; bool readSuccess; ssize_t ret; readSuccess = IT7260_i2cReadNoReadyCheck(BUF_POINT_INFO, point_data, sizeof(point_data)); if (readSuccess) { ret = scnprintf(buf, MAX_BUFFER_SIZE, "point_show read ret[%d]--point[%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x]\n", readSuccess, point_data[0], point_data[1], point_data[2], point_data[3], point_data[4], point_data[5], point_data[6], point_data[7], point_data[8], point_data[9], point_data[10], point_data[11], point_data[12], point_data[13]); } else { ret = scnprintf(buf, MAX_BUFFER_SIZE, "failed to read point data\n"); } dev_dbg(dev, "%s", buf); return ret; } static ssize_t sysfs_version_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, MAX_BUFFER_SIZE, "fw{%X.%X.%X.%X} cfg{%X.%X.%X.%X}\n", gl_ts->fw_ver[0], gl_ts->fw_ver[1], gl_ts->fw_ver[2], gl_ts->fw_ver[3], gl_ts->cfg_ver[0], gl_ts->cfg_ver[1], gl_ts->cfg_ver[2], gl_ts->cfg_ver[3]); } static ssize_t sysfs_sleep_show(struct device *dev, struct device_attribute *attr, char *buf) { /* * The usefulness of this was questionable at best - we were at least * leaking a byte of kernel data (by claiming to return a byte but not * writing to buf. To fix this now we actually return the sleep status */ *buf = gl_ts->suspended ? '1' : '0'; return 1; } static ssize_t sysfs_sleep_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int go_to_sleep, ret; ret = kstrtoint(buf, 10, &go_to_sleep); /* (gl_ts->suspended == true && goToSleepVal > 0) means * device is already suspended and you want it to be in sleep, * (gl_ts->suspended == false && goToSleepVal == 0) means * device is already active and you also want it to be active. */ if ((gl_ts->suspended && go_to_sleep > 0) || (!gl_ts->suspended && go_to_sleep == 0)) dev_err(dev, "duplicate request to %s chip\n", go_to_sleep ? "sleep" : "wake"); else if (go_to_sleep) { disable_irq(gl_ts->client->irq); IT7260_ts_chipLowPowerMode(PWR_CTL_SLEEP_MODE); dev_dbg(dev, "touch is going to sleep...\n"); } else { IT7260_ts_chipLowPowerMode(PWR_CTL_ACTIVE_MODE); enable_irq(gl_ts->client->irq); dev_dbg(dev, "touch is going to wake!\n"); } gl_ts->suspended = go_to_sleep; return count; } static ssize_t sysfs_cfg_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { char *strptr; if (count >= MAX_BUFFER_SIZE) { dev_err(dev, "Input over %d chars long\n", MAX_BUFFER_SIZE); return -EINVAL; } strptr = strnstr(buf, ".bin", count); if (!strptr) { dev_err(dev, "Input is invalid cfg file\n"); return -EINVAL; } strlcpy(gl_ts->cfg_name, buf, count); return count; } static ssize_t sysfs_cfg_name_show(struct device *dev, struct device_attribute *attr, char *buf) { if (strnlen(gl_ts->cfg_name, MAX_BUFFER_SIZE) > 0) return scnprintf(buf, MAX_BUFFER_SIZE, "%s\n", gl_ts->cfg_name); else return scnprintf(buf, MAX_BUFFER_SIZE, "No config file name given\n"); } static ssize_t sysfs_fw_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { char *strptr; if (count >= MAX_BUFFER_SIZE) { dev_err(dev, "Input over %d chars long\n", MAX_BUFFER_SIZE); return -EINVAL; } strptr = strnstr(buf, ".bin", count); if (!strptr) { dev_err(dev, "Input is invalid fw file\n"); return -EINVAL; } strlcpy(gl_ts->fw_name, buf, count); return count; } static ssize_t sysfs_fw_name_show(struct device *dev, struct device_attribute *attr, char *buf) { if (strnlen(gl_ts->fw_name, MAX_BUFFER_SIZE) > 0) return scnprintf(buf, MAX_BUFFER_SIZE, "%s\n", gl_ts->fw_name); else return scnprintf(buf, MAX_BUFFER_SIZE, "No firmware file name given\n"); } static DEVICE_ATTR(version, S_IRUGO | S_IWUSR, sysfs_version_show, NULL); static DEVICE_ATTR(sleep, S_IRUGO | S_IWUSR, sysfs_sleep_show, sysfs_sleep_store); static DEVICE_ATTR(calibration, S_IRUGO | S_IWUSR, sysfs_calibration_show, sysfs_calibration_store); static DEVICE_ATTR(fw_update, S_IRUGO | S_IWUSR, sysfs_fw_upgrade_show, sysfs_fw_upgrade_store); static DEVICE_ATTR(cfg_update, S_IRUGO | S_IWUSR, sysfs_cfg_upgrade_show, sysfs_cfg_upgrade_store); static DEVICE_ATTR(point, S_IRUGO | S_IWUSR, sysfs_point_show, NULL); static DEVICE_ATTR(fw_name, S_IRUGO | S_IWUSR, sysfs_fw_name_show, sysfs_fw_name_store); static DEVICE_ATTR(cfg_name, S_IRUGO | S_IWUSR, sysfs_cfg_name_show, sysfs_cfg_name_store); static DEVICE_ATTR(force_fw_update, S_IRUGO | S_IWUSR, sysfs_force_fw_upgrade_show, sysfs_force_fw_upgrade_store); static DEVICE_ATTR(force_cfg_update, S_IRUGO | S_IWUSR, sysfs_force_cfg_upgrade_show, sysfs_force_cfg_upgrade_store); static struct attribute *it7260_attributes[] = { &dev_attr_version.attr, &dev_attr_sleep.attr, &dev_attr_calibration.attr, &dev_attr_fw_update.attr, &dev_attr_cfg_update.attr, &dev_attr_point.attr, &dev_attr_fw_name.attr, &dev_attr_cfg_name.attr, &dev_attr_force_fw_update.attr, &dev_attr_force_cfg_update.attr, NULL }; static const struct attribute_group it7260_attr_group = { .attrs = it7260_attributes, }; static void IT7260_chipExternalCalibration(bool autoTuneEnabled) { uint8_t resp[2]; dev_dbg(&gl_ts->client->dev, "sent calibration command -> %d\n", IT7260_chipSendCalibrationCmd(autoTuneEnabled)); IT7260_waitDeviceReady(true, true); IT7260_i2cReadNoReadyCheck(BUF_RESPONSE, resp, sizeof(resp)); IT7260_firmware_reinitialize(CMD_FIRMWARE_REINIT_C); } void IT7260_sendCalibrationCmd(void) { IT7260_chipExternalCalibration(false); } EXPORT_SYMBOL(IT7260_sendCalibrationCmd); static void IT7260_ts_release_all(void) { int finger; for (finger = 0; finger < gl_ts->pdata->num_of_fingers; finger++) { input_mt_slot(gl_ts->input_dev, finger); input_mt_report_slot_state(gl_ts->input_dev, MT_TOOL_FINGER, 0); } input_report_key(gl_ts->input_dev, BTN_TOUCH, 0); input_sync(gl_ts->input_dev); } static irqreturn_t IT7260_ts_threaded_handler(int irq, void *devid) { struct PointData point_data; struct input_dev *input_dev = gl_ts->input_dev; u8 dev_status, finger, touch_count = 0, finger_status; u8 pressure = FD_PRESSURE_NONE; u16 x, y; bool palm_detected; /* verify there is point data to read & it is readable and valid */ IT7260_i2cReadNoReadyCheck(BUF_QUERY, &dev_status, sizeof(dev_status)); if (!((dev_status & PT_INFO_BITS) & PT_INFO_YES)) return IRQ_HANDLED; if (!IT7260_i2cReadNoReadyCheck(BUF_POINT_INFO, (void *)&point_data, sizeof(point_data))) { dev_err(&gl_ts->client->dev, "failed to read point data buffer\n"); return IRQ_HANDLED; } /* Check if controller moves from idle to active state */ if ((point_data.flags & PD_FLAGS_DATA_TYPE_BITS) != PD_FLAGS_DATA_TYPE_TOUCH) { /* * This code adds the touch-to-wake functionality to the ITE * tech driver. When user puts a finger on touch controller in * idle state, the controller moves to active state and driver * sends the KEY_WAKEUP event to wake the device. The * pm_stay_awake() call tells the pm core to stay awake until * the CPU cores are up already. The schedule_work() call * schedule a work that tells the pm core to relax once the CPU * cores are up. */ if (gl_ts->device_needs_wakeup) { pm_stay_awake(&gl_ts->client->dev); input_report_key(input_dev, KEY_WAKEUP, 1); input_sync(input_dev); input_report_key(input_dev, KEY_WAKEUP, 0); input_sync(input_dev); schedule_work(&gl_ts->work_pm_relax); return IRQ_HANDLED; } } palm_detected = point_data.palm & PD_PALM_FLAG_BIT; if (palm_detected && gl_ts->pdata->palm_detect_en) { input_report_key(input_dev, gl_ts->pdata->palm_detect_keycode, 1); input_sync(input_dev); input_report_key(input_dev, gl_ts->pdata->palm_detect_keycode, 0); input_sync(input_dev); } for (finger = 0; finger < gl_ts->pdata->num_of_fingers; finger++) { finger_status = point_data.flags & (0x01 << finger); input_mt_slot(input_dev, finger); input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, finger_status != 0); x = point_data.fd[finger].xLo + (((u16)(point_data.fd[finger].hi & 0x0F)) << 8); y = point_data.fd[finger].yLo + (((u16)(point_data.fd[finger].hi & 0xF0)) << 4); pressure = point_data.fd[finger].pressure & FD_PRESSURE_BITS; if (finger_status) { if (pressure >= FD_PRESSURE_LIGHT) { input_report_key(input_dev, BTN_TOUCH, 1); input_report_abs(input_dev, ABS_MT_POSITION_X, x); input_report_abs(input_dev, ABS_MT_POSITION_Y, y); touch_count++; } } } input_report_key(input_dev, BTN_TOUCH, touch_count > 0); input_sync(input_dev); return IRQ_HANDLED; } static void IT7260_ts_work_func(struct work_struct *work) { pm_relax(&gl_ts->client->dev); } static bool IT7260_chipIdentify(void) { static const uint8_t cmd_ident[] = {CMD_IDENT_CHIP}; static const uint8_t expected_id[] = {0x0A, 'I', 'T', 'E', '7', '2', '6', '0'}; uint8_t chip_id[10] = {0,}; IT7260_waitDeviceReady(false, false); if (!IT7260_i2cWriteNoReadyCheck(BUF_COMMAND, cmd_ident, sizeof(cmd_ident))) { dev_err(&gl_ts->client->dev, "failed to write CMD_IDENT_CHIP\n"); return false; } IT7260_waitDeviceReady(false, false); if (!IT7260_i2cReadNoReadyCheck(BUF_RESPONSE, chip_id, sizeof(chip_id))) { dev_err(&gl_ts->client->dev, "failed to read chip-id\n"); return false; } dev_info(&gl_ts->client->dev, "IT7260_chipIdentify read id: %02X %c%c%c%c%c%c%c %c%c\n", chip_id[0], chip_id[1], chip_id[2], chip_id[3], chip_id[4], chip_id[5], chip_id[6], chip_id[7], chip_id[8], chip_id[9]); if (memcmp(chip_id, expected_id, sizeof(expected_id))) return false; if (chip_id[8] == '5' && chip_id[9] == '6') dev_info(&gl_ts->client->dev, "rev BX3 found\n"); else if (chip_id[8] == '6' && chip_id[9] == '6') dev_info(&gl_ts->client->dev, "rev BX4 found\n"); else dev_info(&gl_ts->client->dev, "unknown revision (0x%02X 0x%02X) found\n", chip_id[8], chip_id[9]); return true; } static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA) { return (regulator_count_voltages(reg) > 0) ? regulator_set_optimum_mode(reg, load_uA) : 0; } static int IT7260_regulator_configure(bool on) { int retval; if (on == false) goto hw_shutdown; gl_ts->vdd = devm_regulator_get(&gl_ts->client->dev, "vdd"); if (IS_ERR(gl_ts->vdd)) { dev_err(&gl_ts->client->dev, "%s: Failed to get vdd regulator\n", __func__); return PTR_ERR(gl_ts->vdd); } if (regulator_count_voltages(gl_ts->vdd) > 0) { retval = regulator_set_voltage(gl_ts->vdd, IT_VTG_MIN_UV, IT_VTG_MAX_UV); if (retval) { dev_err(&gl_ts->client->dev, "regulator set_vtg failed retval =%d\n", retval); goto err_set_vtg_vdd; } } gl_ts->avdd = devm_regulator_get(&gl_ts->client->dev, "avdd"); if (IS_ERR(gl_ts->avdd)) { dev_err(&gl_ts->client->dev, "%s: Failed to get i2c regulator\n", __func__); retval = PTR_ERR(gl_ts->avdd); goto err_get_vtg_i2c; } if (regulator_count_voltages(gl_ts->avdd) > 0) { retval = regulator_set_voltage(gl_ts->avdd, IT_I2C_VTG_MIN_UV, IT_I2C_VTG_MAX_UV); if (retval) { dev_err(&gl_ts->client->dev, "reg set i2c vtg failed retval =%d\n", retval); goto err_set_vtg_i2c; } } return 0; err_set_vtg_i2c: err_get_vtg_i2c: if (regulator_count_voltages(gl_ts->vdd) > 0) regulator_set_voltage(gl_ts->vdd, 0, IT_VTG_MAX_UV); err_set_vtg_vdd: return retval; hw_shutdown: if (regulator_count_voltages(gl_ts->vdd) > 0) regulator_set_voltage(gl_ts->vdd, 0, IT_VTG_MAX_UV); if (regulator_count_voltages(gl_ts->avdd) > 0) regulator_set_voltage(gl_ts->avdd, 0, IT_I2C_VTG_MAX_UV); return 0; }; static int IT7260_power_on(bool on) { int retval; if (on == false) goto power_off; retval = reg_set_optimum_mode_check(gl_ts->vdd, IT_ACTIVE_LOAD_UA); if (retval < 0) { dev_err(&gl_ts->client->dev, "Regulator vdd set_opt failed rc=%d\n", retval); return retval; } retval = regulator_enable(gl_ts->vdd); if (retval) { dev_err(&gl_ts->client->dev, "Regulator vdd enable failed rc=%d\n", retval); goto error_reg_en_vdd; } retval = reg_set_optimum_mode_check(gl_ts->avdd, IT_I2C_ACTIVE_LOAD_UA); if (retval < 0) { dev_err(&gl_ts->client->dev, "Regulator avdd set_opt failed rc=%d\n", retval); goto error_reg_opt_i2c; } retval = regulator_enable(gl_ts->avdd); if (retval) { dev_err(&gl_ts->client->dev, "Regulator avdd enable failed rc=%d\n", retval); goto error_reg_en_avdd; } return 0; error_reg_en_avdd: reg_set_optimum_mode_check(gl_ts->avdd, 0); error_reg_opt_i2c: regulator_disable(gl_ts->vdd); error_reg_en_vdd: reg_set_optimum_mode_check(gl_ts->vdd, 0); return retval; power_off: reg_set_optimum_mode_check(gl_ts->vdd, 0); regulator_disable(gl_ts->vdd); reg_set_optimum_mode_check(gl_ts->avdd, 0); regulator_disable(gl_ts->avdd); return 0; } static int IT7260_gpio_configure(bool on) { int retval = 0; if (on) { if (gpio_is_valid(gl_ts->pdata->irq_gpio)) { /* configure touchscreen irq gpio */ retval = gpio_request(gl_ts->pdata->irq_gpio, "ite_irq_gpio"); if (retval) { dev_err(&gl_ts->client->dev, "unable to request irq gpio [%d]\n", retval); goto err_irq_gpio_req; } retval = gpio_direction_input(gl_ts->pdata->irq_gpio); if (retval) { dev_err(&gl_ts->client->dev, "unable to set direction for irq gpio [%d]\n", retval); goto err_irq_gpio_dir; } } else { dev_err(&gl_ts->client->dev, "irq gpio not provided\n"); goto err_irq_gpio_req; } if (gpio_is_valid(gl_ts->pdata->reset_gpio)) { /* configure touchscreen reset out gpio */ retval = gpio_request(gl_ts->pdata->reset_gpio, "ite_reset_gpio"); if (retval) { dev_err(&gl_ts->client->dev, "unable to request reset gpio [%d]\n", retval); goto err_reset_gpio_req; } retval = gpio_direction_output( gl_ts->pdata->reset_gpio, 1); if (retval) { dev_err(&gl_ts->client->dev, "unable to set direction for reset gpio [%d]\n", retval); goto err_reset_gpio_dir; } if (gl_ts->pdata->low_reset) gpio_set_value(gl_ts->pdata->reset_gpio, 0); else gpio_set_value(gl_ts->pdata->reset_gpio, 1); msleep(gl_ts->pdata->reset_delay); } else { dev_err(&gl_ts->client->dev, "reset gpio not provided\n"); goto err_reset_gpio_req; } } else { if (gpio_is_valid(gl_ts->pdata->irq_gpio)) gpio_free(gl_ts->pdata->irq_gpio); if (gpio_is_valid(gl_ts->pdata->reset_gpio)) { /* * This is intended to save leakage current * only. Even if the call(gpio_direction_input) * fails, only leakage current will be more but * functionality will not be affected. */ retval = gpio_direction_input(gl_ts->pdata->reset_gpio); if (retval) { dev_err(&gl_ts->client->dev, "unable to set direction for gpio reset [%d]\n", retval); } gpio_free(gl_ts->pdata->reset_gpio); } } return 0; err_reset_gpio_dir: if (gpio_is_valid(gl_ts->pdata->reset_gpio)) gpio_free(gl_ts->pdata->reset_gpio); err_reset_gpio_req: err_irq_gpio_dir: if (gpio_is_valid(gl_ts->pdata->irq_gpio)) gpio_free(gl_ts->pdata->irq_gpio); err_irq_gpio_req: return retval; } #if CONFIG_OF static int IT7260_get_dt_coords(struct device *dev, char *name, struct IT7260_ts_platform_data *pdata) { u32 coords[IT7260_COORDS_ARR_SIZE]; struct property *prop; struct device_node *np = dev->of_node; int coords_size, rc; prop = of_find_property(np, name, NULL); if (!prop) return -EINVAL; if (!prop->value) return -ENODATA; coords_size = prop->length / sizeof(u32); if (coords_size != IT7260_COORDS_ARR_SIZE) { dev_err(dev, "invalid %s\n", name); return -EINVAL; } rc = of_property_read_u32_array(np, name, coords, coords_size); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read %s\n", name); return rc; } if (strcmp(name, "ite,panel-coords") == 0) { pdata->panel_minx = coords[0]; pdata->panel_miny = coords[1]; pdata->panel_maxx = coords[2]; pdata->panel_maxy = coords[3]; if (pdata->panel_maxx == 0 || pdata->panel_minx > 0) rc = -EINVAL; else if (pdata->panel_maxy == 0 || pdata->panel_miny > 0) rc = -EINVAL; if (rc) { dev_err(dev, "Invalid panel resolution %d\n", rc); return rc; } } else if (strcmp(name, "ite,display-coords") == 0) { pdata->disp_minx = coords[0]; pdata->disp_miny = coords[1]; pdata->disp_maxx = coords[2]; pdata->disp_maxy = coords[3]; } else { dev_err(dev, "unsupported property %s\n", name); return -EINVAL; } return 0; } static int IT7260_parse_dt(struct device *dev, struct IT7260_ts_platform_data *pdata) { struct device_node *np = dev->of_node; u32 temp_val; int rc; /* reset, irq gpio info */ pdata->reset_gpio = of_get_named_gpio_flags(np, "ite,reset-gpio", 0, &pdata->reset_gpio_flags); pdata->irq_gpio = of_get_named_gpio_flags(np, "ite,irq-gpio", 0, &pdata->irq_gpio_flags); rc = of_property_read_u32(np, "ite,num-fingers", &temp_val); if (!rc) pdata->num_of_fingers = temp_val; else if (rc != -EINVAL) { dev_err(dev, "Unable to read reset delay\n"); return rc; } pdata->wakeup = of_property_read_bool(np, "ite,wakeup"); pdata->palm_detect_en = of_property_read_bool(np, "ite,palm-detect-en"); if (pdata->palm_detect_en) { rc = of_property_read_u32(np, "ite,palm-detect-keycode", &temp_val); if (!rc) { pdata->palm_detect_keycode = temp_val; } else { dev_err(dev, "Unable to read palm-detect-keycode\n"); return rc; } } rc = of_property_read_string(np, "ite,fw-name", &pdata->fw_name); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read fw image name %d\n", rc); return rc; } rc = of_property_read_string(np, "ite,cfg-name", &pdata->cfg_name); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read cfg image name %d\n", rc); return rc; } snprintf(gl_ts->fw_name, MAX_BUFFER_SIZE, "%s", (pdata->fw_name != NULL) ? pdata->fw_name : FW_NAME); snprintf(gl_ts->cfg_name, MAX_BUFFER_SIZE, "%s", (pdata->cfg_name != NULL) ? pdata->cfg_name : CFG_NAME); rc = of_property_read_u32(np, "ite,reset-delay", &temp_val); if (!rc) pdata->reset_delay = temp_val; else if (rc != -EINVAL) { dev_err(dev, "Unable to read reset delay\n"); return rc; } pdata->low_reset = of_property_read_bool(np, "ite,low-reset"); rc = IT7260_get_dt_coords(dev, "ite,display-coords", pdata); if (rc && (rc != -EINVAL)) return rc; rc = IT7260_get_dt_coords(dev, "ite,panel-coords", pdata); if (rc && (rc != -EINVAL)) return rc; return 0; } #else static inline int IT7260_ts_parse_dt(struct device *dev, struct IT7260_ts_platform_data *pdata) { return 0; } #endif static int IT7260_ts_pinctrl_init(struct IT7260_ts_data *ts_data) { int retval; /* Get pinctrl if target uses pinctrl */ ts_data->ts_pinctrl = devm_pinctrl_get(&(ts_data->client->dev)); if (IS_ERR_OR_NULL(ts_data->ts_pinctrl)) { retval = PTR_ERR(ts_data->ts_pinctrl); dev_dbg(&ts_data->client->dev, "Target does not use pinctrl %d\n", retval); goto err_pinctrl_get; } ts_data->pinctrl_state_active = pinctrl_lookup_state(ts_data->ts_pinctrl, PINCTRL_STATE_ACTIVE); if (IS_ERR_OR_NULL(ts_data->pinctrl_state_active)) { retval = PTR_ERR(ts_data->pinctrl_state_active); dev_err(&ts_data->client->dev, "Can not lookup %s pinstate %d\n", PINCTRL_STATE_ACTIVE, retval); goto err_pinctrl_lookup; } ts_data->pinctrl_state_suspend = pinctrl_lookup_state(ts_data->ts_pinctrl, PINCTRL_STATE_SUSPEND); if (IS_ERR_OR_NULL(ts_data->pinctrl_state_suspend)) { retval = PTR_ERR(ts_data->pinctrl_state_suspend); dev_err(&ts_data->client->dev, "Can not lookup %s pinstate %d\n", PINCTRL_STATE_SUSPEND, retval); goto err_pinctrl_lookup; } ts_data->pinctrl_state_release = pinctrl_lookup_state(ts_data->ts_pinctrl, PINCTRL_STATE_RELEASE); if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) { retval = PTR_ERR(ts_data->pinctrl_state_release); dev_dbg(&ts_data->client->dev, "Can not lookup %s pinstate %d\n", PINCTRL_STATE_RELEASE, retval); } return 0; err_pinctrl_lookup: devm_pinctrl_put(ts_data->ts_pinctrl); err_pinctrl_get: ts_data->ts_pinctrl = NULL; return retval; } static int IT7260_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { static const uint8_t cmd_start[] = {CMD_UNKNOWN_7}; struct IT7260_ts_platform_data *pdata; uint8_t rsp[2]; int ret = -1; struct dentry *temp; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "need I2C_FUNC_I2C\n"); return -ENODEV; } gl_ts = devm_kzalloc(&client->dev, sizeof(*gl_ts), GFP_KERNEL); if (!gl_ts) return -ENOMEM; gl_ts->client = client; i2c_set_clientdata(client, gl_ts); if (client->dev.platform_data == NULL) return -ENODEV; if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; ret = IT7260_parse_dt(&client->dev, pdata); if (ret) return ret; } else { pdata = client->dev.platform_data; } if (!pdata) return -ENOMEM; gl_ts->pdata = pdata; ret = IT7260_regulator_configure(true); if (ret < 0) { dev_err(&client->dev, "Failed to configure regulators\n"); goto err_reg_configure; } ret = IT7260_power_on(true); if (ret < 0) { dev_err(&client->dev, "Failed to power on\n"); goto err_power_device; } ret = IT7260_ts_pinctrl_init(gl_ts); if (!ret && gl_ts->ts_pinctrl) { /* * Pinctrl handle is optional. If pinctrl handle is found * let pins to be configured in active state. If not * found continue further without error. */ ret = pinctrl_select_state(gl_ts->ts_pinctrl, gl_ts->pinctrl_state_active); if (ret < 0) { dev_err(&gl_ts->client->dev, "failed to select pin to active state %d", ret); } } else { ret = IT7260_gpio_configure(true); if (ret < 0) { dev_err(&client->dev, "Failed to configure gpios\n"); goto err_gpio_config; } } if (!IT7260_chipIdentify()) { dev_err(&client->dev, "Failed to identify chip!!!"); goto err_identification_fail; } IT7260_get_chip_versions(&client->dev); gl_ts->input_dev = input_allocate_device(); if (!gl_ts->input_dev) { dev_err(&client->dev, "failed to allocate input device\n"); ret = -ENOMEM; goto err_input_alloc; } /* Initialize mutex for fw and cfg upgrade */ mutex_init(&gl_ts->fw_cfg_mutex); gl_ts->input_dev->name = DEVICE_NAME; gl_ts->input_dev->phys = "I2C"; gl_ts->input_dev->id.bustype = BUS_I2C; gl_ts->input_dev->id.vendor = 0x0001; gl_ts->input_dev->id.product = 0x7260; set_bit(EV_SYN, gl_ts->input_dev->evbit); set_bit(EV_KEY, gl_ts->input_dev->evbit); set_bit(EV_ABS, gl_ts->input_dev->evbit); set_bit(INPUT_PROP_DIRECT, gl_ts->input_dev->propbit); set_bit(BTN_TOUCH, gl_ts->input_dev->keybit); input_set_abs_params(gl_ts->input_dev, ABS_MT_POSITION_X, gl_ts->pdata->disp_minx, gl_ts->pdata->disp_maxx, 0, 0); input_set_abs_params(gl_ts->input_dev, ABS_MT_POSITION_Y, gl_ts->pdata->disp_miny, gl_ts->pdata->disp_maxy, 0, 0); input_mt_init_slots(gl_ts->input_dev, gl_ts->pdata->num_of_fingers, 0); input_set_drvdata(gl_ts->input_dev, gl_ts); if (pdata->wakeup) { set_bit(KEY_WAKEUP, gl_ts->input_dev->keybit); INIT_WORK(&gl_ts->work_pm_relax, IT7260_ts_work_func); device_init_wakeup(&client->dev, pdata->wakeup); } if (pdata->palm_detect_en) set_bit(gl_ts->pdata->palm_detect_keycode, gl_ts->input_dev->keybit); if (input_register_device(gl_ts->input_dev)) { dev_err(&client->dev, "failed to register input device\n"); goto err_input_register; } if (request_threaded_irq(client->irq, NULL, IT7260_ts_threaded_handler, IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, gl_ts)) { dev_err(&client->dev, "request_irq failed\n"); goto err_irq_reg; } if (sysfs_create_group(&(client->dev.kobj), &it7260_attr_group)) { dev_err(&client->dev, "failed to register sysfs #2\n"); goto err_sysfs_grp_create; } #if defined(CONFIG_FB) gl_ts->fb_notif.notifier_call = fb_notifier_callback; ret = fb_register_client(&gl_ts->fb_notif); if (ret) dev_err(&client->dev, "Unable to register fb_notifier %d\n", ret); #endif IT7260_i2cWriteNoReadyCheck(BUF_COMMAND, cmd_start, sizeof(cmd_start)); msleep(pdata->reset_delay); IT7260_i2cReadNoReadyCheck(BUF_RESPONSE, rsp, sizeof(rsp)); msleep(pdata->reset_delay); gl_ts->dir = debugfs_create_dir(DEBUGFS_DIR_NAME, NULL); if (gl_ts->dir == NULL || IS_ERR(gl_ts->dir)) { dev_err(&client->dev, "%s: Failed to create debugfs directory, ret = %ld\n", __func__, PTR_ERR(gl_ts->dir)); ret = PTR_ERR(gl_ts->dir); goto err_create_debugfs_dir; } temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, gl_ts->dir, gl_ts, &debug_suspend_fops); if (temp == NULL || IS_ERR(temp)) { dev_err(&client->dev, "%s: Failed to create suspend debugfs file, ret = %ld\n", __func__, PTR_ERR(temp)); ret = PTR_ERR(temp); goto err_create_debugfs_file; } return 0; err_create_debugfs_file: debugfs_remove_recursive(gl_ts->dir); err_create_debugfs_dir: #if defined(CONFIG_FB) if (fb_unregister_client(&gl_ts->fb_notif)) dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n"); #endif sysfs_remove_group(&(client->dev.kobj), &it7260_attr_group); err_sysfs_grp_create: free_irq(client->irq, gl_ts); err_irq_reg: input_unregister_device(gl_ts->input_dev); err_input_register: if (pdata->wakeup) { cancel_work_sync(&gl_ts->work_pm_relax); device_init_wakeup(&client->dev, false); } if (gl_ts->input_dev) input_free_device(gl_ts->input_dev); gl_ts->input_dev = NULL; err_input_alloc: err_identification_fail: if (gl_ts->ts_pinctrl) { if (IS_ERR_OR_NULL(gl_ts->pinctrl_state_release)) { devm_pinctrl_put(gl_ts->ts_pinctrl); gl_ts->ts_pinctrl = NULL; } else { ret = pinctrl_select_state(gl_ts->ts_pinctrl, gl_ts->pinctrl_state_release); if (ret) dev_err(&gl_ts->client->dev, "failed to select relase pinctrl state %d\n", ret); } } else { if (gpio_is_valid(pdata->reset_gpio)) gpio_free(pdata->reset_gpio); if (gpio_is_valid(pdata->irq_gpio)) gpio_free(pdata->irq_gpio); } err_gpio_config: IT7260_power_on(false); err_power_device: IT7260_regulator_configure(false); err_reg_configure: return ret; } static int IT7260_ts_remove(struct i2c_client *client) { int ret; debugfs_remove_recursive(gl_ts->dir); #if defined(CONFIG_FB) if (fb_unregister_client(&gl_ts->fb_notif)) dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n"); #endif sysfs_remove_group(&(client->dev.kobj), &it7260_attr_group); free_irq(client->irq, gl_ts); input_unregister_device(gl_ts->input_dev); if (gl_ts->input_dev) input_free_device(gl_ts->input_dev); gl_ts->input_dev = NULL; if (gl_ts->pdata->wakeup) { cancel_work_sync(&gl_ts->work_pm_relax); device_init_wakeup(&client->dev, false); } if (gl_ts->ts_pinctrl) { if (IS_ERR_OR_NULL(gl_ts->pinctrl_state_release)) { devm_pinctrl_put(gl_ts->ts_pinctrl); gl_ts->ts_pinctrl = NULL; } else { ret = pinctrl_select_state(gl_ts->ts_pinctrl, gl_ts->pinctrl_state_release); if (ret) dev_err(&gl_ts->client->dev, "failed to select relase pinctrl state %d\n", ret); } } else { if (gpio_is_valid(gl_ts->pdata->reset_gpio)) gpio_free(gl_ts->pdata->reset_gpio); if (gpio_is_valid(gl_ts->pdata->irq_gpio)) gpio_free(gl_ts->pdata->irq_gpio); } IT7260_power_on(false); IT7260_regulator_configure(false); return 0; } #if defined(CONFIG_FB) static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { struct fb_event *evdata = data; int *blank; if (evdata && evdata->data && gl_ts && gl_ts->client) { if (event == FB_EVENT_BLANK) { blank = evdata->data; if (*blank == FB_BLANK_UNBLANK) IT7260_ts_resume(&(gl_ts->client->dev)); else if (*blank == FB_BLANK_POWERDOWN || *blank == FB_BLANK_VSYNC_SUSPEND) IT7260_ts_suspend(&(gl_ts->client->dev)); } } return 0; } #endif #ifdef CONFIG_PM static int IT7260_ts_resume(struct device *dev) { int retval; if (device_may_wakeup(dev)) { if (gl_ts->device_needs_wakeup) { gl_ts->device_needs_wakeup = false; disable_irq_wake(gl_ts->client->irq); } return 0; } if (gl_ts->ts_pinctrl) { retval = pinctrl_select_state(gl_ts->ts_pinctrl, gl_ts->pinctrl_state_active); if (retval < 0) { dev_err(dev, "Cannot get default pinctrl state %d\n", retval); goto err_pinctrl_select_suspend; } } enable_irq(gl_ts->client->irq); gl_ts->suspended = false; return 0; err_pinctrl_select_suspend: return retval; } static int IT7260_ts_suspend(struct device *dev) { int retval; if (gl_ts->fw_cfg_uploading) { dev_dbg(dev, "Fw/cfg uploading. Can't go to suspend.\n"); return -EBUSY; } /* put the device in low power idle mode */ IT7260_ts_chipLowPowerMode(PWR_CTL_LOW_POWER_MODE); if (device_may_wakeup(dev)) { if (!gl_ts->device_needs_wakeup) { gl_ts->device_needs_wakeup = true; enable_irq_wake(gl_ts->client->irq); } return 0; } disable_irq(gl_ts->client->irq); IT7260_ts_release_all(); if (gl_ts->ts_pinctrl) { retval = pinctrl_select_state(gl_ts->ts_pinctrl, gl_ts->pinctrl_state_suspend); if (retval < 0) { dev_err(dev, "Cannot get idle pinctrl state %d\n", retval); goto err_pinctrl_select_suspend; } } gl_ts->suspended = true; return 0; err_pinctrl_select_suspend: return retval; } static const struct dev_pm_ops IT7260_ts_dev_pm_ops = { .suspend = IT7260_ts_suspend, .resume = IT7260_ts_resume, }; #else static int IT7260_ts_resume(struct device *dev) { return 0; } static int IT7260_ts_suspend(struct device *dev) { return 0; } #endif static const struct i2c_device_id IT7260_ts_id[] = { { DEVICE_NAME, 0}, {} }; MODULE_DEVICE_TABLE(i2c, IT7260_ts_id); static const struct of_device_id IT7260_match_table[] = { { .compatible = "ite,it7260_ts",}, {}, }; static struct i2c_driver IT7260_ts_driver = { .driver = { .owner = THIS_MODULE, .name = DEVICE_NAME, .of_match_table = IT7260_match_table, #ifdef CONFIG_PM .pm = &IT7260_ts_dev_pm_ops, #endif }, .probe = IT7260_ts_probe, .remove = IT7260_ts_remove, .id_table = IT7260_ts_id, }; module_i2c_driver(IT7260_ts_driver); MODULE_DESCRIPTION("IT7260 Touchscreen Driver"); MODULE_LICENSE("GPL v2");