blob: 88b1d3c013c79d863af70972fd4268997331734d [file] [log] [blame]
/* drivers/input/touchscreen/it7258_ts_i2c.c
*
* Copyright (C) 2014 ITE Tech. Inc.
* Copyright (c) 2015-2016, 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 <linux/module.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/of_gpio.h>
#include <linux/fb.h>
#include <linux/debugfs.h>
#include <linux/input/mt.h>
#include <linux/string.h>
#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_COUNT_MAX 500
#define DEVICE_READY_COUNT_20 20
#define IT_I2C_WAIT_10MS 10
#define IT_I2C_READ_RET 2
#define IT_I2C_WRITE_RET 1
/* 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 CMD_STATUS_NO_CONN 0x07
#define PT_INFO_BITS 0xF8
#define PT_INFO_YES 0x80
#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
#define PD_FLAGS_IDLE_TO_ACTIVE 0x10
/* 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 DELAY_VTG_REG_EN 170
#define PINCTRL_STATE_ACTIVE "pmx_ts_active"
#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend"
#define PINCTRL_STATE_RELEASE "pmx_ts_release"
struct finger_data {
u8 xLo;
u8 hi;
u8 yLo;
u8 pressure;
} __packed;
struct point_data {
u8 flags;
u8 gesture_id;
struct finger_data 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;
unsigned int avdd_lpm_cur;
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 in_low_power_mode;
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 int it7260_debug_suspend_set(void *_data, u64 val)
{
struct it7260_ts_data *ts_data = _data;
if (val)
it7260_ts_suspend(&ts_data->client->dev);
else
it7260_ts_resume(&ts_data->client->dev);
return 0;
}
static int it7260_debug_suspend_get(void *_data, u64 *val)
{
struct it7260_ts_data *ts_data = _data;
mutex_lock(&ts_data->input_dev->mutex);
*val = ts_data->suspended;
mutex_lock(&ts_data->input_dev->mutex);
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 int it7260_i2c_read_no_ready_check(struct it7260_ts_data *ts_data,
uint8_t buf_index, uint8_t *buffer, uint16_t buf_len)
{
int ret;
struct i2c_msg msgs[2] = {
{
.addr = ts_data->client->addr,
.flags = I2C_M_NOSTART,
.len = 1,
.buf = &buf_index
},
{
.addr = ts_data->client->addr,
.flags = I2C_M_RD,
.len = buf_len,
.buf = buffer
}
};
memset(buffer, 0xFF, buf_len);
ret = i2c_transfer(ts_data->client->adapter, msgs, 2);
if (ret < 0)
dev_err(&ts_data->client->dev, "i2c read failed %d\n", ret);
return ret;
}
static int it7260_i2c_write_no_ready_check(struct it7260_ts_data *ts_data,
uint8_t buf_index, const uint8_t *buffer, uint16_t buf_len)
{
uint8_t txbuf[257];
int ret;
struct i2c_msg msg = {
.addr = ts_data->client->addr,
.flags = 0,
.len = buf_len + 1,
.buf = txbuf
};
/* just to be careful */
if (buf_len > sizeof(txbuf) - 1) {
dev_err(&ts_data->client->dev, "buf length is out of limit\n");
return false;
}
txbuf[0] = buf_index;
memcpy(txbuf + 1, buffer, buf_len);
ret = i2c_transfer(ts_data->client->adapter, &msg, 1);
if (ret < 0)
dev_err(&ts_data->client->dev, "i2c write failed %d\n", ret);
return ret;
}
/*
* Device is apparently always ready for I2C communication but not for
* actual register reads/writes. This function checks if it is ready
* for that too. The results of this call often were ignored.
* If forever is set to TRUE, then check the device's status until it
* becomes ready with 500 retries at max. Otherwise retry 25 times only.
* If slowly is set to TRUE, then add sleep of 50 ms in each retry,
* otherwise don't sleep.
*/
static int it7260_wait_device_ready(struct it7260_ts_data *ts_data,
bool forever, bool slowly)
{
uint8_t query;
uint32_t count = DEVICE_READY_COUNT_20;
int ret;
if (ts_data->fw_cfg_uploading || forever)
count = DEVICE_READY_COUNT_MAX;
do {
ret = it7260_i2c_read_no_ready_check(ts_data, BUF_QUERY, &query,
sizeof(query));
if (ret < 0 && ((query & CMD_STATUS_BITS)
== CMD_STATUS_NO_CONN))
continue;
if ((query & CMD_STATUS_BITS) == CMD_STATUS_DONE)
break;
query = CMD_STATUS_BUSY;
if (slowly)
msleep(IT_I2C_WAIT_10MS);
} while (--count);
return ((!(query & CMD_STATUS_BITS)) ? 0 : -ENODEV);
}
static int it7260_i2c_read(struct it7260_ts_data *ts_data, uint8_t buf_index,
uint8_t *buffer, uint16_t buf_len)
{
int ret;
ret = it7260_wait_device_ready(ts_data, false, false);
if (ret < 0)
return ret;
return it7260_i2c_read_no_ready_check(ts_data, buf_index,
buffer, buf_len);
}
static int it7260_i2c_write(struct it7260_ts_data *ts_data, uint8_t buf_index,
const uint8_t *buffer, uint16_t buf_len)
{
int ret;
ret = it7260_wait_device_ready(ts_data, false, false);
if (ret < 0)
return ret;
return it7260_i2c_write_no_ready_check(ts_data, buf_index,
buffer, buf_len);
}
static int it7260_firmware_reinitialize(struct it7260_ts_data *ts_data,
u8 command)
{
uint8_t cmd[] = {command};
uint8_t rsp[2];
int ret;
ret = it7260_i2c_write(ts_data, BUF_COMMAND, cmd, sizeof(cmd));
if (ret != IT_I2C_WRITE_RET) {
dev_err(&ts_data->client->dev,
"failed to write fw reinit command %d\n", ret);
return ret;
}
ret = it7260_i2c_read(ts_data, BUF_RESPONSE, rsp, sizeof(rsp));
if (ret != IT_I2C_READ_RET) {
dev_err(&ts_data->client->dev,
"failed to read any response from chip %d\n", ret);
return ret;
}
/* a reply of two zero bytes signifies success */
if (rsp[0] == 0 && rsp[1] == 0)
return 0;
else
return -EIO;
}
static int it7260_enter_exit_fw_ugrade_mode(struct it7260_ts_data *ts_data,
bool enter)
{
uint8_t cmd[] = {CMD_FIRMWARE_UPGRADE, 0, 'I', 'T', '7', '2',
'6', '0', 0x55, 0xAA};
uint8_t resp[2];
int ret;
cmd[1] = enter ? SUB_CMD_ENTER_FW_UPGRADE_MODE :
SUB_CMD_EXIT_FW_UPGRADE_MODE;
ret = it7260_i2c_write(ts_data, BUF_COMMAND, cmd, sizeof(cmd));
if (ret != IT_I2C_WRITE_RET) {
dev_err(&ts_data->client->dev,
"failed to write CMD_FIRMWARE_UPGRADE %d\n", ret);
return ret;
}
ret = it7260_i2c_read(ts_data, BUF_RESPONSE, resp, sizeof(resp));
if (ret != IT_I2C_READ_RET) {
dev_err(&ts_data->client->dev,
"failed to read any response from chip %d\n", ret);
return ret;
}
/* a reply of two zero bytes signifies success */
if (resp[0] == 0 && resp[1] == 0)
return 0;
else
return -EIO;
}
static int it7260_set_start_offset(struct it7260_ts_data *ts_data,
uint16_t offset)
{
uint8_t cmd[] = {CMD_SET_START_OFFSET, 0, ((uint8_t)(offset)),
((uint8_t)((offset) >> 8))};
uint8_t resp[2];
int ret;
ret = it7260_i2c_write(ts_data, BUF_COMMAND, cmd, 4);
if (ret != IT_I2C_WRITE_RET) {
dev_err(&ts_data->client->dev,
"failed to write CMD_SET_START_OFFSET %d\n", ret);
return ret;
}
ret = it7260_i2c_read(ts_data, BUF_RESPONSE, resp, sizeof(resp));
if (ret != IT_I2C_READ_RET) {
dev_err(&ts_data->client->dev,
"failed to read any response from chip %d\n", ret);
return ret;
}
/* a reply of two zero bytes signifies success */
if (resp[0] == 0 && resp[1] == 0)
return 0;
else
return -EIO;
}
/* write fw_length bytes from fw_data at chip offset wr_start_offset */
static int it7260_fw_flash_write_verify(struct it7260_ts_data *ts_data,
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_set_start_offset(ts_data,
wr_start_offset + cur_data_off);
it7260_i2c_write(ts_data, BUF_COMMAND, cmd_write,
cur_wr_size + 2);
/* set offset and read the data back */
it7260_set_start_offset(ts_data,
wr_start_offset + cur_data_off);
it7260_i2c_write(ts_data, BUF_COMMAND, cmd_read,
sizeof(cmd_read));
it7260_i2c_read(ts_data, 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(&ts_data->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 -EIO;
}
}
return 0;
}
/*
* 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 it7260_ts_data *ts_data)
{
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];
int ret;
ret = it7260_i2c_write(ts_data, BUF_COMMAND, cmd_read_fw_ver,
sizeof(cmd_read_fw_ver));
if (ret == IT_I2C_WRITE_RET) {
/*
* Sometimes, the controller may not respond immediately after
* writing the command, so wait for device to get ready.
*/
ret = it7260_wait_device_ready(ts_data, true, false);
if (ret < 0)
dev_err(&ts_data->client->dev,
"failed to read chip status %d\n", ret);
ret = it7260_i2c_read_no_ready_check(ts_data, BUF_RESPONSE,
ver_fw, VERSION_LENGTH);
if (ret == IT_I2C_READ_RET)
memcpy(ts_data->fw_ver, ver_fw + (5 * sizeof(u8)),
VER_BUFFER_SIZE * sizeof(u8));
else
dev_err(&ts_data->client->dev,
"failed to read fw-ver from chip %d\n", ret);
} else {
dev_err(&ts_data->client->dev,
"failed to write fw-read command %d\n", ret);
}
ret = it7260_i2c_write(ts_data, BUF_COMMAND, cmd_read_cfg_ver,
sizeof(cmd_read_cfg_ver));
if (ret == IT_I2C_WRITE_RET) {
/*
* Sometimes, the controller may not respond immediately after
* writing the command, so wait for device to get ready.
*/
ret = it7260_wait_device_ready(ts_data, true, false);
if (ret < 0)
dev_err(&ts_data->client->dev,
"failed to read chip status %d\n", ret);
ret = it7260_i2c_read_no_ready_check(ts_data, BUF_RESPONSE,
ver_cfg, VERSION_LENGTH);
if (ret == IT_I2C_READ_RET)
memcpy(ts_data->cfg_ver, ver_cfg + (1 * sizeof(u8)),
VER_BUFFER_SIZE * sizeof(u8));
else
dev_err(&ts_data->client->dev,
"failed to read cfg-ver from chip %d\n", ret);
} else {
dev_err(&ts_data->client->dev,
"failed to write cfg-read command %d\n", ret);
}
dev_info(&ts_data->client->dev, "Current fw{%X.%X.%X.%X} cfg{%X.%X.%X.%X}\n",
ts_data->fw_ver[0], ts_data->fw_ver[1], ts_data->fw_ver[2],
ts_data->fw_ver[3], ts_data->cfg_ver[0], ts_data->cfg_ver[1],
ts_data->cfg_ver[2], ts_data->cfg_ver[3]);
}
static int it7260_cfg_upload(struct it7260_ts_data *ts_data, bool force)
{
const struct firmware *cfg = NULL;
int ret;
bool cfg_upgrade = false;
struct device *dev = &ts_data->client->dev;
ret = request_firmware(&cfg, ts_data->cfg_name, dev);
if (ret) {
dev_err(dev, "failed to get config data %s for it7260 %d\n",
ts_data->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(ts_data->cfg_ver, cfg))
cfg_upgrade = true;
if (!cfg_upgrade) {
dev_err(dev, "CFG upgrade not required ...\n");
dev_info(dev,
"Chip CFG : %X.%X.%X.%X Binary CFG : %X.%X.%X.%X\n",
ts_data->cfg_ver[0], ts_data->cfg_ver[1],
ts_data->cfg_ver[2], ts_data->cfg_ver[3],
cfg->data[cfg->size - 8], cfg->data[cfg->size - 7],
cfg->data[cfg->size - 6], cfg->data[cfg->size - 5]);
ret = -EFAULT;
goto out;
} else {
dev_info(dev, "Config upgrading...\n");
disable_irq(ts_data->client->irq);
/* enter cfg upload mode */
ret = it7260_enter_exit_fw_ugrade_mode(ts_data, true);
if (ret < 0) {
dev_err(dev, "Can't enter cfg upgrade mode %d\n", ret);
enable_irq(ts_data->client->irq);
goto out;
}
/* flash config data if requested */
ret = it7260_fw_flash_write_verify(ts_data, cfg->size,
cfg->data, CHIP_FLASH_SIZE - cfg->size);
if (ret < 0) {
dev_err(dev,
"failed to upgrade touch cfg data %d\n", ret);
ret = it7260_enter_exit_fw_ugrade_mode(ts_data, false);
if (ret < 0)
dev_err(dev,
"Can't exit cfg upgrade mode%d\n", ret);
ret = it7260_firmware_reinitialize(ts_data,
CMD_FIRMWARE_REINIT_6F);
if (ret < 0)
dev_err(dev, "Can't reinit cfg %d\n", ret);
ret = -EIO;
enable_irq(ts_data->client->irq);
goto out;
} else {
memcpy(ts_data->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",
ts_data->cfg_ver[0], ts_data->cfg_ver[1],
ts_data->cfg_ver[2], ts_data->cfg_ver[3]);
}
enable_irq(ts_data->client->irq);
}
out:
release_firmware(cfg);
return ret;
}
static int it7260_fw_upload(struct it7260_ts_data *ts_data, bool force)
{
const struct firmware *fw = NULL;
int ret;
bool fw_upgrade = false;
struct device *dev = &ts_data->client->dev;
ret = request_firmware(&fw, ts_data->fw_name, dev);
if (ret) {
dev_err(dev, "failed to get firmware %s for it7260 %d\n",
ts_data->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(ts_data->fw_ver, fw))
fw_upgrade = true;
if (!fw_upgrade) {
dev_err(dev, "FW upgrade not required ...\n");
dev_info(dev, "Chip FW : %X.%X.%X.%X Binary FW : %X.%X.%X.%X\n",
ts_data->fw_ver[0], ts_data->fw_ver[1],
ts_data->fw_ver[2], ts_data->fw_ver[3],
fw->data[8], fw->data[9], fw->data[10], fw->data[11]);
ret = -EFAULT;
goto out;
} else {
dev_info(dev, "Firmware upgrading...\n");
disable_irq(ts_data->client->irq);
/* enter fw upload mode */
ret = it7260_enter_exit_fw_ugrade_mode(ts_data, true);
if (ret < 0) {
dev_err(dev, "Can't enter fw upgrade mode %d\n", ret);
enable_irq(ts_data->client->irq);
goto out;
}
/* flash the firmware if requested */
ret = it7260_fw_flash_write_verify(ts_data, fw->size,
fw->data, 0);
if (ret < 0) {
dev_err(dev,
"failed to upgrade touch firmware %d\n", ret);
ret = it7260_enter_exit_fw_ugrade_mode(ts_data, false);
if (ret < 0)
dev_err(dev,
"Can't exit fw upgrade mode %d\n", ret);
ret = it7260_firmware_reinitialize(ts_data,
CMD_FIRMWARE_REINIT_6F);
if (ret < 0)
dev_err(dev, "Can't reinit firmware %d\n", ret);
ret = -EIO;
enable_irq(ts_data->client->irq);
goto out;
} else {
memcpy(ts_data->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",
ts_data->fw_ver[0], ts_data->fw_ver[1],
ts_data->fw_ver[2], ts_data->fw_ver[3]);
}
enable_irq(ts_data->client->irq);
}
out:
release_firmware(fw);
return ret;
}
static int it7260_ts_chip_low_power_mode(struct it7260_ts_data *ts_data,
const u8 sleep_type)
{
const u8 cmd_sleep[] = {CMD_PWR_CTL, 0x00, sleep_type};
u8 dummy;
int ret;
if (sleep_type) {
ret = it7260_i2c_write_no_ready_check(ts_data, BUF_COMMAND,
cmd_sleep, sizeof(cmd_sleep));
if (ret != IT_I2C_WRITE_RET)
dev_err(&ts_data->client->dev,
"Can't go to sleep or low power mode(%d) %d\n",
sleep_type, ret);
else
ret = 0;
} else {
ret = it7260_i2c_read_no_ready_check(ts_data, BUF_QUERY, &dummy,
sizeof(dummy));
if (ret != IT_I2C_READ_RET)
dev_err(&ts_data->client->dev,
"Can't go to active mode %d\n", ret);
else
ret = 0;
}
msleep(WAIT_CHANGE_MODE);
return ret;
}
static ssize_t sysfs_fw_upgrade_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
int mode = 0, ret;
if (ts_data->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(&ts_data->fw_cfg_mutex);
if (mode == 1) {
ts_data->fw_cfg_uploading = true;
ret = it7260_fw_upload(ts_data, false);
if (ret) {
dev_err(dev, "Failed to flash fw: %d", ret);
ts_data->fw_upgrade_result = false;
} else {
ts_data->fw_upgrade_result = true;
}
ts_data->fw_cfg_uploading = false;
}
mutex_unlock(&ts_data->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)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
int mode = 0, ret;
if (ts_data->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(&ts_data->fw_cfg_mutex);
if (mode == 1) {
ts_data->fw_cfg_uploading = true;
ret = it7260_cfg_upload(ts_data, false);
if (ret) {
dev_err(dev, "Failed to flash cfg: %d", ret);
ts_data->cfg_upgrade_result = false;
} else {
ts_data->cfg_upgrade_result = true;
}
ts_data->fw_cfg_uploading = false;
}
mutex_unlock(&ts_data->fw_cfg_mutex);
return count;
}
static ssize_t sysfs_fw_upgrade_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
return scnprintf(buf, MAX_BUFFER_SIZE, "%d\n",
ts_data->fw_upgrade_result);
}
static ssize_t sysfs_cfg_upgrade_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
return scnprintf(buf, MAX_BUFFER_SIZE, "%d\n",
ts_data->cfg_upgrade_result);
}
static ssize_t sysfs_force_fw_upgrade_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
int mode = 0, ret;
if (ts_data->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(&ts_data->fw_cfg_mutex);
if (mode == 1) {
ts_data->fw_cfg_uploading = true;
ret = it7260_fw_upload(ts_data, true);
if (ret) {
dev_err(dev, "Failed to force flash fw: %d", ret);
ts_data->fw_upgrade_result = false;
} else {
ts_data->fw_upgrade_result = true;
}
ts_data->fw_cfg_uploading = false;
}
mutex_unlock(&ts_data->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)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
int mode = 0, ret;
if (ts_data->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(&ts_data->fw_cfg_mutex);
if (mode == 1) {
ts_data->fw_cfg_uploading = true;
ret = it7260_cfg_upload(ts_data, true);
if (ret) {
dev_err(dev, "Failed to force flash cfg: %d", ret);
ts_data->cfg_upgrade_result = false;
} else {
ts_data->cfg_upgrade_result = true;
}
ts_data->fw_cfg_uploading = false;
}
mutex_unlock(&ts_data->fw_cfg_mutex);
return count;
}
static ssize_t sysfs_force_fw_upgrade_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
return snprintf(buf, MAX_BUFFER_SIZE, "%d", ts_data->fw_upgrade_result);
}
static ssize_t sysfs_force_cfg_upgrade_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
return snprintf(buf, MAX_BUFFER_SIZE, "%d",
ts_data->cfg_upgrade_result);
}
static ssize_t sysfs_calibration_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
return scnprintf(buf, MAX_BUFFER_SIZE, "%d\n",
ts_data->calibration_success);
}
static int it7260_ts_send_calibration_cmd(struct it7260_ts_data *ts_data,
bool auto_tune_on)
{
uint8_t cmd_calibrate[] = {CMD_CALIBRATE, 0,
auto_tune_on ? 1 : 0, 0, 0};
return it7260_i2c_write(ts_data, 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)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
uint8_t resp;
int ret;
ret = it7260_ts_send_calibration_cmd(ts_data, false);
if (ret < 0) {
dev_err(dev, "failed to send calibration command\n");
} else {
ret = it7260_i2c_read(ts_data, BUF_RESPONSE, &resp,
sizeof(resp));
if (ret == IT_I2C_READ_RET)
ts_data->calibration_success = true;
/*
* 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(ts_data,
CMD_FIRMWARE_REINIT_6F) ? "success" : "fail");
}
return count;
}
static ssize_t sysfs_point_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
uint8_t pt_data[sizeof(struct point_data)];
int readSuccess;
ssize_t ret;
readSuccess = it7260_i2c_read_no_ready_check(ts_data, BUF_POINT_INFO,
pt_data, sizeof(pt_data));
if (readSuccess == IT_I2C_READ_RET) {
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, pt_data[0], pt_data[1],
pt_data[2], pt_data[3], pt_data[4],
pt_data[5], pt_data[6], pt_data[7],
pt_data[8], pt_data[9], pt_data[10],
pt_data[11], pt_data[12], pt_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)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
return scnprintf(buf, MAX_BUFFER_SIZE,
"fw{%X.%X.%X.%X} cfg{%X.%X.%X.%X}\n",
ts_data->fw_ver[0], ts_data->fw_ver[1],
ts_data->fw_ver[2], ts_data->fw_ver[3],
ts_data->cfg_ver[0], ts_data->cfg_ver[1],
ts_data->cfg_ver[2], ts_data->cfg_ver[3]);
}
static ssize_t sysfs_sleep_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
/*
* 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 = ts_data->suspended ? '1' : '0';
return 1;
}
static ssize_t sysfs_sleep_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
int go_to_sleep, ret;
ret = kstrtoint(buf, 10, &go_to_sleep);
/* (ts_data->suspended == true && goToSleepVal > 0) means
* device is already suspended and you want it to be in sleep,
* (ts_data->suspended == false && goToSleepVal == 0) means
* device is already active and you also want it to be active.
*/
if ((ts_data->suspended && go_to_sleep > 0) ||
(!ts_data->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(ts_data->client->irq);
it7260_ts_chip_low_power_mode(ts_data, PWR_CTL_SLEEP_MODE);
dev_dbg(dev, "touch is going to sleep...\n");
} else {
it7260_ts_chip_low_power_mode(ts_data, PWR_CTL_ACTIVE_MODE);
enable_irq(ts_data->client->irq);
dev_dbg(dev, "touch is going to wake!\n");
}
ts_data->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)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
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(ts_data->cfg_name, buf, count);
return count;
}
static ssize_t sysfs_cfg_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
if (strnlen(ts_data->cfg_name, MAX_BUFFER_SIZE) > 0)
return scnprintf(buf, MAX_BUFFER_SIZE, "%s\n",
ts_data->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)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
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(ts_data->fw_name, buf, count);
return count;
}
static ssize_t sysfs_fw_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
if (strnlen(ts_data->fw_name, MAX_BUFFER_SIZE) > 0)
return scnprintf(buf, MAX_BUFFER_SIZE, "%s\n",
ts_data->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_ts_release_all(struct it7260_ts_data *ts_data)
{
int finger;
for (finger = 0; finger < ts_data->pdata->num_of_fingers; finger++) {
input_mt_slot(ts_data->input_dev, finger);
input_mt_report_slot_state(ts_data->input_dev,
MT_TOOL_FINGER, 0);
}
input_report_key(ts_data->input_dev, BTN_TOUCH, 0);
input_sync(ts_data->input_dev);
}
static irqreturn_t it7260_ts_threaded_handler(int irq, void *devid)
{
struct point_data pt_data;
struct it7260_ts_data *ts_data = devid;
struct input_dev *input_dev = ts_data->input_dev;
u8 dev_status, finger, touch_count = 0, finger_status;
u8 pressure = FD_PRESSURE_NONE;
u16 x, y;
bool palm_detected;
int ret;
/* verify there is point data to read & it is readable and valid */
ret = it7260_i2c_read_no_ready_check(ts_data, BUF_QUERY, &dev_status,
sizeof(dev_status));
if (ret == IT_I2C_READ_RET)
if (!((dev_status & PT_INFO_BITS) & PT_INFO_YES))
return IRQ_HANDLED;
ret = it7260_i2c_read_no_ready_check(ts_data, BUF_POINT_INFO,
(void *)&pt_data, sizeof(pt_data));
if (ret != IT_I2C_READ_RET) {
dev_err(&ts_data->client->dev,
"failed to read point data buffer\n");
return IRQ_HANDLED;
}
/* Check if controller moves from idle to active state */
if ((pt_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 ((pt_data.flags & PD_FLAGS_DATA_TYPE_BITS) ==
PD_FLAGS_IDLE_TO_ACTIVE &&
pt_data.gesture_id == 0) {
pm_stay_awake(&ts_data->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(&ts_data->work_pm_relax);
} else {
dev_dbg(&ts_data->client->dev,
"Ignore the touch data\n");
}
return IRQ_HANDLED;
}
/*
* Check if touch data also includes any palm gesture or not.
* If palm gesture is detected, then send the keycode parsed
* from the DT.
*/
palm_detected = pt_data.gesture_id & PD_PALM_FLAG_BIT;
if (palm_detected && ts_data->pdata->palm_detect_en) {
input_report_key(input_dev,
ts_data->pdata->palm_detect_keycode, 1);
input_sync(input_dev);
input_report_key(input_dev,
ts_data->pdata->palm_detect_keycode, 0);
input_sync(input_dev);
}
for (finger = 0; finger < ts_data->pdata->num_of_fingers; finger++) {
finger_status = pt_data.flags & (0x01 << finger);
input_mt_slot(input_dev, finger);
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
finger_status != 0);
x = pt_data.fd[finger].xLo +
(((u16)(pt_data.fd[finger].hi & 0x0F)) << 8);
y = pt_data.fd[finger].yLo +
(((u16)(pt_data.fd[finger].hi & 0xF0)) << 4);
pressure = pt_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)
{
struct it7260_ts_data *ts_data = container_of(work,
struct it7260_ts_data, work_pm_relax);
pm_relax(&ts_data->client->dev);
}
static int it7260_ts_chip_identify(struct it7260_ts_data *ts_data)
{
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,};
int ret;
/*
* Sometimes, the controller may not respond immediately after
* writing the command, so wait for device to get ready.
* FALSE means to retry 20 times at max to read the chip status.
* TRUE means to add delay in each retry.
*/
ret = it7260_wait_device_ready(ts_data, false, true);
if (ret < 0) {
dev_err(&ts_data->client->dev,
"failed to read chip status %d\n", ret);
return ret;
}
ret = it7260_i2c_write_no_ready_check(ts_data, BUF_COMMAND, cmd_ident,
sizeof(cmd_ident));
if (ret != IT_I2C_WRITE_RET) {
dev_err(&ts_data->client->dev,
"failed to write CMD_IDENT_CHIP %d\n", ret);
return ret;
}
/*
* Sometimes, the controller may not respond immediately after
* writing the command, so wait for device to get ready.
* TRUE means to retry 500 times at max to read the chip status.
* FALSE means to avoid unnecessary delays in each retry.
*/
ret = it7260_wait_device_ready(ts_data, true, false);
if (ret < 0) {
dev_err(&ts_data->client->dev,
"failed to read chip status %d\n", ret);
return ret;
}
ret = it7260_i2c_read_no_ready_check(ts_data, BUF_RESPONSE, chip_id,
sizeof(chip_id));
if (ret != IT_I2C_READ_RET) {
dev_err(&ts_data->client->dev,
"failed to read chip-id %d\n", ret);
return ret;
}
dev_info(&ts_data->client->dev,
"it7260_ts_chip_identify 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 -EINVAL;
if (chip_id[8] == '5' && chip_id[9] == '6')
dev_info(&ts_data->client->dev, "rev BX3 found\n");
else if (chip_id[8] == '6' && chip_id[9] == '6')
dev_info(&ts_data->client->dev, "rev BX4 found\n");
else
dev_info(&ts_data->client->dev, "unknown revision (0x%02X 0x%02X) found\n",
chip_id[8], chip_id[9]);
return 0;
}
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(struct it7260_ts_data *ts_data, bool on)
{
int retval;
if (on == false)
goto hw_shutdown;
ts_data->vdd = devm_regulator_get(&ts_data->client->dev, "vdd");
if (IS_ERR(ts_data->vdd)) {
dev_err(&ts_data->client->dev,
"%s: Failed to get vdd regulator\n", __func__);
return PTR_ERR(ts_data->vdd);
}
if (regulator_count_voltages(ts_data->vdd) > 0) {
retval = regulator_set_voltage(ts_data->vdd,
IT_VTG_MIN_UV, IT_VTG_MAX_UV);
if (retval) {
dev_err(&ts_data->client->dev,
"regulator set_vtg failed retval =%d\n",
retval);
goto err_set_vtg_vdd;
}
}
ts_data->avdd = devm_regulator_get(&ts_data->client->dev, "avdd");
if (IS_ERR(ts_data->avdd)) {
dev_err(&ts_data->client->dev,
"%s: Failed to get i2c regulator\n", __func__);
retval = PTR_ERR(ts_data->avdd);
goto err_get_vtg_i2c;
}
if (regulator_count_voltages(ts_data->avdd) > 0) {
retval = regulator_set_voltage(ts_data->avdd,
IT_I2C_VTG_MIN_UV, IT_I2C_VTG_MAX_UV);
if (retval) {
dev_err(&ts_data->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(ts_data->vdd) > 0)
regulator_set_voltage(ts_data->vdd, 0, IT_VTG_MAX_UV);
err_set_vtg_vdd:
return retval;
hw_shutdown:
if (regulator_count_voltages(ts_data->vdd) > 0)
regulator_set_voltage(ts_data->vdd, 0, IT_VTG_MAX_UV);
if (regulator_count_voltages(ts_data->avdd) > 0)
regulator_set_voltage(ts_data->avdd, 0, IT_I2C_VTG_MAX_UV);
return 0;
};
static int it7260_power_on(struct it7260_ts_data *ts_data, bool on)
{
int retval;
if (on == false)
goto power_off;
retval = reg_set_optimum_mode_check(ts_data->vdd,
IT_ACTIVE_LOAD_UA);
if (retval < 0) {
dev_err(&ts_data->client->dev,
"Regulator vdd set_opt failed rc=%d\n",
retval);
return retval;
}
retval = regulator_enable(ts_data->vdd);
if (retval) {
dev_err(&ts_data->client->dev,
"Regulator vdd enable failed rc=%d\n",
retval);
goto error_reg_en_vdd;
}
retval = reg_set_optimum_mode_check(ts_data->avdd,
IT_I2C_ACTIVE_LOAD_UA);
if (retval < 0) {
dev_err(&ts_data->client->dev,
"Regulator avdd set_opt failed rc=%d\n",
retval);
goto error_reg_opt_i2c;
}
retval = regulator_enable(ts_data->avdd);
if (retval) {
dev_err(&ts_data->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(ts_data->avdd, 0);
error_reg_opt_i2c:
regulator_disable(ts_data->vdd);
error_reg_en_vdd:
reg_set_optimum_mode_check(ts_data->vdd, 0);
return retval;
power_off:
reg_set_optimum_mode_check(ts_data->vdd, 0);
regulator_disable(ts_data->vdd);
reg_set_optimum_mode_check(ts_data->avdd, 0);
regulator_disable(ts_data->avdd);
return 0;
}
static int it7260_gpio_configure(struct it7260_ts_data *ts_data, bool on)
{
int retval = 0;
if (on) {
if (gpio_is_valid(ts_data->pdata->irq_gpio)) {
/* configure touchscreen irq gpio */
retval = gpio_request(ts_data->pdata->irq_gpio,
"ite_irq_gpio");
if (retval) {
dev_err(&ts_data->client->dev,
"unable to request irq gpio [%d]\n",
retval);
goto err_irq_gpio_req;
}
retval = gpio_direction_input(ts_data->pdata->irq_gpio);
if (retval) {
dev_err(&ts_data->client->dev,
"unable to set direction for irq gpio [%d]\n",
retval);
goto err_irq_gpio_dir;
}
} else {
dev_err(&ts_data->client->dev,
"irq gpio not provided\n");
goto err_irq_gpio_req;
}
if (gpio_is_valid(ts_data->pdata->reset_gpio)) {
/* configure touchscreen reset out gpio */
retval = gpio_request(ts_data->pdata->reset_gpio,
"ite_reset_gpio");
if (retval) {
dev_err(&ts_data->client->dev,
"unable to request reset gpio [%d]\n",
retval);
goto err_reset_gpio_req;
}
retval = gpio_direction_output(
ts_data->pdata->reset_gpio, 1);
if (retval) {
dev_err(&ts_data->client->dev,
"unable to set direction for reset gpio [%d]\n",
retval);
goto err_reset_gpio_dir;
}
if (ts_data->pdata->low_reset)
gpio_set_value(ts_data->pdata->reset_gpio, 0);
else
gpio_set_value(ts_data->pdata->reset_gpio, 1);
msleep(ts_data->pdata->reset_delay);
} else {
dev_err(&ts_data->client->dev,
"reset gpio not provided\n");
goto err_reset_gpio_req;
}
} else {
if (gpio_is_valid(ts_data->pdata->irq_gpio))
gpio_free(ts_data->pdata->irq_gpio);
if (gpio_is_valid(ts_data->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(
ts_data->pdata->reset_gpio);
if (retval) {
dev_err(&ts_data->client->dev,
"unable to set direction for gpio reset [%d]\n",
retval);
}
gpio_free(ts_data->pdata->reset_gpio);
}
}
return 0;
err_reset_gpio_dir:
if (gpio_is_valid(ts_data->pdata->reset_gpio))
gpio_free(ts_data->pdata->reset_gpio);
err_reset_gpio_req:
err_irq_gpio_dir:
if (gpio_is_valid(ts_data->pdata->irq_gpio))
gpio_free(ts_data->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 it7260_ts_data *ts_data = dev_get_drvdata(dev);
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(ts_data->fw_name, MAX_BUFFER_SIZE, "%s",
(pdata->fw_name != NULL) ? pdata->fw_name : FW_NAME);
snprintf(ts_data->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;
}
rc = of_property_read_u32(np, "ite,avdd-lpm-cur", &temp_val);
if (!rc) {
pdata->avdd_lpm_cur = temp_val;
} else if (rc && (rc != -EINVAL)) {
dev_err(dev, "Unable to read avdd lpm current value %d\n", rc);
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_data *ts_data;
struct it7260_ts_platform_data *pdata;
uint8_t rsp[2];
int ret = -1, err;
struct dentry *temp;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_err(&client->dev, "need I2C_FUNC_I2C\n");
return -ENODEV;
}
ts_data = devm_kzalloc(&client->dev, sizeof(*ts_data), GFP_KERNEL);
if (!ts_data)
return -ENOMEM;
ts_data->client = client;
i2c_set_clientdata(client, ts_data);
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) {
dev_err(&client->dev, "No platform data found\n");
return -ENOMEM;
}
ts_data->pdata = pdata;
ret = it7260_regulator_configure(ts_data, true);
if (ret < 0) {
dev_err(&client->dev, "Failed to configure regulators\n");
goto err_reg_configure;
}
ret = it7260_power_on(ts_data, true);
if (ret < 0) {
dev_err(&client->dev, "Failed to power on\n");
goto err_power_device;
}
/*
* After enabling regulators, controller needs a delay to come to
* an active state.
*/
msleep(DELAY_VTG_REG_EN);
ret = it7260_ts_pinctrl_init(ts_data);
if (!ret && ts_data->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(ts_data->ts_pinctrl,
ts_data->pinctrl_state_active);
if (ret < 0) {
dev_err(&ts_data->client->dev,
"failed to select pin to active state %d",
ret);
}
} else {
ret = it7260_gpio_configure(ts_data, true);
if (ret < 0) {
dev_err(&client->dev, "Failed to configure gpios\n");
goto err_gpio_config;
}
}
ret = it7260_ts_chip_identify(ts_data);
if (ret) {
dev_err(&client->dev, "Failed to identify chip %d!!!", ret);
goto err_identification_fail;
}
it7260_get_chip_versions(ts_data);
ts_data->input_dev = input_allocate_device();
if (!ts_data->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(&ts_data->fw_cfg_mutex);
ts_data->input_dev->name = DEVICE_NAME;
ts_data->input_dev->phys = "I2C";
ts_data->input_dev->id.bustype = BUS_I2C;
ts_data->input_dev->id.vendor = 0x0001;
ts_data->input_dev->id.product = 0x7260;
set_bit(EV_SYN, ts_data->input_dev->evbit);
set_bit(EV_KEY, ts_data->input_dev->evbit);
set_bit(EV_ABS, ts_data->input_dev->evbit);
set_bit(INPUT_PROP_DIRECT, ts_data->input_dev->propbit);
set_bit(BTN_TOUCH, ts_data->input_dev->keybit);
input_set_abs_params(ts_data->input_dev, ABS_MT_POSITION_X,
ts_data->pdata->disp_minx, ts_data->pdata->disp_maxx, 0, 0);
input_set_abs_params(ts_data->input_dev, ABS_MT_POSITION_Y,
ts_data->pdata->disp_miny, ts_data->pdata->disp_maxy, 0, 0);
input_mt_init_slots(ts_data->input_dev,
ts_data->pdata->num_of_fingers, 0);
input_set_drvdata(ts_data->input_dev, ts_data);
if (pdata->wakeup) {
set_bit(KEY_WAKEUP, ts_data->input_dev->keybit);
INIT_WORK(&ts_data->work_pm_relax, it7260_ts_work_func);
device_init_wakeup(&client->dev, pdata->wakeup);
}
if (pdata->palm_detect_en)
set_bit(ts_data->pdata->palm_detect_keycode,
ts_data->input_dev->keybit);
if (input_register_device(ts_data->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, ts_data)) {
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)
ts_data->fb_notif.notifier_call = fb_notifier_callback;
ret = fb_register_client(&ts_data->fb_notif);
if (ret)
dev_err(&client->dev, "Unable to register fb_notifier %d\n",
ret);
#endif
it7260_i2c_write_no_ready_check(ts_data, BUF_COMMAND, cmd_start,
sizeof(cmd_start));
msleep(pdata->reset_delay);
it7260_i2c_read_no_ready_check(ts_data, BUF_RESPONSE, rsp, sizeof(rsp));
msleep(pdata->reset_delay);
ts_data->dir = debugfs_create_dir(DEBUGFS_DIR_NAME, NULL);
if (ts_data->dir == NULL || IS_ERR(ts_data->dir)) {
dev_err(&client->dev,
"%s: Failed to create debugfs directory, ret = %ld\n",
__func__, PTR_ERR(ts_data->dir));
ret = PTR_ERR(ts_data->dir);
goto err_create_debugfs_dir;
}
temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, ts_data->dir,
ts_data, &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(ts_data->dir);
err_create_debugfs_dir:
#if defined(CONFIG_FB)
if (fb_unregister_client(&ts_data->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, ts_data);
err_irq_reg:
input_unregister_device(ts_data->input_dev);
err_input_register:
if (pdata->wakeup) {
cancel_work_sync(&ts_data->work_pm_relax);
device_init_wakeup(&client->dev, false);
}
if (ts_data->input_dev)
input_free_device(ts_data->input_dev);
ts_data->input_dev = NULL;
err_input_alloc:
err_identification_fail:
if (ts_data->ts_pinctrl) {
if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) {
devm_pinctrl_put(ts_data->ts_pinctrl);
ts_data->ts_pinctrl = NULL;
} else {
err = pinctrl_select_state(ts_data->ts_pinctrl,
ts_data->pinctrl_state_release);
if (err)
dev_err(&ts_data->client->dev,
"failed to select relase pinctrl state %d\n",
err);
}
} 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(ts_data, false);
err_power_device:
it7260_regulator_configure(ts_data, false);
err_reg_configure:
return ret;
}
static int it7260_ts_remove(struct i2c_client *client)
{
struct it7260_ts_data *ts_data = i2c_get_clientdata(client);
int ret;
debugfs_remove_recursive(ts_data->dir);
#if defined(CONFIG_FB)
if (fb_unregister_client(&ts_data->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, ts_data);
input_unregister_device(ts_data->input_dev);
if (ts_data->input_dev)
input_free_device(ts_data->input_dev);
ts_data->input_dev = NULL;
if (ts_data->pdata->wakeup) {
cancel_work_sync(&ts_data->work_pm_relax);
device_init_wakeup(&client->dev, false);
}
if (ts_data->ts_pinctrl) {
if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) {
devm_pinctrl_put(ts_data->ts_pinctrl);
ts_data->ts_pinctrl = NULL;
} else {
ret = pinctrl_select_state(ts_data->ts_pinctrl,
ts_data->pinctrl_state_release);
if (ret)
dev_err(&ts_data->client->dev,
"failed to select relase pinctrl state %d\n",
ret);
}
} else {
if (gpio_is_valid(ts_data->pdata->reset_gpio))
gpio_free(ts_data->pdata->reset_gpio);
if (gpio_is_valid(ts_data->pdata->irq_gpio))
gpio_free(ts_data->pdata->irq_gpio);
}
it7260_power_on(ts_data, false);
it7260_regulator_configure(ts_data, false);
return 0;
}
#if defined(CONFIG_FB)
static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data)
{
struct it7260_ts_data *ts_data = container_of(self,
struct it7260_ts_data, fb_notif);
struct fb_event *evdata = data;
int *blank;
if (evdata && evdata->data && ts_data && ts_data->client) {
if (event == FB_EVENT_BLANK) {
blank = evdata->data;
if (*blank == FB_BLANK_UNBLANK)
it7260_ts_resume(&(ts_data->client->dev));
else if (*blank == FB_BLANK_POWERDOWN ||
*blank == FB_BLANK_VSYNC_SUSPEND)
it7260_ts_suspend(&(ts_data->client->dev));
}
}
return 0;
}
#endif
#ifdef CONFIG_PM
static int it7260_ts_resume(struct device *dev)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
int retval;
if (device_may_wakeup(dev)) {
if (ts_data->in_low_power_mode) {
/* Set active current for the avdd regulator */
if (ts_data->pdata->avdd_lpm_cur) {
retval = reg_set_optimum_mode_check(
ts_data->avdd,
IT_I2C_ACTIVE_LOAD_UA);
if (retval < 0)
dev_err(dev, "Regulator avdd set_opt failed at resume rc=%d\n",
retval);
}
ts_data->in_low_power_mode = false;
disable_irq_wake(ts_data->client->irq);
}
return 0;
}
if (ts_data->ts_pinctrl) {
retval = pinctrl_select_state(ts_data->ts_pinctrl,
ts_data->pinctrl_state_active);
if (retval < 0) {
dev_err(dev, "Cannot get default pinctrl state %d\n",
retval);
goto err_pinctrl_select_suspend;
}
}
enable_irq(ts_data->client->irq);
ts_data->suspended = false;
return 0;
err_pinctrl_select_suspend:
return retval;
}
static int it7260_ts_suspend(struct device *dev)
{
struct it7260_ts_data *ts_data = dev_get_drvdata(dev);
int retval;
if (ts_data->fw_cfg_uploading) {
dev_dbg(dev, "Fw/cfg uploading. Can't go to suspend.\n");
return -EBUSY;
}
if (device_may_wakeup(dev)) {
if (!ts_data->in_low_power_mode) {
/* put the device in low power idle mode */
retval = it7260_ts_chip_low_power_mode(ts_data,
PWR_CTL_LOW_POWER_MODE);
if (retval)
dev_err(dev, "Can't go to low power mode %d\n",
retval);
/* Set lpm current for avdd regulator */
if (ts_data->pdata->avdd_lpm_cur) {
retval = reg_set_optimum_mode_check(
ts_data->avdd,
ts_data->pdata->avdd_lpm_cur);
if (retval < 0)
dev_err(dev, "Regulator avdd set_opt failed at suspend rc=%d\n",
retval);
}
ts_data->in_low_power_mode = true;
enable_irq_wake(ts_data->client->irq);
}
return 0;
}
disable_irq(ts_data->client->irq);
it7260_ts_release_all(ts_data);
if (ts_data->ts_pinctrl) {
retval = pinctrl_select_state(ts_data->ts_pinctrl,
ts_data->pinctrl_state_suspend);
if (retval < 0) {
dev_err(dev, "Cannot get idle pinctrl state %d\n",
retval);
goto err_pinctrl_select_suspend;
}
}
ts_data->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");