/* 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_BUFFER_SIZE 144 #define DEVICE_NAME "it7259" #define SCREEN_X_RESOLUTION 320 #define SCREEN_Y_RESOLUTION 320 #define DEBUGFS_DIR_NAME "ts_debug" #define FW_NAME "it7259_fw.bin" #define CFG_NAME "it7259_cfg.bin" #define IT7259_CFG_PATH "/persist/it7259.cfg" #define IT7259_FW_PATH "/persist/it7259.fw" #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 it7259_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" int download; #define COMMAND_SUCCESS 0x0000 #define COMMAND_ERROR 0x0200 #define ERROR_QUERY_TIME_OUT 0x0800 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 it7259_ts_platform_data { unsigned int reset_gpio; unsigned int reset_gpio_flags; 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 int num_of_fingers; unsigned int reset_delay; unsigned int avdd_lpm_cur; unsigned int irq_gpio; unsigned int irq_gpio_flags; const char *fw_name; const char *cfg_name; unsigned short palm_detect_keycode; bool low_reset; bool wakeup; bool palm_detect_en; }; struct it7259_ts_data { struct i2c_client *client; struct input_dev *input_dev; const struct it7259_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 it7259_ts_resume(struct device *dev); static int it7259_ts_suspend(struct device *dev); static int it7259_debug_suspend_set(void *_data, u64 val) { struct it7259_ts_data *ts_data = _data; if (val) it7259_ts_suspend(&ts_data->client->dev); else it7259_ts_resume(&ts_data->client->dev); return 0; } static int it7259_debug_suspend_get(void *_data, u64 *val) { struct it7259_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, it7259_debug_suspend_get, it7259_debug_suspend_set, "%lld\n"); /* internal use func - does not make sure chip is ready before read */ static int it7259_i2c_read_no_ready_check(struct it7259_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 it7259_i2c_write_no_ready_check(struct it7259_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 it7259_wait_device_ready(struct it7259_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 = it7259_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 it7259_i2c_write(struct it7259_ts_data *ts_data, uint8_t buf_index, const uint8_t *buffer, uint16_t buf_len) { int ret; ret = it7259_wait_device_ready(ts_data, false, false); if (ret < 0) return ret; return it7259_i2c_write_no_ready_check(ts_data, buf_index, buffer, buf_len); } #ifdef CONFIG_PM static int it7259_ts_chip_low_power_mode(struct it7259_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 = it7259_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 = it7259_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; } #endif static int i2cInternalWriteToIT7259(struct it7259_ts_data *ts_data, int wAddress, unsigned char const dataBuffer[], unsigned short dataLength) { unsigned char buffer4Write[1024] = {0}; struct i2c_msg msgs[1] = { { .addr = ts_data->client->addr, .flags = 0, .len = dataLength + 3, .buf = buffer4Write } }; //printk("====in internal write function===\n"); buffer4Write[0] = 0x70; buffer4Write[1] = (unsigned char)(wAddress & 0xFF); memcpy(&(buffer4Write[2]), dataBuffer, dataLength); return i2c_transfer(ts_data->client->adapter, msgs, 1); } static int i2cDirectReadFromIT7259(struct it7259_ts_data *ts_data, int wAddress, unsigned char readDataBuffer[], unsigned short readDataLength) { int ret; unsigned char buffer4Write[1024] = {0}; struct i2c_msg msgs[2] = { { .addr = ts_data->client->addr, .flags = 0, .len = 4, .buf = buffer4Write }, { .addr = ts_data->client->addr, .flags = I2C_M_RD, .len = readDataLength, .buf = readDataBuffer } }; //printk("====in Direct read function===\n"); buffer4Write[0] = 0x90; buffer4Write[1] = 0x00; buffer4Write[2] = (unsigned char)((wAddress & 0xFF00) >> 8); buffer4Write[3] = (unsigned char)(wAddress & 0xFF); memset(readDataBuffer, 0xFF, readDataLength); ret = i2c_transfer(ts_data->client->adapter, msgs, 2); return ret; } static int i2cDirectWriteToIT7259(struct it7259_ts_data *ts_data, int wAddress, unsigned char const dataBuffer[], unsigned short dataLength) { unsigned char buffer4Write[1024] = {0}; int nRetryCount = 0; int nRet = 0; struct i2c_msg msgs[1] = { { .addr = ts_data->client->addr, .flags = 0, .len = dataLength + 4, .buf = buffer4Write } }; //printk("====in Direct write function===\n"); buffer4Write[0] = 0x10; buffer4Write[1] = 0x00; buffer4Write[2] = (unsigned char)((wAddress & 0xFF00) >> 8); buffer4Write[3] = (unsigned char)(wAddress & 0xFF); memcpy(&(buffer4Write[4]), dataBuffer, dataLength); do { nRet = i2c_transfer(ts_data->client->adapter, msgs, 1); } while ((nRet <= 0) && (nRetryCount++ < 10)); return nRet; } static bool gfnIT7259_SPIFCRReady(struct it7259_ts_data *ts_data) { int nReadCount = 0; unsigned char ucBuffer[2] = {0}; do { i2cDirectReadFromIT7259(ts_data, 0xF400, ucBuffer, 2);//gfnIT7259_DirectReadMemoryRegister } while (((ucBuffer[1] & 0x01) != 0x00) && ++nReadCount < 20); //nReadCount 3000 if (nReadCount >= 20) //nReadCount 3000 return false; return true; } static int gfnIT7259_DirectReadFlash(struct it7259_ts_data *ts_data, int wFlashAddress, unsigned int readLength, unsigned char *pData) { int nSector = 0; unsigned char pucCommandBuffer[1024] = {0}; int wTmp; int wAddress; unsigned int /*AddrOffset, */LenOffset; unsigned char bufTemp[4] = {0}; int wOffset; int i; nSector = wFlashAddress/0x0400; pucCommandBuffer[0] = nSector; //Select Sector wAddress = 0xF404; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 1); if (wTmp <= 0) { return COMMAND_ERROR; } //Wait SPIFCR if (!gfnIT7259_SPIFCRReady(ts_data)) { return ERROR_QUERY_TIME_OUT; } //Read flash wOffset = wFlashAddress - (nSector*0x0400); wAddress = 0x3000 + wOffset; //printk("======= gfnIT7259_DirectReadFlash 8 byte limit =======\n"); for (LenOffset = 0; LenOffset < readLength; LenOffset += 4) { wTmp = i2cDirectReadFromIT7259(ts_data, wAddress, bufTemp, 4); if (wTmp <= 0) { return COMMAND_ERROR; } for (i = 0; i < 4; i++) { pucCommandBuffer[LenOffset + i] = bufTemp[i] ; } wAddress = wAddress + 4; } //Wait SPIFCR if (!gfnIT7259_SPIFCRReady(ts_data)) { return ERROR_QUERY_TIME_OUT; } memcpy((unsigned char *)pData, pucCommandBuffer, readLength * sizeof(unsigned char)); return COMMAND_SUCCESS; } static int i2cInternalReadFromIT7259(struct it7259_ts_data *ts_data, int wAddress, unsigned char readDataBuffer[], unsigned short readDataLength) { int ret; unsigned char buffer4Write[1024] = {0}; struct i2c_msg msgs[2] = { { .addr = ts_data->client->addr, .flags = 0, .len = 2, .buf = buffer4Write }, { .addr = ts_data->client->addr, .flags = I2C_M_RD, .len = readDataLength, .buf = readDataBuffer } }; //printk("====in internal read function===\n"); buffer4Write[0] = 0x70; buffer4Write[1] = (unsigned char)(wAddress & 0xFF); memset(readDataBuffer, 0xFF, readDataLength); ret = i2c_transfer(ts_data->client->adapter, msgs, 2); return ret; } static int gfnIT7259_DirectEraseFlash(struct it7259_ts_data *ts_data, unsigned char ucEraseType, int wFlashAddress) { int nSector = 0; unsigned char pucCommandBuffer[1024]; int wTmp; int wAddress; nSector = wFlashAddress/0x0400; pucCommandBuffer[0] = nSector; //Select Sector wAddress = 0xF404; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 1); if (wTmp <= 0) { return COMMAND_ERROR; } //Wait SPIFCR if (!gfnIT7259_SPIFCRReady(ts_data)) { return ERROR_QUERY_TIME_OUT; } //Read flash wAddress = 0xF402; pucCommandBuffer[0] = ucEraseType; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 1); //Wait SPIFCR if (!gfnIT7259_SPIFCRReady(ts_data)) { return ERROR_QUERY_TIME_OUT; } return COMMAND_SUCCESS; } static int gfnIT7259_DMAModeWriteFlash(struct it7259_ts_data *ts_data, int wFlashAddress, int wSRAMAddress, unsigned int dataLength, unsigned char *pData, bool bPollingWait) { int nSector = 0; int wAddress; int wTmp; int i; unsigned char pucCommandBuffer[1024]; unsigned char pucReadData[2]; unsigned int LenOffset; unsigned char bufTemp[4]; unsigned int wStartAddress; //write to address 0x0000 (SRAM only 6K) memset(bufTemp, 0xFF, 4); //for 8 byte limit wAddress = wSRAMAddress; printk("###write to address 0x0000 (wSRAMAddress = %04x, dataLength = %02x)\n", wSRAMAddress, dataLength); for (LenOffset = 0; LenOffset < dataLength; LenOffset += 4) { for (i = 0; i < 4; i++) { bufTemp[i] = pData[LenOffset + i]; } wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, bufTemp, 4); if (wTmp <= 0) { //printk("###write to address 0x0000 fail!\n"); return COMMAND_ERROR; } wAddress = wAddress + 4; //printk(" ======== wAddress = %04x , LenOffset = %02x ========\n",wAddress,LenOffset); } //Select Sector memset(pucCommandBuffer, 0xFF, 1024); nSector = wFlashAddress/0x0400; pucCommandBuffer[0] = (unsigned char)(nSector & 0xFF); wAddress = 0xF404; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 1);//DirectWriteMemoryRegister if (wTmp <= 0) { printk("###Select Sector fail!"); return COMMAND_ERROR; } //Wait SPIFCR //printk("###Wait SPIFCR\n"); if (!gfnIT7259_SPIFCRReady(ts_data)) { return ERROR_QUERY_TIME_OUT; } //Write Flash strat address //printk("###Write Flash strat address\n"); memset(pucCommandBuffer, 0xFF, 1024); wAddress = 0xF41A; wStartAddress = wFlashAddress - (nSector*0x0400); pucCommandBuffer[0] = wStartAddress & 0x00FF; pucCommandBuffer[1] = (wStartAddress & 0xFF00) >> 8 ; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 2);//DirectWriteMemoryRegister if (wTmp <= 0) { printk("###Write Flash strat address fail!\n"); return COMMAND_ERROR; } //Write SARM strat address wAddress = 0xF41C; memset(pucCommandBuffer, 0xFF, 1024); pucCommandBuffer[0] = wSRAMAddress & 0xFF; pucCommandBuffer[1] = (wSRAMAddress & 0xFF00) >> 8; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 2);//DirectWriteMemoryRegister if (wTmp <= 0) { printk("###Write SARM strat address fail!\n"); return COMMAND_ERROR; } //write DMA transfer length wAddress = 0xF41E; pucCommandBuffer[0] = dataLength & 0xFF; pucCommandBuffer[1] = (dataLength & 0xFF00) >> 8 ; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 2);//DirectWriteMemoryRegister if (wTmp <= 0) { printk("###write DMA transfer length fail!\n"); return COMMAND_ERROR; } //Write DMA_DIR and DMAEN wAddress = 0xF418; pucCommandBuffer[0] = 0x0B; //auto erase pucCommandBuffer[1] = 0x00; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 2);//DirectWriteMemoryRegister if (wTmp <= 0) { printk("###Write DMA_DIR and DMAEN fail!\n"); return COMMAND_ERROR; } if (bPollingWait) { //polling bit 0, until value of bit 0 = 0 wAddress = 0xF418; do { wTmp = i2cDirectReadFromIT7259(ts_data, wAddress, pucReadData, 2);//gfnIT7259_DirectReadMemoryRegister if (wTmp <= 0) { break; return COMMAND_ERROR; } } while ((pucReadData[0] & 0x01) != 0x00); //Wait SPIFCR if (!gfnIT7259_SPIFCRReady(ts_data)) { return ERROR_QUERY_TIME_OUT; } } return COMMAND_SUCCESS; } static unsigned int gfnIT7259_GetFWSize(struct it7259_ts_data *ts_data) { int wAddress; unsigned char arucBuffer[1024]; unsigned int unRet = 0; printk("###Entry gfnIT7259_GetFWSize()\n"); wAddress = 0; gfnIT7259_DirectReadFlash(ts_data, wAddress, 0x0400, arucBuffer); unRet = arucBuffer[0x80+12] + (arucBuffer[0x80+13] << 8); return unRet; } static bool gfnIT7259_SwitchCPUClock(struct it7259_ts_data *ts_data, unsigned char ucMode) { unsigned char ucCommandBuffer[1]; unsigned char ucRetCommandBuffer[1]; int nErrCount = 0; int dwAddress = 0x0023; ucCommandBuffer[0] = ucMode; do { i2cInternalWriteToIT7259(ts_data, dwAddress, ucCommandBuffer, 1); i2cInternalReadFromIT7259(ts_data, dwAddress, ucRetCommandBuffer, 1); nErrCount++; } while (((ucRetCommandBuffer[0] & 0x0F) != ucMode) && nErrCount <= 1000); if (nErrCount > 1000) { return false; } return true; } static int gfnIT7259_DirectWriteFlash(struct it7259_ts_data *ts_data, int wFlashAddress, unsigned int wWriteLength, unsigned char *pData) { //printk("###Entry gfnIT7259_DirectWriteFlash()\n"); //struct IT7259_ts_data *ts = gl_ts; //struct it7259_ts_data *ts_data = dev_get_drvdata(dev); int nSector = 0; unsigned char pucCommandBuffer[1024]; int wTmp; int wAddress; int wOffset; nSector = wFlashAddress/0x0400; pucCommandBuffer[0] = nSector; //Select Sector wAddress = 0xF404; wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, 1); if (wTmp <= 0) { return COMMAND_ERROR; } //Wait SPIFCR if (!gfnIT7259_SPIFCRReady(ts_data)) { return ERROR_QUERY_TIME_OUT; } //write flash wOffset = wFlashAddress - (nSector*0x0400); wAddress = 0x3000 + wOffset; memcpy(pucCommandBuffer, (unsigned char *)pData, wWriteLength * sizeof(unsigned char)); //wTmp = gfnIT7259_DirectWriteMemoryRegister(0x01,wAddress,0x0000,wWriteLength, pucCommandBuffer); wTmp = i2cDirectWriteToIT7259(ts_data, wAddress, pucCommandBuffer, wWriteLength); if (wTmp <= 0) { return COMMAND_ERROR; } //Wait SPIFCR if (!gfnIT7259_SPIFCRReady(ts_data)) { return ERROR_QUERY_TIME_OUT; } return COMMAND_SUCCESS; } static bool gfnIT7259_FirmwareDownload(struct it7259_ts_data *ts_data, unsigned int unFirmwareLength, unsigned char arucFW[], unsigned int unConfigLength, unsigned char arucConfig[]) { int dwAddress = 0; unsigned char RetDATABuffer[10] = {0}; unsigned char DATABuffer[10] = {0}; int nSector = 0; unsigned int nFillSize = 0; int wTmp = 0; unsigned int unTmp = 0; unsigned int nConfigSize = 0; unsigned long dwFlashSize = 0x10000; unsigned int nEndFwSector = 0; unsigned int nStartCFGSector = 0; unsigned char putFWBuffer[1024]; int wAddress = 0; int wRemainderFWAddress = 0; int wConfigAddress = 0; unsigned int nRemainderFwSize = 0; unsigned int i = 0; int nConfigCount = 0; int nSize = 0; int Tmp = 0; if ((unFirmwareLength == 0) && (unConfigLength == 0)) { printk("XXX %s, %d\n", __FUNCTION__, __LINE__); return false; } //trun off CPU data clock if (!gfnIT7259_SwitchCPUClock(ts_data, 0x01)) { printk("###002 gfnIT7259_SwitchCPUClock(0x01) fail!\n"); return false; } //Wait SPIFCR //printk("###003 Wait SPIFCR\n"); dwAddress = 0xF400; do { i2cDirectReadFromIT7259(ts_data, dwAddress, RetDATABuffer, 2); } while ((RetDATABuffer[1] & 0x01) != 0x00); //printk("###003 End SPIFCR\n"); //Erase signature //printk("###004 Erase signature\n"); dwAddress = 0xF404; DATABuffer[0] = 0x3F; i2cDirectWriteToIT7259(ts_data, dwAddress, DATABuffer, 1); dwAddress = 0xF402; DATABuffer[0] = 0xD7; i2cDirectWriteToIT7259(ts_data, dwAddress, DATABuffer, 1); //Wait SPIFCR //printk("###005 Wait SPIFCR\n"); dwAddress = 0xF400; do { i2cDirectReadFromIT7259(ts_data, dwAddress, RetDATABuffer, 2); } while ((RetDATABuffer[1] & 0x01) != 0x00); //printk("###005 End SPIFCR\n"); if ((download == 2) || (download == 3)) { //Download FW printk("###006 Download FW\n"); for (i = 0; i < unFirmwareLength; i += 0x0400) { if ((unFirmwareLength - i) >= 0x0400)//0x0400 nFillSize = 0x0400;//0x0400 else nFillSize = unFirmwareLength - i; Tmp = gfnIT7259_DMAModeWriteFlash(ts_data, i, 0x0000, nFillSize, arucFW+i, true); mdelay(100);//for test if (wTmp != COMMAND_SUCCESS) { //Write Firmware Flash error printk("###DMA ModeWrite Firmware Flash error(FlashAddress:%04x)\n", i); return false; } } //3. Fw CRC Check //check FW CRC //printk("###007 check FW CRC\n"); //write start address dwAddress = 0xF40A; DATABuffer[0] = 0x00; DATABuffer[1] = 0x00; i2cDirectWriteToIT7259(ts_data, dwAddress, DATABuffer, 2); //write end address dwAddress = 0xF40C; DATABuffer[0] = (unFirmwareLength-3) & 0x00ff; DATABuffer[1] = ((unFirmwareLength-3) & 0xff00) >> 8; i2cDirectWriteToIT7259(ts_data, dwAddress, DATABuffer, 2); //write CRCCR dwAddress = 0xF408; DATABuffer[0] = 0x01 ; i2cDirectWriteToIT7259(ts_data, dwAddress, DATABuffer, 1); //wait CRCCR dwAddress = 0xF408; do { i2cDirectReadFromIT7259(ts_data, dwAddress, RetDATABuffer, 2); } while ((RetDATABuffer[0] & 0x01) != 0x00); //read CRC dwAddress = 0xF40E; i2cDirectReadFromIT7259(ts_data, dwAddress, RetDATABuffer, 2); //compare FW CRC //printk("###008 compare FW CRC\n"); if (RetDATABuffer[0] != arucFW[unFirmwareLength - 2] || RetDATABuffer[1] != arucFW[unFirmwareLength - 1]) { printk("###008 FW CRC check fail\n"); printk("RetDATABuffer[0]:%02x,RetDATABuffer[1]:%02x,FW[Length-2]:%02x,FW[Length-1]:%02x\n", RetDATABuffer[0], RetDATABuffer[1], arucFW[unFirmwareLength - 2], arucFW[unFirmwareLength - 1]); return false;//FW CRC check fail } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if ((download == 1) || (download == 3)) { //download config printk("###009 start to download config\n"); unTmp = gfnIT7259_GetFWSize(ts_data); nConfigSize = unConfigLength; //3.7 get address for writing config (in flash) //check whether fw and config are in the same sector or not //set flash size //dwFlashSize = 0x10000; nEndFwSector = (unTmp - 1) / 1024; nStartCFGSector = 62 - (unConfigLength - 1)/1024; nRemainderFwSize = 0; if (nEndFwSector == nStartCFGSector) { nRemainderFwSize = unTmp - nEndFwSector*1024; wAddress = nEndFwSector*0x0400; //printk(" =========== nRemainderFwSize = %4x ===========\n",nRemainderFwSize); gfnIT7259_DirectReadFlash(ts_data, wAddress, nRemainderFwSize, putFWBuffer); } //get config start address wTmp = dwFlashSize - 1024 - unConfigLength; //printk("###010 get config start address(%04x)\n",wTmp); for (i = wTmp; i < (dwFlashSize - 1024); i += 0x0400) { nSector = i/0x0400; if ((nRemainderFwSize != 0) && (nSector == nStartCFGSector)) { wRemainderFWAddress = nStartCFGSector*0x0400; nFillSize = nRemainderFwSize; gfnIT7259_DMAModeWriteFlash(ts_data, wRemainderFWAddress, 0x0000, nFillSize, putFWBuffer, true); } //write config nSize = (unConfigLength - (62 - nSector)*1024); if (nSize >= 1024) { wConfigAddress = nSector * 0x0400; nFillSize = 1024; } else { wConfigAddress = i; nFillSize = nSize; } wTmp = gfnIT7259_DMAModeWriteFlash(ts_data, wConfigAddress, 0x0000, nFillSize, arucConfig + nConfigCount, true); if (wTmp != COMMAND_SUCCESS) return false; nConfigCount += nFillSize; } //Config CRC Check //printk("###011 Config CRC Check\n"); //write start address dwAddress = 0xF40A; DATABuffer[0] = (0x10000 - unConfigLength - 1024) & 0x00ff; DATABuffer[1] = ((0x10000 - unConfigLength - 1024) & 0xff00) >> 8; i2cDirectWriteToIT7259(ts_data, dwAddress, DATABuffer, 2); //write end address dwAddress = 0xF40C; DATABuffer[0] = (0x10000 - 1024 - 3) & 0x00ff; DATABuffer[1] = ((0x10000 - 1024 - 3) & 0xff00) >> 8; i2cDirectWriteToIT7259(ts_data, dwAddress, DATABuffer, 2); //write CRCCR dwAddress = 0xF408; DATABuffer[0] = 0x01 ; i2cDirectWriteToIT7259(ts_data, dwAddress, DATABuffer, 1); //wait CRCCR dwAddress = 0xF408; do { i2cDirectReadFromIT7259(ts_data, dwAddress, RetDATABuffer, 2); } while ((RetDATABuffer[0] & 0x01) != 0x00); //read CRC dwAddress = 0xF40E; i2cDirectReadFromIT7259(ts_data, dwAddress, RetDATABuffer, 2); //compare Config CRC if ((RetDATABuffer[0] != arucConfig[unConfigLength - 2]) || (RetDATABuffer[1] != arucConfig[unConfigLength - 1])) { printk("###011 config CRC Check Error\n"); printk("RetDATABuffer[0]:%02x,RetDATABuffer[1]:%02x,CFG[Length-2]:%02x,CFG[Length-1]:%02x\n", RetDATABuffer[0], RetDATABuffer[1], arucConfig[unConfigLength - 2], arucConfig[unConfigLength - 1]); return false;//config CRC Check Error } } //write signature DATABuffer[0] = 0x57; DATABuffer[1] = 0x72; gfnIT7259_DirectEraseFlash(ts_data, 0xD7, (dwFlashSize - 1024)); gfnIT7259_DirectWriteFlash(ts_data, (dwFlashSize - 1024), 2, DATABuffer); DATABuffer[0] = 0x00; DATABuffer[1] = 0x00; i2cDirectReadFromIT7259(ts_data, dwAddress, DATABuffer, 2); //trun on CPU data clock //printk("###012 trun on CPU data clock\n"); if (!gfnIT7259_SwitchCPUClock(ts_data, 0x04)) { printk("###012 trun on CPU data clock fail\n"); return false; } printk("###gfnIT7259_FirmwareDownload() end.\n"); return true; } static int Upgrade_FW_CFG(struct it7259_ts_data *ts_data) { unsigned int fw_size = 0; unsigned int config_size = 0; struct file *fw_fd = NULL; struct file *config_fd = NULL; mm_segment_t fs; unsigned char *fw_buf = kzalloc(0x10000, GFP_KERNEL); unsigned char *config_buf = kzalloc(0x500, GFP_KERNEL); printk(KERN_ERR"Execute Upgrade_FW_CFG()\n"); if (fw_buf == NULL || config_buf == NULL) { printk("kzalloc failed\n"); } fs = get_fs(); set_fs(get_ds()); //load fw file fw_fd = filp_open(IT7259_FW_PATH, O_RDONLY, 0); if (fw_fd < 0) { printk("open %s failed \n", IT7259_FW_PATH); return 1; } fw_size = fw_fd->f_op->read(fw_fd, fw_buf, 0x10000, &fw_fd->f_pos); printk(KERN_ERR "File Firmware version : %02x %02x %02x %02x\n", fw_buf[136], fw_buf[137], fw_buf[138], fw_buf[139]); //printk("--------------------- fw_size = %x\n", fw_size); //load config file config_fd = filp_open(IT7259_CFG_PATH, O_RDONLY, 0); if (config_fd < 0) { printk("open %s failed \n", IT7259_CFG_PATH); return 1; } config_size = config_fd->f_op->read(config_fd, config_buf, 0x500, &config_fd->f_pos); printk(KERN_ERR "File Config version : %02x %02x %02x %02x\n", config_buf[config_size-8], config_buf[config_size-7], config_buf[config_size-6], config_buf[config_size-5]); set_fs(fs); filp_close(fw_fd, NULL); filp_close(config_fd, NULL); printk(KERN_ERR "Chip firmware version : %02x %02x %02x %02x\n", ts_data->fw_ver[0], ts_data->fw_ver[1], ts_data->fw_ver[2], ts_data->fw_ver[3]); printk(KERN_ERR "Chip config version : %02x %02x %02x %02x\n", ts_data->cfg_ver[0], ts_data->cfg_ver[1], ts_data->cfg_ver[2], ts_data->cfg_ver[3]); download = 0; if ((ts_data->cfg_ver[0] != config_buf[config_size-8]) || (ts_data->cfg_ver[1] != config_buf[config_size-7]) || (ts_data->cfg_ver[2] != config_buf[config_size-6]) || (ts_data->cfg_ver[3] != config_buf[config_size-5])) download += 1; if ((ts_data->fw_ver[0] != fw_buf[136]) || (ts_data->fw_ver[1] != fw_buf[137]) || (ts_data->fw_ver[2] != fw_buf[138]) || (ts_data->fw_ver[3] != fw_buf[139])) download += 2; printk(KERN_ERR "%s, print download = %d\n", __func__, download); if (download == 0) { printk(KERN_ERR "Do not need to upgrade\n"); return 0; } else { if (gfnIT7259_FirmwareDownload(ts_data, fw_size, fw_buf, config_size, config_buf) == false) { //fail return 1; } else { //success return 0; } } } static ssize_t sysfs_point_show(struct device *dev, struct device_attribute *attr, char *buf) { struct it7259_ts_data *ts_data = dev_get_drvdata(dev); uint8_t pt_data[sizeof(struct point_data)]; int readSuccess; ssize_t ret; readSuccess = it7259_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_upgrade_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct it7259_ts_data *ts_data = dev_get_drvdata(dev); printk(KERN_INFO "%s():\n", __func__); if (ts_data->suspended) { dev_err(dev, "Device is suspended, can't upgrade FW/CFG !!!\n"); return -EBUSY; } mutex_lock(&ts_data->fw_cfg_mutex); if (Upgrade_FW_CFG(ts_data)) { printk(KERN_ERR "IT7259_upgrade_failed\n"); } else { printk(KERN_ERR "IT7259_upgrade_OK\n\n"); } mutex_unlock(&ts_data->fw_cfg_mutex); return 1; } static ssize_t sysfs_upgrade_show(struct device *dev, struct device_attribute *attr, char *buf) { struct it7259_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_GetCSEL_show(struct device *dev, struct device_attribute *attr, char *buf) { struct it7259_ts_data *ts_data = dev_get_drvdata(dev); static const u8 Current_Mode[] = {0x1A, 0x05, 0x00}; static const u8 Ground_Mode[] = {0x1A, 0x05, 0x01}; static const u8 Shielding_Mode[] = {0x1A, 0x05, 0x02}; u8 Current_CSEL[56] = {0,}; u8 Ground_CSEL[56] = {0,}; u8 Shielding_CSEL[56] = {0,}; int ret; ret = it7259_i2c_write_no_ready_check(ts_data, BUF_COMMAND, Current_Mode, sizeof(Current_Mode)); if (ret != IT_I2C_WRITE_RET) { dev_err(&ts_data->client->dev, "failed to write CMD_IDENT_CHIP\n"); return scnprintf(buf, MAX_BUFFER_SIZE, "failed to write CMD_IDENT_CHIP\n"); } ret = it7259_wait_device_ready(ts_data, true, false); if (ret < 0) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip status\n"); } ret = it7259_i2c_read_no_ready_check(ts_data, BUF_RESPONSE, Current_CSEL, sizeof(Current_CSEL)); if (ret != IT_I2C_READ_RET) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip-id\n"); } return scnprintf(buf, MAX_BUFFER_SIZE, "it7259 Current_CSEL : 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n ===========================================================================\n", Current_CSEL[0], Current_CSEL[1], Current_CSEL[2], Current_CSEL[3], Current_CSEL[4], Current_CSEL[5], Current_CSEL[6], Current_CSEL[7], Current_CSEL[8], Current_CSEL[9], Current_CSEL[10], Current_CSEL[11], Current_CSEL[12], Current_CSEL[13], Current_CSEL[14], Current_CSEL[15], Current_CSEL[16], Current_CSEL[17], Current_CSEL[18], Current_CSEL[19], Current_CSEL[20], Current_CSEL[21], Current_CSEL[22], Current_CSEL[23], Current_CSEL[24], Current_CSEL[25], Current_CSEL[26], Current_CSEL[27], Current_CSEL[28], Current_CSEL[29], Current_CSEL[30], Current_CSEL[31], Current_CSEL[32], Current_CSEL[33], Current_CSEL[34], Current_CSEL[35], Current_CSEL[36], Current_CSEL[37], Current_CSEL[38], Current_CSEL[39], Current_CSEL[40], Current_CSEL[41], Current_CSEL[42], Current_CSEL[43], Current_CSEL[44], Current_CSEL[45], Current_CSEL[46], Current_CSEL[47], Current_CSEL[48], Current_CSEL[49], Current_CSEL[50], Current_CSEL[51], Current_CSEL[52], Current_CSEL[53], Current_CSEL[54], Current_CSEL[55]); ret = it7259_i2c_write_no_ready_check(ts_data, BUF_COMMAND, Ground_Mode, sizeof(Ground_Mode)); if (ret != IT_I2C_WRITE_RET) { dev_err(&ts_data->client->dev, "failed to write CMD_IDENT_CHIP\n"); return scnprintf(buf, MAX_BUFFER_SIZE, "failed to write CMD_IDENT_CHIP\n"); } ret = it7259_wait_device_ready(ts_data, true, false); if (ret < 0) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip status\n"); } ret = it7259_i2c_read_no_ready_check(ts_data, BUF_RESPONSE, Ground_CSEL, sizeof(Ground_CSEL)); if (ret != IT_I2C_READ_RET) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip-id\n"); } return scnprintf(buf, MAX_BUFFER_SIZE, "it7259 Ground_CSEL : 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n ===========================================================================\n", Ground_CSEL[0], Ground_CSEL[1], Ground_CSEL[2], Ground_CSEL[3], Ground_CSEL[4], Ground_CSEL[5], Ground_CSEL[6], Ground_CSEL[7], Ground_CSEL[8], Ground_CSEL[9], Ground_CSEL[10], Ground_CSEL[11], Ground_CSEL[12], Ground_CSEL[13], Ground_CSEL[14], Ground_CSEL[15], Ground_CSEL[16], Ground_CSEL[17], Ground_CSEL[18], Ground_CSEL[19], Ground_CSEL[20], Ground_CSEL[21], Ground_CSEL[22], Ground_CSEL[23], Ground_CSEL[24], Ground_CSEL[25], Ground_CSEL[26], Ground_CSEL[27], Ground_CSEL[28], Ground_CSEL[29], Ground_CSEL[30], Ground_CSEL[31], Ground_CSEL[32], Ground_CSEL[33], Ground_CSEL[34], Ground_CSEL[35], Ground_CSEL[36], Ground_CSEL[37], Ground_CSEL[38], Ground_CSEL[39], Ground_CSEL[40], Ground_CSEL[41], Ground_CSEL[42], Ground_CSEL[43], Ground_CSEL[44], Ground_CSEL[45], Ground_CSEL[46], Ground_CSEL[47], Ground_CSEL[48], Ground_CSEL[49], Ground_CSEL[50], Ground_CSEL[51], Ground_CSEL[52], Ground_CSEL[53], Ground_CSEL[54], Ground_CSEL[55]); ret = it7259_i2c_write_no_ready_check(ts_data, BUF_COMMAND, Shielding_Mode, sizeof(Shielding_Mode)); if (ret != IT_I2C_WRITE_RET) { dev_err(&ts_data->client->dev, "failed to write CMD_IDENT_CHIP\n"); return scnprintf(buf, MAX_BUFFER_SIZE, "failed to write CMD_IDENT_CHIP\n"); } ret = it7259_wait_device_ready(ts_data, true, false); if (ret < 0) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip status\n"); } ret = it7259_i2c_read_no_ready_check(ts_data, BUF_RESPONSE, Shielding_CSEL, sizeof(Shielding_CSEL)); if (ret != IT_I2C_READ_RET) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip-id\n"); } return scnprintf(buf, MAX_BUFFER_SIZE, "it7259 Shielding_CSEL : 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n ===========================================================================\n", Shielding_CSEL[0], Shielding_CSEL[1], Shielding_CSEL[2], Shielding_CSEL[3], Shielding_CSEL[4], Shielding_CSEL[5], Shielding_CSEL[6], Shielding_CSEL[7], Shielding_CSEL[8], Shielding_CSEL[9], Shielding_CSEL[10], Shielding_CSEL[11], Shielding_CSEL[12], Shielding_CSEL[13], Shielding_CSEL[14], Shielding_CSEL[15], Shielding_CSEL[16], Shielding_CSEL[17], Shielding_CSEL[18], Shielding_CSEL[19], Shielding_CSEL[20], Shielding_CSEL[21], Shielding_CSEL[22], Shielding_CSEL[23], Shielding_CSEL[24], Shielding_CSEL[25], Shielding_CSEL[26], Shielding_CSEL[27], Shielding_CSEL[28], Shielding_CSEL[29], Shielding_CSEL[30], Shielding_CSEL[31], Shielding_CSEL[32], Shielding_CSEL[33], Shielding_CSEL[34], Shielding_CSEL[35], Shielding_CSEL[36], Shielding_CSEL[37], Shielding_CSEL[38], Shielding_CSEL[39], Shielding_CSEL[40], Shielding_CSEL[41], Shielding_CSEL[42], Shielding_CSEL[43], Shielding_CSEL[44], Shielding_CSEL[45], Shielding_CSEL[46], Shielding_CSEL[47], Shielding_CSEL[48], Shielding_CSEL[49], Shielding_CSEL[50], Shielding_CSEL[51], Shielding_CSEL[52], Shielding_CSEL[53], Shielding_CSEL[54], Shielding_CSEL[55]); } static ssize_t sysfs_readstage_show(struct device *dev, struct device_attribute *attr, char *buf) { struct it7259_ts_data *ts_data = dev_get_drvdata(dev); static const u8 read_stage[] = {0x1A, 0x00, 0x01, 0x05}; u8 stage_CDC[10] = {0,}; int ret; ret = it7259_i2c_write_no_ready_check(ts_data, BUF_COMMAND, read_stage, sizeof(read_stage)); if (ret != IT_I2C_WRITE_RET) { dev_err(&ts_data->client->dev, "failed to write CMD_IDENT_CHIP\n"); return scnprintf(buf, MAX_BUFFER_SIZE, "failed to write CMD_IDENT_CHIP\n"); } ret = it7259_wait_device_ready(ts_data, true, false); if (ret < 0) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip status\n"); } ret = it7259_i2c_read_no_ready_check(ts_data, BUF_RESPONSE, stage_CDC, sizeof(stage_CDC)); if (ret != IT_I2C_READ_RET) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip-id\n"); } return scnprintf(buf, MAX_BUFFER_SIZE, "it7259 stage CDC : 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n", stage_CDC[0], stage_CDC[1], stage_CDC[2], stage_CDC[3], stage_CDC[4], stage_CDC[5], stage_CDC[6], stage_CDC[7], stage_CDC[8], stage_CDC[9]); } static ssize_t sysfs_chipID_show(struct device *dev, struct device_attribute *attr, char *buf) { struct it7259_ts_data *ts_data = dev_get_drvdata(dev); static const uint8_t cmd_ident[] = {CMD_IDENT_CHIP}; uint8_t chip_id[10] = {0,}; int ret; ret = it7259_wait_device_ready(ts_data, false, true); if (ret < 0) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip status\n"); } ret = it7259_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\n"); return scnprintf(buf, MAX_BUFFER_SIZE, "failed to write CMD_IDENT_CHIP\n"); } ret = it7259_wait_device_ready(ts_data, true, false); if (ret < 0) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip status\n"); } ret = it7259_i2c_read_no_ready_check(ts_data, BUF_RESPONSE, chip_id, sizeof(chip_id)); if (ret != IT_I2C_READ_RET) { return scnprintf(buf, MAX_BUFFER_SIZE, "failed to read chip-id\n"); } return scnprintf(buf, MAX_BUFFER_SIZE, "it7259_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]); } static ssize_t sysfs_version_show(struct device *dev, struct device_attribute *attr, char *buf) { struct it7259_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_cfg_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct it7259_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 it7259_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 it7259_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 it7259_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(chipID, S_IRUGO | S_IWUSR, sysfs_chipID_show, NULL); static DEVICE_ATTR(readstage, S_IRUGO | S_IWUSR, sysfs_readstage_show, NULL); static DEVICE_ATTR(GetCSEL, S_IRUGO | S_IWUSR, sysfs_GetCSEL_show, NULL); static DEVICE_ATTR(upgrade, S_IRUGO | S_IWUSR, sysfs_upgrade_show, sysfs_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 struct attribute *it7259_attributes[] = { &dev_attr_version.attr, &dev_attr_upgrade.attr, &dev_attr_point.attr, &dev_attr_fw_name.attr, &dev_attr_cfg_name.attr, &dev_attr_chipID.attr, &dev_attr_readstage.attr, &dev_attr_GetCSEL.attr, NULL }; static const struct attribute_group it7259_attr_group = { .attrs = it7259_attributes, }; #ifdef CONFIG_PM static void it7259_ts_release_all(struct it7259_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); } #endif static irqreturn_t it7259_ts_threaded_handler(int irq, void *devid) { u16 tmp; struct point_data pt_data; struct it7259_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, x_center, y_center, panel_radius, disp_radius, x_position, y_position; u32 sq_rad_position, sq_disp_position; bool palm_detected; int ret; //printk("%s %d %s\n", __FILE__, __LINE__, __func__); // printk("%s %d %s\n", __FILE__, __LINE__, __func__); /* verify there is point data to read & it is readable and valid */ ret = it7259_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 = it7259_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; } // printk("%s %d %s\n", __FILE__, __LINE__, __func__); /* 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. */ //printk("%s %d %s\n", __FILE__, __LINE__, __func__); if ((pt_data.flags & PD_FLAGS_DATA_TYPE_BITS) == PD_FLAGS_IDLE_TO_ACTIVE && pt_data.gesture_id == 0) { printk("%s %d %s\n", __FILE__, __LINE__, __func__); pm_stay_awake(&ts_data->client->dev); // printk("%s %d %s KEY_WAKEUP:0x%x\n", __FILE__, __LINE__, __func__, KEY_WAKEUP); 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. printk("%s %d %s\n", __FILE__, __LINE__, __func__); */ palm_detected = pt_data.gesture_id & PD_PALM_FLAG_BIT; if (palm_detected && ts_data->pdata->palm_detect_en) { //printk("%s %d %s palm_detect_keycode:0x%x\n", __FILE__, __LINE__, __func__, ts_data->pdata->palm_detect_keycode); //printk("%s %d %s\n", __FILE__, __LINE__, __func__); 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); //printk("%s %d %s finger:0x%x\n", __FILE__, __LINE__, __func__, 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; //printk("%s %d %s\n", __FILE__, __LINE__, __func__); //printk("X: %d Y:%d, pressure:%d\n", x, y, pressure); if (finger_status) { if (pressure >= FD_PRESSURE_LIGHT) { /* Center co-odinate of panel */ x_center = 246; y_center = 246; /* Radius of the panel */ panel_radius = x_center; /* Radius of the display */ disp_radius = 226; /* Distance from present co-ordinate to center co-ordinate */ if (x > x_center) { x_position = x - x_center; } else { x_position = x_center - x; //only x } if (y > y_center) { y_position = y - y_center; } else { y_position = y_center - y; //only y } sq_rad_position = (u32)((x_position * x_position) + (u32)(y_position * y_position)); sq_disp_position = (u32)(disp_radius * disp_radius); tmp = x; x = y; y = 240 - tmp; if (sq_rad_position > sq_disp_position) { //printk("####%s %d %s\n", __FILE__, __LINE__, __func__); printk("#### Bezel Touch X: %d Y:%d\n", x, y); 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, 0); // input_report_key(input_dev, BTN_TOOL_FINGER, 1); // input_report_abs(input_dev, ABS_MT_POSITION_X, TS_REMAP_X[x][y]); // input_report_abs(input_dev, ABS_MT_POSITION_Y, TS_REMAP_Y[x][y]); // input_report_abs(input_dev, ABS_DISTANCE, 5/** Z distance dummy*/); // bezel_count++; ////input_sync(ts_data->input_dev); } else { //printk("####%s %d %s\n", __FILE__, __LINE__, __func__); printk("#### Display Touch X: %d Y:%d\n", x, y); 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++; } } } } //printk("%s %d %s\n", __FILE__, __LINE__, __func__); //printk("%s %d %s BTN_TOUCH:0x%x\n", __FILE__, __LINE__, __func__, BTN_TOUCH); //printk("%s %d %s touch_count:%d\n", __FILE__, __LINE__, __func__, touch_count); input_report_key(input_dev, BTN_TOUCH, touch_count > 0); input_sync(input_dev); return IRQ_HANDLED; } static void it7259_ts_work_func(struct work_struct *work) { struct it7259_ts_data *ts_data = container_of(work, struct it7259_ts_data, work_pm_relax); pm_relax(&ts_data->client->dev); } static int it7259_ts_chip_identify(struct it7259_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', '5', '1'}; 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 = it7259_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 = it7259_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 = it7259_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 = it7259_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, "it7259_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) { #if 0 return (regulator_count_voltages(reg) > 0) ? regulator_set_optimum_mode(reg, load_uA) : 0; #else return 0; #endif } static int it7259_regulator_configure(struct it7259_ts_data *ts_data, bool on) { int retval; if (on == false) goto hw_shutdown; #if 0 ts_data->vdd = devm_regulator_get(&ts_data->client->dev, "axp2101_aldo3"); 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; } } #endif ts_data->avdd = devm_regulator_get(&ts_data->client->dev, "vcc-ctp"); 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 0 if (regulator_count_voltages(ts_data->vdd) > 0) regulator_set_voltage(ts_data->vdd, 0, IT_VTG_MAX_UV); #endif return retval; hw_shutdown: #if 0 if (regulator_count_voltages(ts_data->vdd) > 0) regulator_set_voltage(ts_data->vdd, 0, IT_VTG_MAX_UV); #endif if (regulator_count_voltages(ts_data->avdd) > 0) regulator_set_voltage(ts_data->avdd, 0, IT_I2C_VTG_MAX_UV); return 0; }; static int it7259_power_on(struct it7259_ts_data *ts_data, bool on) { int retval; if (on == false) goto power_off; #if 0 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; } #endif 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: #if 0 regulator_disable(ts_data->vdd); #endif #if 0 reg_set_optimum_mode_check(ts_data->vdd, 0); #endif return retval; power_off: #if 0 reg_set_optimum_mode_check(ts_data->vdd, 0); regulator_disable(ts_data->vdd); #endif reg_set_optimum_mode_check(ts_data->avdd, 0); regulator_disable(ts_data->avdd); return 0; } static int it7259_gpio_configure(struct it7259_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); udelay(ts_data->pdata->reset_delay); if (ts_data->pdata->low_reset) gpio_set_value(ts_data->pdata->reset_gpio, 1); else gpio_set_value(ts_data->pdata->reset_gpio, 0); } 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 #if 0 static int it7259_get_dt_coords(struct device *dev, char *name, struct it7259_ts_platform_data *pdata) { u32 coords[it7259_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 != it7259_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, "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, "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; } #endif static int it7259_parse_dt(struct device *dev, struct it7259_ts_platform_data *pdata) { struct it7259_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, "reset-gpios", 0, &pdata->reset_gpio_flags); pdata->irq_gpio = of_get_named_gpio_flags(np, "int-gpios", 0, &pdata->irq_gpio_flags); rc = of_property_read_u32(np, "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; } //printk("%s %d %s num-fingers:%d\n", __FILE__, __LINE__, __func__, temp_val); pdata->wakeup = of_property_read_bool(np, "wakeup"); //printk("%s %d %s wakeup:%d\n", __FILE__, __LINE__, __func__, pdata->wakeup); pdata->palm_detect_en = of_property_read_bool(np, "palm-detect-en"); //printk("%s %d %s palm-detect-en:%d\n", __FILE__, __LINE__, __func__, pdata->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, "fw-name", &pdata->fw_name); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read fw image name %d\n", rc); return rc; } else if (rc == -EINVAL) { pdata->fw_name = NULL; } //printk("%s %d %s rc:%d\n", __FILE__, __LINE__, __func__, rc); rc = of_property_read_string(np, "cfg-name", &pdata->cfg_name); if (rc && (rc != -EINVAL)) { dev_err(dev, "Unable to read cfg image name %d\n", rc); return rc; } else if (rc == -EINVAL) { pdata->cfg_name = NULL; } //printk("%s %d %s rc:%d\n", __FILE__, __LINE__, __func__, 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, "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; } //printk("%s %d %s reset_delay:%d\n", __FILE__, __LINE__, __func__, pdata->reset_delay); rc = of_property_read_u32(np, "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, "low-reset"); //printk("%s %d %s low_reset:%d\n", __FILE__, __LINE__, __func__, pdata->low_reset); #if 1 pdata->disp_minx = 0; pdata->disp_miny = 0; pdata->disp_maxx = 240; pdata->disp_maxy = 240; pdata->panel_minx = 0; pdata->panel_miny = 0; pdata->panel_maxx = 240; pdata->panel_maxy = 240; #else rc = it7259_get_dt_coords(dev, "display-coords", pdata); if (rc && (rc != -EINVAL)) return rc; rc = it7259_get_dt_coords(dev, "panel-coords", pdata); if (rc && (rc != -EINVAL)) return rc; #endif return 0; } #else static inline int it7259_ts_parse_dt(struct device *dev, struct it7259_ts_platform_data *pdata) { return 0; } #endif static int it7259_ts_pinctrl_init(struct it7259_ts_data *ts_data) { int retval = 0; /* 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; } /* * this code to get versions from the chip via i2c transactions, and save * them in driver data structure. */ static void it7259_get_chip_versions(struct it7259_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] = {0}, ver_cfg[VERSION_LENGTH] = {0}; int ret = 0; ret = it7259_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 = it7259_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 = it7259_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 = it7259_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 = it7259_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 = it7259_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 it7259_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { static const uint8_t cmd_start[] = {CMD_UNKNOWN_7}; struct it7259_ts_data *ts_data = NULL; struct it7259_ts_platform_data *pdata = NULL; uint8_t rsp[2]; int ret = -1, err; struct dentry *temp; printk("%s %d %s\n", __FILE__, __LINE__, __func__); 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(struct it7259_ts_platform_data), GFP_KERNEL); if (!pdata) return -ENOMEM; ret = it7259_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 = it7259_regulator_configure(ts_data, true); if (ret < 0) { dev_err(&client->dev, "Failed to configure regulators\n"); goto err_reg_configure; } ret = it7259_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 = it7259_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 = it7259_gpio_configure(ts_data, true); if (ret < 0) { dev_err(&client->dev, "Failed to configure gpios\n"); goto err_gpio_config; } } //printk("%s %d %s\n", __FILE__, __LINE__, __func__); ret = it7259_ts_chip_identify(ts_data); if (ret) { dev_err(&client->dev, "Failed to identify chip %d!!!", ret); goto err_identification_fail; } //printk("%s %d %s\n", __FILE__, __LINE__, __func__); it7259_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 = 0x7259; 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); printk("disp_minx=%d, %d\n", ts_data->pdata->disp_minx, ts_data->pdata->disp_maxx); printk("disp_miny=%d, %d\n", ts_data->pdata->disp_miny, ts_data->pdata->disp_maxy); 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); //printk("%s %d %s\n", __FILE__, __LINE__, __func__); if (pdata->wakeup) { set_bit(KEY_WAKEUP, ts_data->input_dev->keybit); INIT_WORK(&ts_data->work_pm_relax, it7259_ts_work_func); device_init_wakeup(&client->dev, pdata->wakeup); } //printk("%s %d %s\n", __FILE__, __LINE__, __func__); 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; } //printk("%s %d %s client->irq:%d\n", __FILE__, __LINE__, __func__, client->irq); client->irq = gpio_to_irq(ts_data->pdata->irq_gpio); //printk("%s %d %s client->irq:%d\n", __FILE__, __LINE__, __func__, client->irq); ret = request_threaded_irq(client->irq, NULL, it7259_ts_threaded_handler, IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ts_data); if (ret != 0) { dev_err(&client->dev, "request_irq failed %d\n", ret); goto err_irq_reg; } if (sysfs_create_group(&(client->dev.kobj), &it7259_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 //printk("%s %d %s\n", __FILE__, __LINE__, __func__); it7259_i2c_write_no_ready_check(ts_data, BUF_COMMAND, cmd_start, sizeof(cmd_start)); udelay(pdata->reset_delay); //printk("%s %d %s\n", __FILE__, __LINE__, __func__); it7259_i2c_read_no_ready_check(ts_data, BUF_RESPONSE, rsp, sizeof(rsp)); udelay(pdata->reset_delay); //printk("%s %d %s\n", __FILE__, __LINE__, __func__); 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; } printk("%s %d %s\n", __FILE__, __LINE__, __func__); 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), &it7259_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: it7259_power_on(ts_data, false); err_power_device: it7259_regulator_configure(ts_data, false); err_reg_configure: return ret; } static int it7259_ts_remove(struct i2c_client *client) { struct it7259_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), &it7259_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); } it7259_power_on(ts_data, false); it7259_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 it7259_ts_data *ts_data = container_of(self, struct it7259_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) it7259_ts_resume(&(ts_data->client->dev)); else if (*blank == FB_BLANK_POWERDOWN || *blank == FB_BLANK_VSYNC_SUSPEND) it7259_ts_suspend(&(ts_data->client->dev)); } } return 0; } #endif #ifdef CONFIG_PM static int it7259_ts_resume(struct device *dev) { struct it7259_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 it7259_ts_suspend(struct device *dev) { struct it7259_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 = it7259_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); it7259_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 it7259_ts_dev_pm_ops = { .suspend = it7259_ts_suspend, .resume = it7259_ts_resume, }; #else static int it7259_ts_resume(struct device *dev) { return 0; } static int it7259_ts_suspend(struct device *dev) { return 0; } #endif static const struct i2c_device_id it7259_ts_id[] = { { DEVICE_NAME, 0}, {} }; MODULE_DEVICE_TABLE(i2c, it7259_ts_id); static const struct of_device_id it7259_match_table[] = { { .compatible = "ite,it7251_ts",}, {}, }; static struct i2c_driver it7259_ts_driver = { .driver = { .owner = THIS_MODULE, .name = DEVICE_NAME, .of_match_table = it7259_match_table, #ifdef CONFIG_PM .pm = &it7259_ts_dev_pm_ops, #endif }, .probe = it7259_ts_probe, .remove = it7259_ts_remove, .id_table = it7259_ts_id, }; module_i2c_driver(it7259_ts_driver); MODULE_DESCRIPTION("it7259 Touchscreen Driver"); MODULE_LICENSE("GPL v2");