diff options
Diffstat (limited to 'drivers/input/touchscreen/mxt540e.c')
-rw-r--r-- | drivers/input/touchscreen/mxt540e.c | 2940 |
1 files changed, 0 insertions, 2940 deletions
diff --git a/drivers/input/touchscreen/mxt540e.c b/drivers/input/touchscreen/mxt540e.c deleted file mode 100644 index cf3cb09..0000000 --- a/drivers/input/touchscreen/mxt540e.c +++ /dev/null @@ -1,2940 +0,0 @@ -/* - * Copyright (C) 2010, Samsung Electronics Co. Ltd. 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 as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/input.h> -#include <linux/input/mt.h> -#include <linux/interrupt.h> -#include <linux/i2c.h> -#include <linux/delay.h> -#include <linux/earlysuspend.h> -#include <linux/slab.h> -#include <linux/gpio.h> -#include <linux/i2c/mxt540e.h> -#include <asm/unaligned.h> -#include <linux/firmware.h> -#include <mach/cpufreq.h> - -#define OBJECT_TABLE_START_ADDRESS 7 -#define OBJECT_TABLE_ELEMENT_SIZE 6 - -#define CMD_RESET_OFFSET 0 -#define CMD_BACKUP_OFFSET 1 -#define CMD_CALIBRATE_OFFSET 2 -#define CMD_REPORTATLL_OFFSET 3 -#define CMD_DEBUG_CTRL_OFFSET 4 -#define CMD_DIAGNOSTIC_OFFSET 5 - -#define DETECT_MSG_MASK 0x80 -#define PRESS_MSG_MASK 0x40 -#define RELEASE_MSG_MASK 0x20 -#define MOVE_MSG_MASK 0x10 -#define VECTOR_MSG_MASK 0x08 -#define AMP_MSG_MASK 0x04 -#define SUPPRESS_MSG_MASK 0x02 -#define UNGRIP_MSG_MASK 0x01 - -/* Version */ -#define MXT540E_VER_10 0x10 - -/* Slave addresses */ -#define MXT540E_APP_LOW 0x4C -#define MXT540E_APP_HIGH 0x4D -#define MXT540E_BOOT_LOW 0x26 -#define MXT540E_BOOT_HIGH 0x27 - -/* FIRMWARE NAME */ -#define MXT540E_FW_NAME "tsp_atmel/mXT540E.fw" - -#define MXT540E_BOOT_VALUE 0xa5 -#define MXT540E_BACKUP_VALUE 0x55 - -/* Bootloader mode status */ -#define MXT540E_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */ -#define MXT540E_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */ -#define MXT540E_FRAME_CRC_CHECK 0x02 -#define MXT540E_FRAME_CRC_FAIL 0x03 -#define MXT540E_FRAME_CRC_PASS 0x04 -#define MXT540E_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */ -#define MXT540E_BOOT_STATUS_MASK 0x3f - -/* Command to unlock bootloader */ -#define MXT540E_UNLOCK_CMD_MSB 0xaa -#define MXT540E_UNLOCK_CMD_LSB 0xdc - -#define ID_BLOCK_SIZE 7 - -#define DRIVER_FILTER - -#define MXT540E_STATE_INACTIVE -1 -#define MXT540E_STATE_RELEASE 0 -#define MXT540E_STATE_PRESS 1 -#define MXT540E_STATE_MOVE 2 - -#define MAX_FINGER_NUM 10 - -#define MEDIANERROR_MAX_BAT 5 -#define MEDIANERROR_MAX_TA 10 - -struct object_t { - u8 object_type; - u16 i2c_address; - u8 size; - u8 instances; - u8 num_report_ids; -} __packed; - -struct finger_info { - s16 x; - s16 y; - s16 z; - u16 w; - s8 state; - int16_t component; -}; - -struct median_error_t { - u8 err_cnt_bat; - u8 err_cnt_ta; - u8 setting_flag; - u8 table_cnt; - u8 table_ta[4]; - u8 table_bat[4]; -}; - -struct report_id_map_t { - u8 object_type; /*!< Object type. */ - u8 instance; /*!< Instance number. */ -}; - -u8 max_report_id; -struct report_id_map_t *rid_map; -static bool rid_map_alloc; - -struct mxt540e_data { - struct i2c_client *client; - struct input_dev *input_dev; - struct early_suspend early_suspend; - struct median_error_t *median_error; - struct object_t *objects; - struct delayed_work config_dwork; - struct delayed_work resume_check_dwork; - struct delayed_work cal_check_dwork; - const u8 *power_cfg; - const u8 *t48_config_batt_e; - const u8 *t48_config_chrg_e; - u16 msg_proc; - u16 cmd_proc; - u16 msg_object_size; - u32 x_dropbits:2; - u32 y_dropbits:2; - u32 finger_mask; - u8 objects_len; - u8 tsp_version; - u8 tsp_build; - u8 family_id; - u8 finger_type; - u8 chrgtime_batt; - u8 chrgtime_charging; - u8 atchcalst; - u8 atchcalsthr; - u8 tchthr_batt; - u8 tchthr_charging; - u8 actvsyncsperx_batt; - u8 actvsyncsperx_charging; - u8 calcfg_batt_e; - u8 calcfg_charging_e; - u8 atchfrccalthr_e; - u8 atchfrccalratio_e; - void (*power_on) (void); - void (*power_off) (void); - void (*power_on_with_oleddet) (void); - void (*power_off_with_oleddet) (void); - void (*register_cb) (void *); - void (*read_ta_status) (void *); - int num_fingers; - int gpio_read_done; - unsigned int cpu_freq_lock; - struct finger_info fingers[]; -}; - -struct mxt540e_data *copy_data; - -static int mxt540e_enabled; -static bool g_debug_switch; -static u8 tsp_version_disp; -static u8 threshold; -static int firm_status_data; -static bool deepsleep; -static bool touch_cpu_lock_status; -static int check_resume_err; -static int check_resume_err_count; -static int check_calibrate; -static int config_dwork_flag; -int16_t sumsize; -int touch_is_pressed; -EXPORT_SYMBOL(touch_is_pressed); - -struct device *sec_touchscreen; -static u8 firmware_latest = 0x13; -static u8 build_latest = 0xAA; - -struct device *mxt540e_noise_test; -/* - top_left, top_right, center, bottom_left, bottom_right -*/ -unsigned int test_node[5] = { 443, 53, 253, 422, 32 }; -uint16_t qt_refrence_node[540] = { 0 }; -uint16_t qt_delta_node[540] = { 0 }; - -static int read_mem(struct mxt540e_data *data, u16 reg, u8 len, u8 *buf) -{ - int ret; - u16 le_reg = cpu_to_le16(reg); - struct i2c_msg msg[2] = { - { - .addr = data->client->addr, - .flags = 0, - .len = 2, - .buf = (u8 *) &le_reg, - }, - { - .addr = data->client->addr, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - }, - }; - - ret = i2c_transfer(data->client->adapter, msg, 2); - if (ret < 0) - return ret; - - return ret == 2 ? 0 : -EIO; -} - -static int write_mem(struct mxt540e_data *data, u16 reg, u8 len, const u8 *buf) -{ - int ret; - u8 tmp[len + 2]; - - put_unaligned_le16(cpu_to_le16(reg), tmp); - memcpy(tmp + 2, buf, len); - - ret = i2c_master_send(data->client, tmp, sizeof(tmp)); - - if (ret < 0) - return ret; - - return ret == sizeof(tmp) ? 0 : -EIO; -} - -static int __devinit mxt540e_reset(struct mxt540e_data *data) -{ - u8 buf = 1u; - return write_mem(data, data->cmd_proc + CMD_RESET_OFFSET, 1, &buf); -} - -static int __devinit mxt540e_backup(struct mxt540e_data *data) -{ - u8 buf = 0x55u; - return write_mem(data, data->cmd_proc + CMD_BACKUP_OFFSET, 1, &buf); -} - -static int get_object_info(struct mxt540e_data *data, u8 object_type, - u16 *size, u16 *address) -{ - int i; - - for (i = 0; i < data->objects_len; i++) { - if (data->objects[i].object_type == object_type) { - *size = data->objects[i].size + 1; - *address = data->objects[i].i2c_address; - return 0; - } - } - - return -ENODEV; -} - -static int write_config(struct mxt540e_data *data, u8 type, const u8 * cfg) -{ - int ret; - u16 address = 0; - u16 size = 0; - - ret = get_object_info(data, type, &size, &address); - - if (size == 0 && address == 0) - return 0; - else - return write_mem(data, address, size, cfg); -} - -static int check_instance(struct mxt540e_data *data, u8 object_type) -{ - int i; - - for (i = 0; i < data->objects_len; i++) { - if (data->objects[i].object_type == object_type) - return data->objects[i].instances; - } - return 0; -} - -static int init_write_config(struct mxt540e_data *data, u8 type, const u8 * cfg) -{ - int ret; - u16 address = 0; - u16 size = 0; - u8 *temp; - int instance_num; - - ret = get_object_info(data, type, &size, &address); - - if ((size == 0) || (address == 0)) - return 0; - - ret = write_mem(data, address, size, cfg); - instance_num = check_instance(data, type); - if (instance_num > 0) { - printk(KERN_DEBUG "[TSP] exist instance%d objects (%d)\n", - instance_num, type); - temp = kmalloc(size * instance_num * sizeof(u8), GFP_KERNEL); - memset(temp, 0, size * instance_num); - ret |= write_mem(data, address + size, - size * instance_num, temp); - if (ret < 0) - printk(KERN_ERR "[TSP] %s, %d Error!!\n", __func__, - __LINE__); - kfree(temp); - } - return ret; -} - -static u32 __devinit crc24(u32 crc, u8 byte1, u8 byte2) -{ - static const u32 crcpoly = 0x80001B; - u32 res; - u16 data_word; - - data_word = (((u16) byte2) << 8) | byte1; - res = (crc << 1) ^ (u32) data_word; - - if (res & 0x1000000) - res ^= crcpoly; - - return res; -} - -static int __devinit calculate_infoblock_crc(struct mxt540e_data *data, - u32 *crc_pointer) -{ - u32 crc = 0; - u8 mem[7 + data->objects_len * 6]; - int status; - int i; - - status = read_mem(data, 0, sizeof(mem), mem); - - if (status) - return status; - - for (i = 0; i < sizeof(mem) - 1; i += 2) - crc = crc24(crc, mem[i], mem[i + 1]); - - *crc_pointer = crc24(crc, mem[i], 0) & 0x00FFFFFF; - - return 0; -} - -/* mxt540e reconfigration */ -static void mxt_reconfigration_normal(struct work_struct *work) -{ - int error, id; - u16 size; - - struct mxt540e_data *data = - container_of(work, struct mxt540e_data, config_dwork.work); - u16 obj_address = 0; - if (mxt540e_enabled) { - disable_irq(data->client->irq); - - for (id = 0; id < MAX_FINGER_NUM; ++id) { - if (data->fingers[id].state == MXT540E_STATE_INACTIVE) - continue; - schedule_delayed_work(&data->config_dwork, HZ * 5); - printk(KERN_DEBUG "[TSP] touch pressed!! %s didn't execute!!\n", - __func__); - enable_irq(data->client->irq); - return; - } - - get_object_info(data, GEN_ACQUISITIONCONFIG_T8, &size, - &obj_address); - error = write_mem(data, obj_address + 8, 1, - &data->atchfrccalthr_e); - if (error < 0) - printk(KERN_ERR "[TSP] %s, %d Error!!\n", __func__, - __LINE__); - error = - write_mem(data, obj_address + 9, 1, - &data->atchfrccalratio_e); - if (error < 0) - printk(KERN_ERR "[TSP] %s, %d Error!!\n", __func__, - __LINE__); - printk(KERN_DEBUG "[TSP] %s execute!!\n", __func__); - enable_irq(data->client->irq); - } - config_dwork_flag = 0; - return; -} - -static void resume_check_dworker(struct work_struct *work) -{ - check_resume_err = 0; - check_resume_err_count = 0; -} - -static void cal_check_dworker(struct work_struct *work) -{ - struct mxt540e_data *data = - container_of(work, struct mxt540e_data, cal_check_dwork.work); - int error; - u16 size; - u8 value; - u16 obj_address = 0; - if (mxt540e_enabled) { - check_calibrate = 0; - get_object_info(data, GEN_POWERCONFIG_T7, &size, &obj_address); - value = 50; - error = write_mem(data, obj_address + 2, 1, &value); - if (error < 0) - printk(KERN_ERR "[TSP] %s, %d Error!!\n", __func__, - __LINE__); - } - return; -} - -uint8_t calibrate_chip(struct mxt540e_data *data) -{ - u8 cal_data = 1; - int ret = 0; - /* send calibration command to the chip */ - ret = write_mem(data, data->cmd_proc + CMD_CALIBRATE_OFFSET, 1, - &cal_data); - - if (!ret) { - printk(KERN_DEBUG "[TSP] calibration success!!!\n"); - if (check_resume_err == 2) { - check_resume_err = 1; - schedule_delayed_work(&data->resume_check_dwork, - msecs_to_jiffies(2500)); - } else if (check_resume_err == 1) { - cancel_delayed_work(&data->resume_check_dwork); - schedule_delayed_work(&data->resume_check_dwork, - msecs_to_jiffies(2500)); - } - } - return ret; -} - -static void mxt540e_ta_probe(int ta_status) -{ - u16 obj_address; - u16 size; - u8 value; - int error; - struct mxt540e_data *data = copy_data; - - if (!mxt540e_enabled) { - printk(KERN_ERR "mxt540e_enabled is 0\n"); - return; - } - - data->median_error->err_cnt_ta = 0; - data->median_error->err_cnt_bat = 0; - data->median_error->setting_flag = 1; - data->median_error->table_cnt = 0; - - error = 0; - obj_address = 0; - if (ta_status) { - get_object_info(data, SPT_CTECONFIG_T46, &size, &obj_address); - value = data->actvsyncsperx_charging; - error |= write_mem(data, obj_address + 3, 1, &value); - get_object_info(data, PROCG_NOISESUPPRESSION_T48, &size, - &obj_address); - error |= - write_config(data, data->t48_config_chrg_e[0], - data->t48_config_chrg_e + 1); - threshold = data->tchthr_charging; - } else { - get_object_info(data, TOUCH_MULTITOUCHSCREEN_T9, &size, - &obj_address); - value = 192; - error |= write_mem(data, obj_address + 6, 1, &value); - value = 50; - error |= write_mem(data, obj_address + 7, 1, &value); - value = 80; - error |= write_mem(data, obj_address + 13, 1, &value); - get_object_info(data, SPT_GENERICDATA_T57, &size, &obj_address); - value = 25; - error |= write_mem(data, obj_address + 1, 1, &value); - get_object_info(data, SPT_CTECONFIG_T46, &size, &obj_address); - value = data->actvsyncsperx_batt; - error |= write_mem(data, obj_address + 3, 1, &value); - get_object_info(data, PROCG_NOISESUPPRESSION_T48, &size, - &obj_address); - error |= - write_config(data, data->t48_config_batt_e[0], - data->t48_config_batt_e + 1); - threshold = data->tchthr_batt; - } - if (error < 0) - printk(KERN_ERR "[TSP] %s Error!!\n", __func__); -}; - -#if defined(DRIVER_FILTER) -static void equalize_coordinate(bool detect, u8 id, u16 *px, u16 *py) -{ - static int tcount[MAX_FINGER_NUM] = { 0, }; - static u16 pre_x[MAX_FINGER_NUM][4] = { {0}, }; - static u16 pre_y[MAX_FINGER_NUM][4] = { {0}, }; - int coff[4] = { 0, }; - int distance = 0; - - if (detect) - tcount[id] = 0; - - pre_x[id][tcount[id] % 4] = *px; - pre_y[id][tcount[id] % 4] = *py; - - if (tcount[id] > 3) { - distance = - abs(pre_x[id][(tcount[id] - 1) % 4] - *px) + - abs(pre_y[id][(tcount[id] - 1) % 4] - *py); - - coff[0] = (u8)(2 + distance / 5); - if (coff[0] < 8) { - coff[0] = max(2, coff[0]); - coff[1] = min((8 - coff[0]), (coff[0] >> 1) + 1); - coff[2] = min((8 - coff[0] - coff[1]), - (coff[1] >> 1) + 1); - coff[3] = 8 - coff[0] - coff[1] - coff[2]; - - *px = (u16)((*px * (coff[0]) + - pre_x[id][(tcount[id] - 1) % 4] * (coff[1]) + - pre_x[id][(tcount[id] - 2) % 4] * (coff[2]) + - pre_x[id][(tcount[id] - 3) % 4] * (coff[3])) - / 8); - *py = (u16)((*py * (coff[0]) + - pre_y[id][(tcount[id] - 1) % 4] * (coff[1]) + - pre_y[id][(tcount[id] - 2) % 4] * (coff[2]) + - pre_y[id][(tcount[id] - 3) % 4] * (coff[3])) - / 8); - } else { - *px = (u16)((*px * 4 + pre_x[id][(tcount[id] - 1) % 4]) - / 5); - *py = (u16)((*py * 4 + pre_y[id][(tcount[id] - 1) % 4]) - / 5); - } - } - tcount[id]++; -} -#endif /* DRIVER_FILTER */ - -uint8_t reportid_to_type(struct mxt540e_data *data, u8 report_id, u8 * instance) -{ - struct report_id_map_t *report_id_map; - report_id_map = rid_map; - - if (report_id <= max_report_id) { - *instance = report_id_map[report_id].instance; - return report_id_map[report_id].object_type; - } else - return 0; -} - -static int __devinit mxt540e_init_touch_driver(struct mxt540e_data *data) -{ - struct object_t *object_table; - struct report_id_map_t *report_id_map_t; - u32 read_crc = 0; - u32 calc_crc; - u16 crc_address; - u16 dummy; - int i, j; - u8 id[ID_BLOCK_SIZE]; - int ret; - u8 type_count = 0; - u8 tmp; - int current_report_id, start_report_id; - - ret = read_mem(data, 0, sizeof(id), id); - if (ret) - return ret; - - dev_info(&data->client->dev, "family = %#02x, variant = %#02x, version " - "= %#02x, build = %d\n", id[0], id[1], id[2], id[3]); - printk(KERN_ERR "family = %#02x, variant = %#02x, version " - "= %#02x, build = %d\n", id[0], id[1], id[2], id[3]); - dev_dbg(&data->client->dev, "matrix X size = %d\n", id[4]); - dev_dbg(&data->client->dev, "matrix Y size = %d\n", id[5]); - - data->family_id = id[0]; - data->tsp_version = id[2]; - data->tsp_build = id[3]; - data->objects_len = id[6]; - - tsp_version_disp = data->tsp_version; - - object_table = kmalloc(data->objects_len * sizeof(*object_table), - GFP_KERNEL); - if (!object_table) - return -ENOMEM; - - ret = read_mem(data, OBJECT_TABLE_START_ADDRESS, - data->objects_len * sizeof(*object_table), - (u8 *) object_table); - if (ret) - goto err; - - max_report_id = 0; - - for (i = 0; i < data->objects_len; i++) { - object_table[i].i2c_address = - le16_to_cpu(object_table[i].i2c_address); - max_report_id += - object_table[i].num_report_ids * - (object_table[i].instances + 1); - tmp = 0; - if (object_table[i].num_report_ids) { - tmp = type_count + 1; - type_count += object_table[i].num_report_ids * - (object_table[i].instances + 1); - } - switch (object_table[i].object_type) { - case TOUCH_MULTITOUCHSCREEN_T9: - data->finger_type = tmp; - dev_dbg(&data->client->dev, "Finger type = %d\n", - data->finger_type); - break; - case GEN_MESSAGEPROCESSOR_T5: - data->msg_object_size = object_table[i].size + 1; - dev_dbg(&data->client->dev, "Message object size = " - "%d\n", data->msg_object_size); - break; - } - } - if (rid_map_alloc) { - rid_map_alloc = false; - kfree(rid_map); - } - rid_map = kmalloc((sizeof(*report_id_map_t) * max_report_id + 1), - GFP_KERNEL); - if (!rid_map) { - kfree(object_table); - return -ENOMEM; - } - rid_map_alloc = true; - rid_map[0].instance = 0; - rid_map[0].object_type = 0; - current_report_id = 1; - - for (i = 0; i < data->objects_len; i++) { - if (object_table[i].num_report_ids != 0) { - for (j = 0; j <= object_table[i].instances; j++) { - for (start_report_id = current_report_id; - current_report_id < - (start_report_id + - object_table[i].num_report_ids); - current_report_id++) { - rid_map[current_report_id].instance = j; - rid_map[current_report_id].object_type = - object_table[i].object_type; - } - } - } - } - - data->objects = object_table; - - /* Verify CRC */ - crc_address = OBJECT_TABLE_START_ADDRESS + - data->objects_len * OBJECT_TABLE_ELEMENT_SIZE; - -#ifdef __BIG_ENDIAN -#error The following code will likely break on a big endian machine -#endif - ret = read_mem(data, crc_address, 3, (u8 *) &read_crc); - if (ret) - goto err; - - read_crc = le32_to_cpu(read_crc); - - ret = calculate_infoblock_crc(data, &calc_crc); - if (ret) - goto err; - - if (read_crc != calc_crc) { - dev_err(&data->client->dev, "CRC error\n"); - ret = -EFAULT; - goto err; - } - - ret = get_object_info(data, GEN_MESSAGEPROCESSOR_T5, &dummy, - &data->msg_proc); - if (ret) - goto err; - - ret = get_object_info(data, GEN_COMMANDPROCESSOR_T6, &dummy, - &data->cmd_proc); - if (ret) - goto err; - - return 0; - - err: - kfree(object_table); - return ret; -} - -static void resume_cal_err_func(struct mxt540e_data *data) -{ - int i; - bool ta_status; - int count; - u8 id[ID_BLOCK_SIZE]; - int ret; - int retry; - - printk(KERN_DEBUG "[TSP] %s\n", __func__); - cancel_delayed_work(&data->config_dwork); - cancel_delayed_work(&data->resume_check_dwork); - cancel_delayed_work(&data->cal_check_dwork); - data->power_off(); - - count = 0; - for (i = 0; i < data->num_fingers; i++) { - if (data->fingers[i].state == MXT540E_STATE_INACTIVE) - continue; - data->fingers[i].z = 0; - data->fingers[i].state = MXT540E_STATE_INACTIVE; - - input_mt_slot(data->input_dev, i); - input_mt_report_slot_state(data->input_dev, - MT_TOOL_FINGER, false); - -#if 0 -#if defined(CONFIG_SHAPE_TOUCH) - if (get_sec_debug_level() != 0) - printk(KERN_DEBUG - "[TSP] id[%d],x=%d,y=%d,z=%d,w=%d,com=%d\n", i, - data->fingers[i].x, data->fingers[i].y, - data->fingers[i].z, data->fingers[i].w, - data->fingers[i].component); - else - printk(KERN_DEBUG "[TSP] id[%d] status:%d\n", i, - data->fingers[i].z); -#else - if (get_sec_debug_level() != 0) - printk(KERN_DEBUG "[TSP] id[%d],x=%d,y=%d,z=%d,w=%d\n", - i, data->fingers[i].x, data->fingers[i].y, - data->fingers[i].z, data->fingers[i].w); - else - printk(KERN_DEBUG "[TSP] id[%d] status:%d\n", i, - data->fingers[i].z); -#endif -#else - if (data->fingers[i].z == 0) - printk(KERN_DEBUG "[TSP] released\n"); - else - printk(KERN_DEBUG "[TSP] pressed\n"); -#endif - count++; - } - - if (count) - input_sync(data->input_dev); - touch_is_pressed = 0; - - msleep(50); - data->power_on(); - - ret = 0; - retry = 3; - ret = read_mem(data, 0, sizeof(id), id); - if (ret) { - while (retry--) { - printk(KERN_DEBUG "[TSP] chip boot failed. retry(%d)\n", - retry); - - data->power_off(); - msleep(200); - data->power_on(); - - ret = read_mem(data, 0, sizeof(id), id); - if (ret == 0 || retry <= 0) - break; - } - } - - if (data->read_ta_status) { - data->read_ta_status(&ta_status); - printk(KERN_DEBUG "[TSP] ta_status is %d\n", ta_status); - mxt540e_ta_probe(ta_status); - } - check_resume_err = 2; - calibrate_chip(data); - check_calibrate = 3; - schedule_delayed_work(&data->config_dwork, HZ * 5); - config_dwork_flag = 3; -} - -static void median_filter_err_func(struct mxt540e_data *data) -{ - struct median_error_t *median_error = data->median_error; - u16 obj_address = 0; - u16 size; - u8 value; - int error = 0; - bool ta_status = 0; - - if (data->read_ta_status) { - data->read_ta_status(&ta_status); - printk(KERN_DEBUG "[TSP] ta_status is %d\n", ta_status); - - if (ta_status) { - get_object_info(data, PROCG_NOISESUPPRESSION_T48, - &size, &obj_address); -#if 0 - value = 33; - error |= write_mem(data, obj_address + 3, 1, &value); -#else - if (median_error->err_cnt_ta >= MEDIANERROR_MAX_TA) { - median_error->err_cnt_ta = 0; - - if (median_error->table_cnt > 3) - median_error->table_cnt = 0; - else - median_error->table_cnt++; - - value = median_error->table_ta - [median_error->table_cnt]; - error |= write_mem(data, obj_address + 3, - 1, &value); - printk(KERN_DEBUG "[TSP] median base_Freq_ta %d\n", - value); - } else { - median_error->err_cnt_ta++; - printk(KERN_DEBUG "[TSP] median error_cnt_ta %d\n", - median_error->err_cnt_ta); - } - - if (median_error->setting_flag) { - median_error->setting_flag = 0; - value = median_error->table_ta[0]; - error |= write_mem(data, obj_address + 3, - 1, &value); - } -#endif - value = 1; - error |= write_mem(data, obj_address + 8, 1, &value); - - value = 2; - error |= write_mem(data, obj_address + 9, 1, &value); - - value = 100; - error |= write_mem(data, obj_address + 17, 1, &value); - - value = 20; - error |= write_mem(data, obj_address + 22, 1, &value); - - value = 2; - error |= write_mem(data, obj_address + 23, 1, &value); - - value = 46; - error |= write_mem(data, obj_address + 25, 1, &value); - - value = 80; - error |= write_mem(data, obj_address + 34, 1, &value); - - value = 35; - error |= write_mem(data, obj_address + 35, 1, &value); - - value = 15; - error |= write_mem(data, obj_address + 37, 1, &value); - - value = 5; - error |= write_mem(data, obj_address + 38, 1, &value); - - value = 65; - error |= write_mem(data, obj_address + 39, 1, &value); - - value = 30; - error |= write_mem(data, obj_address + 41, 1, &value); - - value = 50; - error |= write_mem(data, obj_address + 42, 1, &value); - - value = 7; - error |= write_mem(data, obj_address + 45, 1, &value); - - value = 7; - error |= write_mem(data, obj_address + 46, 1, &value); - - value = 40; - error |= write_mem(data, obj_address + 50, 1, &value); - - value = 32; - error |= write_mem(data, obj_address + 51, 1, &value); - - value = 15; - error |= write_mem(data, obj_address + 52, 1, &value); - - get_object_info(data, SPT_CTECONFIG_T46, - &size, &obj_address); - value = 32; - error |= write_mem(data, obj_address + 3, 1, &value); - - get_object_info(data, SPT_GENERICDATA_T57, - &size, &obj_address); - value = 22; - error |= write_mem(data, obj_address + 1, 1, &value); - } else { - get_object_info(data, TOUCH_MULTITOUCHSCREEN_T9, - &size, &obj_address); - value = 160; - error |= write_mem(data, obj_address + 6, 1, &value); - - value = 45; - error |= write_mem(data, obj_address + 7, 1, &value); - - value = 80; - error |= write_mem(data, obj_address + 13, 1, &value); - - value = 3; - error |= write_mem(data, obj_address + 22, 1, &value); - - value = 2; - error |= write_mem(data, obj_address + 24, 1, &value); - - get_object_info(data, PROCG_NOISESUPPRESSION_T48, - &size, &obj_address); - value = 242; - error |= write_mem(data, obj_address + 2, 1, &value); -#if 0 - value = 20; - error |= write_mem(data, obj_address + 3, 1, &value); -#else - if (median_error->err_cnt_bat >= MEDIANERROR_MAX_BAT) { - median_error->err_cnt_bat = 0; - - if (median_error->table_cnt > 3) - median_error->table_cnt = 0; - else - median_error->table_cnt++; - - value = median_error->table_bat - [median_error->table_cnt]; - error |= write_mem(data, obj_address + 3, - 1, &value); - printk(KERN_DEBUG "[TSP] median base_freq_bat %d\n", - value); - } else { - median_error->err_cnt_bat++; - printk(KERN_DEBUG "[TSP] median error_cnt_bat %d\n", - median_error->err_cnt_bat); - } - - if (median_error->setting_flag) { - median_error->setting_flag = 0; - value = median_error->table_bat[0]; - error |= write_mem(data, obj_address + 3, - 1, &value); - } -#endif - value = 100; - error |= write_mem(data, obj_address + 17, 1, &value); - - value = 25; - error |= write_mem(data, obj_address + 22, 1, &value); - - value = 46; - error |= write_mem(data, obj_address + 25, 1, &value); - - value = 112; - error |= write_mem(data, obj_address + 34, 1, &value); - - value = 35; - error |= write_mem(data, obj_address + 35, 1, &value); - - value = 0; - error |= write_mem(data, obj_address + 39, 1, &value); - - value = 40; - error |= write_mem(data, obj_address + 42, 1, &value); - - get_object_info(data, SPT_CTECONFIG_T46, - &size, &obj_address); - value = 32; - error |= write_mem(data, obj_address + 3, 1, &value); - - get_object_info(data, SPT_GENERICDATA_T57, - &size, &obj_address); - value = 15; - error |= write_mem(data, obj_address + 1, 1, &value); - } - if (error) - printk(KERN_ERR "[TSP] fail median filter err setting\n"); - else - printk(KERN_DEBUG "[TSP] success median filter err setting\n"); - - } else { - get_object_info(data, PROCG_NOISESUPPRESSION_T48, - &size, &obj_address); - value = 0; - error |= write_mem(data, obj_address + 2, 1, &value); - msleep(20); - value = data->calcfg_batt_e; - error |= write_mem(data, obj_address + 2, 1, &value); - if (error) - printk(KERN_ERR "[TSP] failed to reenable CHRGON\n"); - else - printk(KERN_DEBUG "[TSP] success reenable CHRGON\n"); - } - -} - -static void calibration_check_func(struct mxt540e_data *data) -{ - u16 obj_address = 0; - u16 size; - u8 value; - int error; - - if (check_calibrate == 3) - check_calibrate = 0; - else if (check_calibrate == 1) { - cancel_delayed_work(&data->cal_check_dwork); - schedule_delayed_work(&data->cal_check_dwork, - msecs_to_jiffies(1400)); - } else { - check_calibrate = 1; - value = 6; - get_object_info(data, GEN_POWERCONFIG_T7, - &size, &obj_address); - error = write_mem(data, obj_address + 2, 1, &value); - if (error < 0) - printk(KERN_ERR "[TSP] %s, %d Error!!\n", - __func__, __LINE__); - schedule_delayed_work(&data->cal_check_dwork, - msecs_to_jiffies(1400)); - } - - if (config_dwork_flag == 3) - config_dwork_flag = 1; - else if (config_dwork_flag == 1) { - cancel_delayed_work(&data->config_dwork); - schedule_delayed_work(&data->config_dwork, HZ * 5); - } else { - config_dwork_flag = 1; - get_object_info(data, GEN_ACQUISITIONCONFIG_T8, - &size, &obj_address); - value = 8; - error = write_mem(data, obj_address + 8, 1, &value); - value = 180; - error |= write_mem(data, obj_address + 9, 1, &value); - if (error < 0) - printk(KERN_ERR "[TSP] %s, %d Error!!\n", - __func__, __LINE__); - schedule_delayed_work(&data->config_dwork, HZ * 5); - } - -} - -static void report_input_data(struct mxt540e_data *data) -{ - int i; - int count = 0; - int report_count = 0; - int press_count = 0; - int move_count = 0; - - for (i = 0; i < data->num_fingers; i++) { - if (data->fingers[i].state == MXT540E_STATE_INACTIVE) - continue; - - if (data->fingers[i].state == MXT540E_STATE_RELEASE) { - input_mt_slot(data->input_dev, i); - input_mt_report_slot_state(data->input_dev, - MT_TOOL_FINGER, false); - } else { - input_mt_slot(data->input_dev, i); - input_mt_report_slot_state(data->input_dev, - MT_TOOL_FINGER, true); - input_report_abs(data->input_dev, ABS_MT_POSITION_X, - data->fingers[i].x); - input_report_abs(data->input_dev, ABS_MT_POSITION_Y, - data->fingers[i].y); - input_report_abs(data->input_dev, ABS_MT_PRESSURE, - data->fingers[i].z); - input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, - data->fingers[i].w); - input_report_abs(data->input_dev, ABS_MT_COMPONENT, - data->fingers[i].component); - input_report_abs(data->input_dev, ABS_MT_SUMSIZE, - sumsize); - } - report_count++; - - if (data->fingers[i].state == MXT540E_STATE_PRESS - || data->fingers[i].state == MXT540E_STATE_RELEASE) { -#if 0 - printk(KERN_DEBUG - "[TSP] id[%d],x=%d,y=%d,z=%d,w=%d,com=%d\n", i, - data->fingers[i].x, data->fingers[i].y, - data->fingers[i].z, data->fingers[i].w, - data->fingers[i].component); -#else - if (data->fingers[i].z == 0) - printk(KERN_DEBUG "[TSP][%d] released\n", i); - else - printk(KERN_DEBUG "[TSP][%d] pressed\n", i); -#endif - } - - if (check_resume_err != 0) { - if (data->fingers[i].state == MXT540E_STATE_MOVE) - move_count++; - if (data->fingers[i].state == MXT540E_STATE_PRESS) - press_count++; - } - - if (data->fingers[i].state == MXT540E_STATE_RELEASE) { - data->fingers[i].state = MXT540E_STATE_INACTIVE; - } else { - data->fingers[i].state = MXT540E_STATE_MOVE; - count++; - } - } - if (report_count > 0) - input_sync(data->input_dev); - - if (count) - touch_is_pressed = 1; - else - touch_is_pressed = 0; - - if (count == 0) { - sumsize = 0; - if (data->cpu_freq_lock != -1) { - if (touch_cpu_lock_status) { - exynos_cpufreq_lock_free(DVFS_LOCK_ID_TSP); - touch_cpu_lock_status = 0; - } - } - } - data->finger_mask = 0; - - if (check_resume_err != 0) { - if ((press_count > 0) && (move_count > 0)) { - check_resume_err_count++; - if (check_resume_err_count > 4) { - check_resume_err_count = 0; - resume_cal_err_func(data); - } - } - } - - if (check_calibrate == 1) { - if (touch_is_pressed) - cancel_delayed_work(&data->cal_check_dwork); - else - schedule_delayed_work(&data->cal_check_dwork, - msecs_to_jiffies(1400)); - } -} - -static irqreturn_t mxt540e_irq_thread(int irq, void *ptr) -{ - struct mxt540e_data *data = ptr; - int id; - u8 msg[data->msg_object_size]; - u8 touch_message_flag = 0; - u8 object_type, instance; - - if (data->cpu_freq_lock == -1) - exynos_cpufreq_get_level(500000, &data->cpu_freq_lock); - - do { - touch_message_flag = 0; - if (read_mem(data, data->msg_proc, sizeof(msg), msg)) { - if (data->cpu_freq_lock != -1) { - if (touch_cpu_lock_status) { - exynos_cpufreq_lock_free - (DVFS_LOCK_ID_TSP); - touch_cpu_lock_status = 0; - } - } - return IRQ_HANDLED; - } - - object_type = reportid_to_type(data, msg[0], &instance); - - if (object_type == GEN_COMMANDPROCESSOR_T6) { - if (msg[1] == 0x00) { /* normal mode */ - printk(KERN_DEBUG "[TSP] normal mode\n"); - } - if ((msg[1] & 0x04) == 0x04) { /* I2C checksum error */ - printk(KERN_DEBUG "[TSP] I2C checksum error\n"); - } - if ((msg[1] & 0x08) == 0x08) { /* config error */ - printk(KERN_DEBUG "[TSP] config error\n"); - } - if ((msg[1] & 0x10) == 0x10) { /* calibration */ - printk(KERN_DEBUG "[TSP] calibration is on going\n"); - calibration_check_func(data); - } - if ((msg[1] & 0x20) == 0x20) { /* signal error */ - printk(KERN_DEBUG "[TSP] signal error\n"); - } - if ((msg[1] & 0x40) == 0x40) { /* overflow */ - printk(KERN_DEBUG "[TSP] overflow detected\n"); - } - if ((msg[1] & 0x80) == 0x80) { /* reset */ - printk(KERN_DEBUG "[TSP] reset is ongoing\n"); - } - } - - if (object_type == PROCI_TOUCHSUPPRESSION_T42) { - if ((msg[1] & 0x01) == 0x00) { /* Palm release */ - printk(KERN_DEBUG "[TSP] palm touch released\n"); - touch_is_pressed = 0; - } else if ((msg[1] & 0x01) == 0x01) { /* Palm Press */ - printk(KERN_DEBUG "[TSP] palm touch detected\n"); - touch_is_pressed = 1; - touch_message_flag = 1; - } - } - - if (object_type == SPT_GENERICDATA_T57) - sumsize = msg[1] + (msg[2] << 8); - - if (object_type == PROCG_NOISESUPPRESSION_T48) { - if (msg[4] == 5) { /* Median filter error */ - printk(KERN_DEBUG "[TSP] Median filter Error\n"); - median_filter_err_func(data); - } - } - - if (object_type == TOUCH_MULTITOUCHSCREEN_T9) { - id = msg[0] - data->finger_type; - - /* If not a touch event, then keep going */ - if (id < 0 || id >= data->num_fingers) - continue; - - if (data->finger_mask & (1U << id)) - report_input_data(data); - - if (msg[1] & RELEASE_MSG_MASK) { - data->fingers[id].z = 0; - data->fingers[id].w = msg[5]; - data->finger_mask |= 1U << id; - data->fingers[id].state = MXT540E_STATE_RELEASE; - } else if ((msg[1] & DETECT_MSG_MASK) && - (msg[1] & (PRESS_MSG_MASK | MOVE_MSG_MASK - | VECTOR_MSG_MASK))) { - if (data->cpu_freq_lock != -1) { - if (touch_cpu_lock_status == 0) { - exynos_cpufreq_lock - (DVFS_LOCK_ID_TSP, - data->cpu_freq_lock); - touch_cpu_lock_status = 1; - } - } - touch_message_flag = 1; - data->fingers[id].component = msg[7]; - data->fingers[id].z = msg[6]; - data->fingers[id].w = msg[5]; - data->fingers[id].x = - ((msg[2] << 4) | (msg[4] >> 4)) >> - data->x_dropbits; - data->fingers[id].y = - ((msg[3] << 4) | (msg[4] & 0xF)) >> - data->y_dropbits; - data->finger_mask |= 1U << id; -#if defined(DRIVER_FILTER) - if (msg[1] & PRESS_MSG_MASK) { - equalize_coordinate(1, id, - &data->fingers[id].x, - &data->fingers[id].y); - data->fingers[id].state = - MXT540E_STATE_PRESS; - } else if (msg[1] & MOVE_MSG_MASK) { - equalize_coordinate(0, id, - &data->fingers[id].x, - &data->fingers[id].y); - } -#else - if (msg[1] & PRESS_MSG_MASK) { - data->fingers[id].state = - MXT540E_STATE_PRESS; - } -#endif - - data->fingers[id].component = msg[7]; - - - } else if ((msg[1] & SUPPRESS_MSG_MASK) - && (data->fingers[id].state != - MXT540E_STATE_INACTIVE)) { - data->fingers[id].z = 0; - data->fingers[id].w = msg[5]; - data->fingers[id].state = MXT540E_STATE_RELEASE; - data->finger_mask |= 1U << id; - } else { - dev_dbg(&data->client->dev, - "Unknown state %#02x %#02x\n", msg[0], - msg[1]); - continue; - } - } - } while (!gpio_get_value(data->gpio_read_done)); - - if (data->finger_mask) - report_input_data(data); - - return IRQ_HANDLED; -} - -#if 0 -static void mxt540e_deepsleep(struct mxt540e_data *data) -{ - u8 power_cfg[3] = { 0, }; - write_config(data, GEN_POWERCONFIG_T7, power_cfg); - deepsleep = 1; -} -#endif -static void mxt540e_wakeup(struct mxt540e_data *data) -{ - write_config(data, GEN_POWERCONFIG_T7, data->power_cfg); -} - -static int mxt540e_internal_suspend(struct mxt540e_data *data) -{ - int i; - cancel_delayed_work(&data->config_dwork); - cancel_delayed_work(&data->resume_check_dwork); - cancel_delayed_work(&data->cal_check_dwork); - - for (i = 0; i < data->num_fingers; i++) { - if (data->fingers[i].state == MXT540E_STATE_INACTIVE) - continue; - data->fingers[i].z = 0; - data->fingers[i].state = MXT540E_STATE_RELEASE; - } - report_input_data(data); - if (!deepsleep) - data->power_off_with_oleddet(); - return 0; -} - -static int mxt540e_internal_resume(struct mxt540e_data *data) -{ - if (!deepsleep) - data->power_on_with_oleddet(); - else - mxt540e_wakeup(data); -#if 0 - calibrate_chip(data); - schedule_delayed_work(&data->config_dwork, HZ * 5); -#endif - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -#define mxt540e_suspend NULL -#define mxt540e_resume NULL - -static void mxt540e_early_suspend(struct early_suspend *h) -{ - struct mxt540e_data *data = container_of(h, struct mxt540e_data, - early_suspend); - if (mxt540e_enabled) { - printk(KERN_DEBUG "[TSP] %s\n", __func__); - mxt540e_enabled = 0; - touch_is_pressed = 0; - - disable_irq(data->client->irq); - mxt540e_internal_suspend(data); - } else { - printk(KERN_DEBUG "[TSP] %s, but already off\n", __func__); - } -} - -static void mxt540e_late_resume(struct early_suspend *h) -{ - struct mxt540e_data *data = container_of(h, struct mxt540e_data, - early_suspend); - bool ta_status = 0; - u8 id[ID_BLOCK_SIZE]; - int ret = 0; - int retry = 3; - - if (mxt540e_enabled == 0) { - printk(KERN_DEBUG "[TSP] %s\n", __func__); - mxt540e_internal_resume(data); - - mxt540e_enabled = 1; - - ret = read_mem(data, 0, sizeof(id), id); - if (ret) { - while (retry--) { - printk(KERN_DEBUG "[TSP] chip boot failed." - "retry(%d)\n", retry); - - data->power_off(); - msleep(200); - data->power_on(); - - ret = read_mem(data, 0, sizeof(id), id); - if (ret == 0 || retry <= 0) - break; - } - } - - if (data->read_ta_status) { - data->read_ta_status(&ta_status); - printk(KERN_DEBUG "[TSP] ta_status is %d\n", ta_status); - mxt540e_ta_probe(ta_status); - } - if (deepsleep) - deepsleep = 0; - - check_resume_err = 2; - calibrate_chip(data); - check_calibrate = 3; - schedule_delayed_work(&data->config_dwork, HZ * 5); - config_dwork_flag = 3; - enable_irq(data->client->irq); - } else { - printk(KERN_DEBUG "[TSP] %s, but already on\n", __func__); - } -} -#else -static int mxt540e_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct mxt540e_data *data = i2c_get_clientdata(client); - - mxt540e_enabled = 0; - touch_is_pressed = 0; - disable_irq(data->client->irq); - return mxt540e_internal_suspend(data); -} - -static int mxt540e_resume(struct device *dev) -{ - int ret = 0; - bool ta_status = 0; - struct i2c_client *client = to_i2c_client(dev); - struct mxt540e_data *data = i2c_get_clientdata(client); - - ret = mxt540e_internal_resume(data); - - mxt540e_enabled = 1; - - if (data->read_ta_status) { - data->read_ta_status(&ta_status); - printk(KERN_DEBUG "[TSP] ta_status is %d\n", ta_status); - mxt540e_ta_probe(ta_status); - } - enable_irq(data->client->irq); - return ret; -} -#endif - -void Mxt540e_force_released(void) -{ - struct mxt540e_data *data = copy_data; - int i; - - if (!mxt540e_enabled) { - printk(KERN_ERR "[TSP] mxt540e_enabled is 0\n"); - return; - } - - for (i = 0; i < data->num_fingers; i++) { - if (data->fingers[i].state == MXT540E_STATE_INACTIVE) - continue; - data->fingers[i].z = 0; - data->fingers[i].state = MXT540E_STATE_RELEASE; - } - report_input_data(data); - calibrate_chip(data); -}; -EXPORT_SYMBOL(Mxt540e_force_released); - -static ssize_t mxt540e_debug_setting(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - g_debug_switch = !g_debug_switch; - return 0; -} - -static ssize_t mxt540e_object_setting(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct mxt540e_data *data = dev_get_drvdata(dev); - unsigned int object_type; - unsigned int object_register; - unsigned int register_value; - u8 value; - u8 val; - int ret; - u16 address; - u16 size; - sscanf(buf, "%u%u%u", &object_type, &object_register, ®ister_value); - printk(KERN_ERR "[TSP] object type T%d", object_type); - printk(KERN_ERR "[TSP] object register ->Byte%d\n", object_register); - printk(KERN_ERR "[TSP] register value %d\n", register_value); - ret = get_object_info(data, (u8) object_type, &size, &address); - if (ret) { - printk(KERN_ERR "[TSP] fail to get object_info\n"); - return count; - } - - size = 1; - value = (u8) register_value; - write_mem(data, address + (u16) object_register, size, &value); - read_mem(data, address + (u16) object_register, (u8) size, &val); - - printk(KERN_ERR "[TSP] T%d Byte%d is %d\n", object_type, - object_register, val); - return count; -} - -static ssize_t mxt540e_object_show(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct mxt540e_data *data = dev_get_drvdata(dev); - unsigned int object_type; - u8 val; - int ret; - u16 address; - u16 size; - u16 i; - sscanf(buf, "%u", &object_type); - printk(KERN_DEBUG "[TSP] object type T%d\n", object_type); - ret = get_object_info(data, (u8) object_type, &size, &address); - if (ret) { - printk(KERN_ERR "[TSP] fail to get object_info\n"); - return count; - } - for (i = 0; i < size; i++) { - read_mem(data, address + i, 1, &val); - printk(KERN_DEBUG "[TSP] Byte %u --> %u\n", i, val); - } - return count; -} - -int get_tsp_status(void) -{ - return touch_is_pressed; -} - -void diagnostic_chip(u8 mode) -{ - int error; - u16 t6_address = 0; - u16 size_one; - int ret; - - ret = get_object_info(copy_data, GEN_COMMANDPROCESSOR_T6, - &size_one, &t6_address); - - size_one = 1; - error = write_mem(copy_data, t6_address + 5, (u8) size_one, &mode); - - if (error < 0) - printk(KERN_ERR "[TSP] error %s: write_object\n", __func__); -} - -uint8_t read_uint16_t(struct mxt540e_data *data, uint16_t address, - uint16_t *buf) -{ - uint8_t status; - uint8_t temp[2]; - - status = read_mem(data, address, 2, temp); - *buf = ((uint16_t) temp[1] << 8) + (uint16_t) temp[0]; - - return status; -} - -void read_dbg_data(uint8_t dbg_mode, uint16_t node, uint16_t *dbg_data) -{ - u8 read_page, read_point; - uint8_t mode, page; - u16 size; - u16 diagnostic_addr = 0; - - if (!mxt540e_enabled) { - printk(KERN_ERR "[TSP ]read_dbg_data. mxt540e_enabled is 0\n"); - return; - } - - get_object_info(copy_data, DEBUG_DIAGNOSTIC_T37, &size, - &diagnostic_addr); - - read_page = node / 64; - node %= 64; - read_point = (node * 2) + 2; - - /* Page Num Clear */ - diagnostic_chip(MXT_CTE_MODE); - msleep(20); - - do { - if (read_mem(copy_data, diagnostic_addr, 1, &mode)) { - printk(KERN_INFO "[TSP] READ_MEM_FAILED\n"); - return; - } - } while (mode != MXT_CTE_MODE); - - diagnostic_chip(dbg_mode); - msleep(20); - - do { - if (read_mem(copy_data, diagnostic_addr, 1, &mode)) { - printk(KERN_INFO "[TSP] READ_MEM_FAILED\n"); - return; - } - } while (mode != dbg_mode); - - for (page = 1; page <= read_page; page++) { - diagnostic_chip(MXT_PAGE_UP); - msleep(20); - do { - if (read_mem(copy_data, diagnostic_addr + 1, 1, - &mode)) { - printk(KERN_INFO "[TSP] READ_MEM_FAILED\n"); - return; - } - } while (mode != page); - } - - if (read_uint16_t(copy_data, diagnostic_addr + read_point, dbg_data)) { - printk(KERN_INFO "[TSP] READ_MEM_FAILED\n"); - return; - } -} - -#define MIN_VALUE 19744 -#define MAX_VALUE 28864 - -int read_all_data(uint16_t dbg_mode) -{ - u8 read_page, read_point; - u16 max_value = MIN_VALUE, min_value = MAX_VALUE; - u16 object_address = 0; - u8 data_buffer[2] = { 0 }; - u8 node = 0; - int state = 0; - int num = 0; - int ret; - u16 size; - - /* Page Num Clear */ - diagnostic_chip(MXT_CTE_MODE); - msleep(30); - - diagnostic_chip(dbg_mode); - msleep(30); - - ret = get_object_info(copy_data, DEBUG_DIAGNOSTIC_T37, - &size, &object_address); - msleep(50); - - for (read_page = 0; read_page < 9; read_page++) { - for (node = 0; node < 64; node++) { - read_point = (node * 2) + 2; - read_mem(copy_data, object_address + (u16) read_point, - 2, data_buffer); - qt_refrence_node[num] = - ((uint16_t) data_buffer[1] << 8) + - (uint16_t) data_buffer[0]; -#ifdef CONFIG_MACH_Q1_BD - /* q1 use x=16 line, y=26 line */ - if ((num % 30 == 26) || (num % 30 == 27) - || (num % 30 == 28) || (num % 30 == 29)) { - num++; - if (num == 480) - break; - else - continue; - } -#endif - if ((qt_refrence_node[num] < MIN_VALUE) - || (qt_refrence_node[num] > MAX_VALUE)) { - state = 1; - printk(KERN_ERR - "[TSP] Mxt540E qt_refrence_node[%3d] = %5d\n", - num, qt_refrence_node[num]); - } - - if (data_buffer[0] != 0) { - if (qt_refrence_node[num] > max_value) - max_value = qt_refrence_node[num]; - if (qt_refrence_node[num] < min_value) - min_value = qt_refrence_node[num]; - } - num++; -#ifdef CONFIG_MACH_Q1_BD - if (num == 480) - break; -#endif - /* all node => 18 * 30 = 540 => (8page * 64) + 28 */ - if ((read_page == 8) && (node == 28)) - break; - } - diagnostic_chip(MXT_PAGE_UP); - msleep(35); -#ifdef CONFIG_MACH_Q1_BD - if (num == 480) - break; -#endif - } - - if ((max_value - min_value) > 4500) { - printk(KERN_ERR - "[TSP] diff = %d, max_value = %d, min_value = %d\n", - (max_value - min_value), max_value, min_value); - state = 1; - } - - return state; -} - -int read_all_delta_data(uint16_t dbg_mode) -{ - u8 read_page, read_point; - u16 object_address = 0; - u8 data_buffer[2] = { 0 }; - u8 node = 0; - int state = 0; - int num = 0; - int ret; - u16 size; - - /* Page Num Clear */ - diagnostic_chip(MXT_CTE_MODE); - msleep(30); - - diagnostic_chip(dbg_mode); - msleep(30); - - ret = get_object_info(copy_data, DEBUG_DIAGNOSTIC_T37, - &size, &object_address); - msleep(50); - - for (read_page = 0; read_page < 9; read_page++) { - for (node = 0; node < 64; node++) { - read_point = (node * 2) + 2; - read_mem(copy_data, object_address + (u16) read_point, - 2, data_buffer); - qt_delta_node[num] = - ((uint16_t) data_buffer[1] << 8) + - (uint16_t) data_buffer[0]; - - num++; - - /* all node => 18 * 30 = 540 => (8page * 64) + 28 */ - if ((read_page == 8) && (node == 28)) - break; - } - diagnostic_chip(MXT_PAGE_UP); - msleep(35); - } - - return state; -} - -static int mxt540e_check_bootloader(struct i2c_client *client, - unsigned int state) -{ - u8 val; - u8 temp; - - recheck: - if (i2c_master_recv(client, &val, 1) != 1) { - dev_err(&client->dev, "%s: i2c recv failed\n", __func__); - return -EIO; - } - - if (val & 0x20) { - - if (i2c_master_recv(client, &temp, 1) != 1) { - dev_err(&client->dev, "%s: i2c recv failed\n", - __func__); - return -EIO; - } - - if (i2c_master_recv(client, &temp, 1) != 1) { - dev_err(&client->dev, "%s: i2c recv failed\n", - __func__); - return -EIO; - } - - val &= ~0x20; - } - - if ((val & 0xF0) == MXT540E_APP_CRC_FAIL) { - printk(KERN_DEBUG "[TOUCH] MXT540E_APP_CRC_FAIL\n"); - if (i2c_master_recv(client, &val, 1) != 1) { - dev_err(&client->dev, "%s: i2c recv failed\n", - __func__); - return -EIO; - } - - if (val & 0x20) { - if (i2c_master_recv(client, &temp, 1) != 1) { - dev_err(&client->dev, "%s: i2c recv failed\n", - __func__); - return -EIO; - } - - if (i2c_master_recv(client, &temp, 1) != 1) { - dev_err(&client->dev, "%s: i2c recv failed\n", - __func__); - return -EIO; - } - - val &= ~0x20; - } - } - - switch (state) { - case MXT540E_WAITING_BOOTLOAD_CMD: - case MXT540E_WAITING_FRAME_DATA: - val &= ~MXT540E_BOOT_STATUS_MASK; - break; - case MXT540E_FRAME_CRC_PASS: - if (val == MXT540E_FRAME_CRC_CHECK) - goto recheck; - break; - default: - return -EINVAL; - } - - if (val != state) { - dev_err(&client->dev, "Unvalid bootloader mode state\n"); - printk(KERN_ERR "[TSP] Unvalid bootloader mode state\n"); - return -EINVAL; - } - - return 0; -} - -static int mxt540e_unlock_bootloader(struct i2c_client *client) -{ - u8 buf[2]; - - buf[0] = MXT540E_UNLOCK_CMD_LSB; - buf[1] = MXT540E_UNLOCK_CMD_MSB; - - if (i2c_master_send(client, buf, 2) != 2) { - dev_err(&client->dev, "%s: i2c send failed\n", __func__); - return -EIO; - } - - return 0; -} - -static int mxt540e_fw_write(struct i2c_client *client, - const u8 *data, unsigned int frame_size) -{ - if (i2c_master_send(client, data, frame_size) != frame_size) { - dev_err(&client->dev, "%s: i2c send failed\n", __func__); - return -EIO; - } - - return 0; -} - -static int mxt540e_load_fw(struct device *dev, const char *fn) -{ - struct mxt540e_data *data = copy_data; - struct i2c_client *client = copy_data->client; - const struct firmware *fw = NULL; - unsigned int frame_size; - unsigned int pos = 0; - int ret; - u16 obj_address = 0; - u16 size_one; - u8 value; - unsigned int object_register; - int check_frame_crc_error = 0; - int check_wating_frame_data_error = 0; - - printk(KERN_DEBUG "[TSP] mxt540e_load_fw start!!!\n"); - - ret = request_firmware(&fw, fn, &client->dev); - if (ret) { - dev_err(dev, "Unable to open firmware %s\n", fn); - printk(KERN_ERR "[TSP] Unable to open firmware %s\n", fn); - return ret; - } - - /* Change to the bootloader mode */ - object_register = 0; - value = (u8) MXT540E_BOOT_VALUE; - ret = get_object_info(data, GEN_COMMANDPROCESSOR_T6, - &size_one, &obj_address); - if (ret) { - printk(KERN_ERR "[TSP] fail to get object_info\n"); - release_firmware(fw); - return ret; - } - size_one = 1; - write_mem(data, obj_address + (u16) object_register, (u8) size_one, - &value); - msleep(MXT540E_SW_RESET_TIME); - - /* Change to slave address of bootloader */ - if (client->addr == MXT540E_APP_LOW) - client->addr = MXT540E_BOOT_LOW; - else - client->addr = MXT540E_BOOT_HIGH; - - ret = mxt540e_check_bootloader(client, MXT540E_WAITING_BOOTLOAD_CMD); - if (ret) - goto out; - - /* Unlock bootloader */ - mxt540e_unlock_bootloader(client); - - while (pos < fw->size) { - ret = mxt540e_check_bootloader(client, - MXT540E_WAITING_FRAME_DATA); - if (ret) { - check_wating_frame_data_error++; - if (check_wating_frame_data_error > 10) { - printk(KERN_ERR - "[TSP] firm update fail. wating_frame_data err\n"); - goto out; - } else { - printk(KERN_ERR - "[TSP]check_wating_frame_data_error = %d, " - "retry\n", - check_wating_frame_data_error); - continue; - } - } - - frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); - - /* We should add 2 at frame size as the the firmware data is not - * included the CRC bytes. - */ - frame_size += 2; - - /* Write one frame to device */ - mxt540e_fw_write(client, fw->data + pos, frame_size); - - ret = mxt540e_check_bootloader(client, MXT540E_FRAME_CRC_PASS); - if (ret) { - check_frame_crc_error++; - if (check_frame_crc_error > 10) { - printk(KERN_ERR - "[TSP] firm update fail. frame_crc err\n"); - goto out; - } else { - printk(KERN_ERR - "[TSP]check_frame_crc_error = %d, " - "retry\n", - check_frame_crc_error); - continue; - } - } - - pos += frame_size; - - dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); - printk(KERN_DEBUG "[TSP] Updated %d bytes / %zd bytes\n", - pos, fw->size); - - msleep(20); - } - - out: - release_firmware(fw); - - /* Change to slave address of application */ - if (client->addr == MXT540E_BOOT_LOW) - client->addr = MXT540E_APP_LOW; - else - client->addr = MXT540E_APP_HIGH; - - return ret; -} - -static int mxt540e_load_fw_bootmode(struct device *dev, const char *fn) -{ - struct i2c_client *client = copy_data->client; - const struct firmware *fw = NULL; - unsigned int frame_size; - unsigned int pos = 0; - int ret; - int check_frame_crc_error = 0; - int check_wating_frame_data_error = 0; - - printk(KERN_DEBUG "[TSP] mxt540e_load_fw start!!!\n"); - - ret = request_firmware(&fw, fn, &client->dev); - if (ret) { - dev_err(dev, "Unable to open firmware %s\n", fn); - printk(KERN_ERR "[TSP] Unable to open firmware %s\n", fn); - return ret; - } - - /* Unlock bootloader */ - mxt540e_unlock_bootloader(client); - - while (pos < fw->size) { - ret = mxt540e_check_bootloader(client, - MXT540E_WAITING_FRAME_DATA); - if (ret) { - check_wating_frame_data_error++; - if (check_wating_frame_data_error > 10) { - printk(KERN_ERR - "[TSP] firm update fail. wating_frame_data err\n"); - goto out; - } else { - printk(KERN_ERR - "[TSP]check_wating_frame_data_error = %d, " - "retry\n", - check_wating_frame_data_error); - continue; - } - } - - frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); - - /* We should add 2 at frame size as the the firmware data is not - * included the CRC bytes. - */ - frame_size += 2; - - /* Write one frame to device */ - mxt540e_fw_write(client, fw->data + pos, frame_size); - - ret = mxt540e_check_bootloader(client, MXT540E_FRAME_CRC_PASS); - if (ret) { - check_frame_crc_error++; - if (check_frame_crc_error > 10) { - printk(KERN_ERR - "[TSP] firm update fail. frame_crc err\n"); - goto out; - } else { - printk(KERN_ERR - "[TSP]check_frame_crc_error = %d, " - "retry\n", - check_frame_crc_error); - continue; - } - } - - pos += frame_size; - - dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); - printk(KERN_DEBUG "[TSP] Updated %d bytes / %zd bytes\n", - pos, fw->size); - - msleep(20); - } - - out: - release_firmware(fw); - - /* Change to slave address of application */ - if (client->addr == MXT540E_BOOT_LOW) - client->addr = MXT540E_APP_LOW; - else - client->addr = MXT540E_APP_HIGH; - - return ret; -} - -static ssize_t set_refer0_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_reference = 0; - read_dbg_data(MXT_REFERENCE_MODE, test_node[0], &mxt_reference); - return sprintf(buf, "%u\n", mxt_reference); -} - -static ssize_t set_refer1_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_reference = 0; - read_dbg_data(MXT_REFERENCE_MODE, test_node[1], &mxt_reference); - return sprintf(buf, "%u\n", mxt_reference); -} - -static ssize_t set_refer2_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_reference = 0; - read_dbg_data(MXT_REFERENCE_MODE, test_node[2], &mxt_reference); - return sprintf(buf, "%u\n", mxt_reference); -} - -static ssize_t set_refer3_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_reference = 0; - read_dbg_data(MXT_REFERENCE_MODE, test_node[3], &mxt_reference); - return sprintf(buf, "%u\n", mxt_reference); -} - -static ssize_t set_refer4_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_reference = 0; - read_dbg_data(MXT_REFERENCE_MODE, test_node[4], &mxt_reference); - return sprintf(buf, "%u\n", mxt_reference); -} - -static ssize_t set_delta0_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_delta = 0; - read_dbg_data(MXT_DELTA_MODE, test_node[0], &mxt_delta); - if (mxt_delta < 32767) - return sprintf(buf, "%u\n", mxt_delta); - else - mxt_delta = 65535 - mxt_delta; - - if (mxt_delta) - return sprintf(buf, "-%u\n", mxt_delta); - else - return sprintf(buf, "%u\n", mxt_delta); -} - -static ssize_t set_delta1_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_delta = 0; - read_dbg_data(MXT_DELTA_MODE, test_node[1], &mxt_delta); - if (mxt_delta < 32767) - return sprintf(buf, "%u\n", mxt_delta); - else - mxt_delta = 65535 - mxt_delta; - - if (mxt_delta) - return sprintf(buf, "-%u\n", mxt_delta); - else - return sprintf(buf, "%u\n", mxt_delta); -} - -static ssize_t set_delta2_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_delta = 0; - read_dbg_data(MXT_DELTA_MODE, test_node[2], &mxt_delta); - if (mxt_delta < 32767) - return sprintf(buf, "%u\n", mxt_delta); - else - mxt_delta = 65535 - mxt_delta; - - if (mxt_delta) - return sprintf(buf, "-%u\n", mxt_delta); - else - return sprintf(buf, "%u\n", mxt_delta); -} - -static ssize_t set_delta3_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_delta = 0; - read_dbg_data(MXT_DELTA_MODE, test_node[3], &mxt_delta); - if (mxt_delta < 32767) - return sprintf(buf, "%u\n", mxt_delta); - else - mxt_delta = 65535 - mxt_delta; - - if (mxt_delta) - return sprintf(buf, "-%u\n", mxt_delta); - else - return sprintf(buf, "%u\n", mxt_delta); -} - -static ssize_t set_delta4_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - uint16_t mxt_delta = 0; - read_dbg_data(MXT_DELTA_MODE, test_node[4], &mxt_delta); - if (mxt_delta < 32767) - return sprintf(buf, "%u\n", mxt_delta); - else - mxt_delta = 65535 - mxt_delta; - - if (mxt_delta) - return sprintf(buf, "-%u\n", mxt_delta); - else - return sprintf(buf, "%u\n", mxt_delta); -} - -static ssize_t set_threshold_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", threshold); -} - -static ssize_t set_all_refer_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int status = 0; - - status = read_all_data(MXT_REFERENCE_MODE); - - return sprintf(buf, "%u\n", status); -} - -static int index_reference; - -ssize_t disp_all_refdata_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", qt_refrence_node[index_reference]); -} - -ssize_t disp_all_refdata_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - int reference; - - sscanf(buf, "%u", &reference); - printk(KERN_DEBUG "%u\n", reference); - index_reference = reference; - - return size; -} - -static ssize_t set_all_delta_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int status = 0; - - status = read_all_delta_data(MXT_DELTA_MODE); - - return sprintf(buf, "%u\n", status); -} - -static int index_delta; - -ssize_t disp_all_deltadata_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - if (qt_delta_node[index_delta] < 32767) - return sprintf(buf, "%u\n", qt_delta_node[index_delta]); - else - qt_delta_node[index_delta] = 65535 - qt_delta_node[index_delta]; - - return sprintf(buf, "-%u\n", qt_delta_node[index_delta]); -} - -ssize_t disp_all_deltadata_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - int delta; - - sscanf(buf, "%u", &delta); - printk(KERN_DEBUG "%u\n", delta); - index_delta = delta; - - return size; -} - -static ssize_t set_firm_version_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - return sprintf(buf, "%#02x\n", tsp_version_disp); - -} - -static ssize_t set_module_off_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mxt540e_data *data = copy_data; - int count; - - mxt540e_enabled = 0; - touch_is_pressed = 0; - - disable_irq(data->client->irq); - mxt540e_internal_suspend(data); - - count = sprintf(buf, "tspoff\n"); - - return count; -} - -static ssize_t set_module_on_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mxt540e_data *data = copy_data; - int count; - - bool ta_status = 0; - - mxt540e_internal_resume(data); - enable_irq(data->client->irq); - - mxt540e_enabled = 1; - - if (data->read_ta_status) { - data->read_ta_status(&ta_status); - printk(KERN_DEBUG "[TSP] ta_status is %d", ta_status); - mxt540e_ta_probe(ta_status); - } - calibrate_chip(data); - - count = sprintf(buf, "tspon\n"); - - return count; -} - -static ssize_t set_mxt_firm_update_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct mxt540e_data *data = dev_get_drvdata(dev); - int error = 0; - printk(KERN_DEBUG "[TSP] set_mxt_update_show start!!\n"); - if (*buf != 'S' && *buf != 'F') { - printk(KERN_ERR "Invalid values\n"); - dev_err(dev, "Invalid values\n"); - return -EINVAL; - } - - disable_irq(data->client->irq); - firm_status_data = 1; - if (*buf != 'F' && data->tsp_version >= firmware_latest - && data->tsp_build != build_latest) { - printk(KERN_ERR "[TSP] mxt540E has latest firmware\n"); - firm_status_data = 2; - enable_irq(data->client->irq); - return size; - } - printk(KERN_DEBUG "[TSP] mxt540E_fm_update\n"); - error = mxt540e_load_fw(dev, MXT540E_FW_NAME); - - if (error) { - dev_err(dev, "The firmware update failed(%d)\n", error); - firm_status_data = 3; - printk(KERN_ERR "[TSP]The firmware update failed(%d)\n", error); - return error; - } else { - dev_dbg(dev, "The firmware update succeeded\n"); - firm_status_data = 2; - printk(KERN_DEBUG "[TSP] The firmware update succeeded\n"); - - /* Wait for reset */ - msleep(MXT540E_SW_RESET_TIME); - - mxt540e_init_touch_driver(data); - } - - enable_irq(data->client->irq); - error = mxt540e_backup(data); - if (error) { - printk(KERN_ERR "[TSP]mxt540e_backup fail!!!\n"); - return error; - } - - /* reset the touch IC. */ - error = mxt540e_reset(data); - if (error) { - printk(KERN_ERR "[TSP]mxt540e_reset fail!!!\n"); - return error; - } - - msleep(MXT540E_SW_RESET_TIME); - return size; -} - -static ssize_t set_mxt_firm_status_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - int count; - printk(KERN_DEBUG "Enter firmware_status_show by Factory command\n"); - - if (firm_status_data == 1) - count = sprintf(buf, "DOWNLOADING\n"); - else if (firm_status_data == 2) - count = sprintf(buf, "PASS\n"); - else if (firm_status_data == 3) - count = sprintf(buf, "FAIL\n"); - else - count = sprintf(buf, "PASS\n"); - - return count; -} - -static ssize_t key_threshold_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", threshold); -} - -static ssize_t key_threshold_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - /*TO DO IT */ - unsigned int object_register = 7; - u8 value; - u8 val; - int ret; - u16 address = 0; - u16 size_one; - int num; - if (sscanf(buf, "%d", &num) == 1) { - threshold = num; - printk(KERN_DEBUG "threshold value %d\n", threshold); - ret = get_object_info(copy_data, TOUCH_MULTITOUCHSCREEN_T9, - &size_one, &address); - size_one = 1; - value = (u8) threshold; - write_mem(copy_data, address + (u16) object_register, size_one, - &value); - read_mem(copy_data, address + (u16) object_register, - (u8) size_one, &val); - printk(KERN_ERR "T9 Byte%d is %d\n", object_register, val); - } - return size; -} - -static ssize_t set_mxt_firm_version_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - pr_info("Atmel Latest firmware version is %d\n", firmware_latest); - return sprintf(buf, "%#02x\n", firmware_latest); -} - -static ssize_t set_mxt_firm_version_read_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mxt540e_data *data = dev_get_drvdata(dev); - return sprintf(buf, "%#02x\n", data->tsp_version); -} - -static ssize_t mxt_touchtype_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - char temp[15]; - - sprintf(temp, "ATMEL,MXT540E\n"); - strcat(buf, temp); - - return strlen(buf); -} - -static DEVICE_ATTR(set_refer0, S_IRUGO, set_refer0_mode_show, NULL); -static DEVICE_ATTR(set_delta0, S_IRUGO, set_delta0_mode_show, NULL); -static DEVICE_ATTR(set_refer1, S_IRUGO, set_refer1_mode_show, NULL); -static DEVICE_ATTR(set_delta1, S_IRUGO, set_delta1_mode_show, NULL); -static DEVICE_ATTR(set_refer2, S_IRUGO, set_refer2_mode_show, NULL); -static DEVICE_ATTR(set_delta2, S_IRUGO, set_delta2_mode_show, NULL); -static DEVICE_ATTR(set_refer3, S_IRUGO, set_refer3_mode_show, NULL); -static DEVICE_ATTR(set_delta3, S_IRUGO, set_delta3_mode_show, NULL); -static DEVICE_ATTR(set_refer4, S_IRUGO, set_refer4_mode_show, NULL); -static DEVICE_ATTR(set_delta4, S_IRUGO, set_delta4_mode_show, NULL); -static DEVICE_ATTR(set_all_refer, S_IRUGO, set_all_refer_mode_show, NULL); -static DEVICE_ATTR(disp_all_refdata, S_IRUGO | S_IWUSR | S_IWGRP, - disp_all_refdata_show, disp_all_refdata_store); -static DEVICE_ATTR(set_all_delta, S_IRUGO, set_all_delta_mode_show, NULL); -static DEVICE_ATTR(disp_all_deltadata, S_IRUGO | S_IWUSR | S_IWGRP, - disp_all_deltadata_show, disp_all_deltadata_store); -static DEVICE_ATTR(set_threshold, S_IRUGO, set_threshold_mode_show, NULL); -static DEVICE_ATTR(set_firm_version, S_IRUGO | S_IWUSR | S_IWGRP, - set_firm_version_show, NULL); -static DEVICE_ATTR(set_module_off, S_IRUGO | S_IWUSR | S_IWGRP, - set_module_off_show, NULL); -static DEVICE_ATTR(set_module_on, S_IRUGO | S_IWUSR | S_IWGRP, - set_module_on_show, NULL); -static DEVICE_ATTR(tsp_firm_update, S_IWUSR | S_IWGRP, NULL, - set_mxt_firm_update_store); /* firmware update */ -static DEVICE_ATTR(tsp_firm_update_status, S_IRUGO, - set_mxt_firm_status_show, NULL); -static DEVICE_ATTR(tsp_threshold, S_IRUGO | S_IWUSR | S_IWGRP, - key_threshold_show, key_threshold_store); -static DEVICE_ATTR(tsp_firm_version_phone, S_IRUGO, - set_mxt_firm_version_show, NULL); /* PHONE */ -static DEVICE_ATTR(tsp_firm_version_panel, S_IRUGO, - set_mxt_firm_version_read_show, NULL); -static DEVICE_ATTR(mxt_touchtype, S_IRUGO | S_IWUSR | S_IWGRP, - mxt_touchtype_show, NULL); -static DEVICE_ATTR(object_show, S_IWUSR | S_IWGRP, NULL, mxt540e_object_show); -static DEVICE_ATTR(object_write, S_IWUSR | S_IWGRP, NULL, - mxt540e_object_setting); -static DEVICE_ATTR(dbg_switch, S_IWUSR | S_IWGRP, NULL, mxt540e_debug_setting); - -static struct attribute *mxt540e_attrs[] = { - &dev_attr_object_show.attr, - &dev_attr_object_write.attr, - &dev_attr_dbg_switch.attr, - NULL -}; - -static const struct attribute_group mxt540e_attr_group = { - .attrs = mxt540e_attrs, -}; - -static int __devinit mxt540e_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct mxt540e_platform_data *pdata = client->dev.platform_data; - struct mxt540e_data *data; - struct input_dev *input_dev; - struct median_error_t *median_error; - int ret; - int i; - bool ta_status = 0; - u8 **tsp_config; - int retry = 3; - - touch_is_pressed = 0; - - if (!pdata) { - dev_err(&client->dev, "missing platform data\n"); - return -ENODEV; - } - - if (pdata->max_finger_touches <= 0) - return -EINVAL; - - data = kzalloc(sizeof(*data) + pdata->max_finger_touches * - sizeof(*data->fingers), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->num_fingers = pdata->max_finger_touches; - data->power_on = pdata->power_on; - data->power_off = pdata->power_off; - data->power_on_with_oleddet = pdata->power_on_with_oleddet; - data->power_off_with_oleddet = pdata->power_off_with_oleddet; - data->register_cb = pdata->register_cb; - data->read_ta_status = pdata->read_ta_status; - - data->client = client; - i2c_set_clientdata(client, data); - - input_dev = input_allocate_device(); - if (!input_dev) { - ret = -ENOMEM; - dev_err(&client->dev, "input device allocation failed\n"); - goto err_alloc_dev; - } - data->input_dev = input_dev; - input_set_drvdata(input_dev, data); - input_dev->name = "sec_touchscreen"; - - set_bit(EV_SYN, input_dev->evbit); - set_bit(EV_ABS, input_dev->evbit); - set_bit(EV_KEY, input_dev->evbit); - set_bit(MT_TOOL_FINGER, input_dev->keybit); - set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - - input_mt_init_slots(input_dev, MAX_FINGER_NUM); - - input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->min_x, - pdata->max_x, 0, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->min_y, - pdata->max_y, 0, 0); - input_set_abs_params(input_dev, ABS_MT_PRESSURE, pdata->min_z, - pdata->max_z, 0, 0); - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, pdata->min_w, - pdata->max_w, 0, 0); - input_set_abs_params(input_dev, ABS_MT_COMPONENT, 0, 255, 0, 0); - input_set_abs_params(input_dev, ABS_MT_SUMSIZE, 0, 16 * 26, 0, 0); - - ret = input_register_device(input_dev); - if (ret) { - input_free_device(input_dev); - goto err_reg_dev; - } - - data->gpio_read_done = pdata->gpio_read_done; - - data->power_on(); - - copy_data = data; - - if (client->addr == MXT540E_APP_LOW) - client->addr = MXT540E_BOOT_LOW; - else - client->addr = MXT540E_BOOT_HIGH; - - ret = mxt540e_check_bootloader(client, MXT540E_WAITING_BOOTLOAD_CMD); - if (ret >= 0) { - printk(KERN_DEBUG "[TSP] boot mode. firm update excute\n"); - mxt540e_load_fw_bootmode(NULL, MXT540E_FW_NAME); - msleep(MXT540E_SW_RESET_TIME); - } else { - if (client->addr == MXT540E_BOOT_LOW) - client->addr = MXT540E_APP_LOW; - else - client->addr = MXT540E_APP_HIGH; - } - - data->register_cb(mxt540e_ta_probe); - - while (retry--) { - ret = mxt540e_init_touch_driver(data); - - if (ret == 0 || retry <= 0) - break; - - printk(KERN_DEBUG - "[TSP] chip initialization failed. retry(%d)\n", retry); - - data->power_off(); - msleep(300); - data->power_on(); - } - - if (ret) { - dev_err(&client->dev, "chip initialization failed\n"); - goto err_init_drv; - } - data->cpu_freq_lock = -1; - - /* median filter error tunning */ - median_error = kmalloc(sizeof(*median_error), GFP_KERNEL); - median_error->err_cnt_bat = 0; - median_error->err_cnt_ta = 0; - median_error->setting_flag = 0; - median_error->table_cnt = 0; - median_error->table_ta[0] = 33; - median_error->table_ta[1] = 20; - median_error->table_ta[2] = 15; - median_error->table_ta[3] = 0; - median_error->table_bat[0] = 20; - median_error->table_bat[1] = 10; - median_error->table_bat[2] = 30; - median_error->table_bat[3] = 10; - data->median_error = median_error; - - if (data->family_id == 0xA1) { /* tsp_family_id - 0xA1 : MXT-540E */ - tsp_config = (u8 **) pdata->config_e; - data->t48_config_batt_e = pdata->t48_config_batt_e; - data->t48_config_chrg_e = pdata->t48_config_chrg_e; - data->chrgtime_batt = pdata->chrgtime_batt; - data->chrgtime_charging = pdata->chrgtime_charging; - data->tchthr_batt = pdata->tchthr_batt; - data->tchthr_charging = pdata->tchthr_charging; - data->calcfg_batt_e = pdata->calcfg_batt_e; - data->calcfg_charging_e = pdata->calcfg_charging_e; - data->atchfrccalthr_e = pdata->atchfrccalthr_e; - data->atchfrccalratio_e = pdata->atchfrccalratio_e; - data->actvsyncsperx_batt = pdata->actvsyncsperx_batt; - data->actvsyncsperx_charging = pdata->actvsyncsperx_charging; - - printk(KERN_DEBUG "[TSP] TSP chip is MXT540E\n"); - if ((data->tsp_version < firmware_latest) - || (data->tsp_build != build_latest)) { - printk(KERN_DEBUG "[TSP] mxt540E force firmware update\n"); - if (mxt540e_load_fw(NULL, MXT540E_FW_NAME)) { - printk(KERN_ERR "[TSP] firm update fail\n"); - goto err_config; - } else { - msleep(MXT540E_SW_RESET_TIME); - mxt540e_init_touch_driver(data); - } - } - INIT_DELAYED_WORK(&data->config_dwork, - mxt_reconfigration_normal); - INIT_DELAYED_WORK(&data->resume_check_dwork, - resume_check_dworker); - INIT_DELAYED_WORK(&data->cal_check_dwork, cal_check_dworker); - } else { - printk(KERN_ERR "ERROR : There is no valid TSP ID\n"); - goto err_config; - } - - for (i = 0; tsp_config[i][0] != RESERVED_T255; i++) { - ret = init_write_config(data, tsp_config[i][0], - tsp_config[i] + 1); - if (ret) - goto err_config; - - if (tsp_config[i][0] == GEN_POWERCONFIG_T7) - data->power_cfg = tsp_config[i] + 1; - - if (tsp_config[i][0] == TOUCH_MULTITOUCHSCREEN_T9) { - /* Are x and y inverted? */ - if (tsp_config[i][10] & 0x1) { - data->x_dropbits = - (!(tsp_config[i][22] & 0xC)) << 1; - data->y_dropbits = - (!(tsp_config[i][20] & 0xC)) << 1; - } else { - data->x_dropbits = - (!(tsp_config[i][20] & 0xC)) << 1; - data->y_dropbits = - (!(tsp_config[i][22] & 0xC)) << 1; - } - } - } - - ret = mxt540e_backup(data); - if (ret) - goto err_backup; - - /* reset the touch IC. */ - ret = mxt540e_reset(data); - if (ret) - goto err_reset; - - msleep(MXT540E_SW_RESET_TIME); - - mxt540e_enabled = 1; - - if (data->read_ta_status) { - data->read_ta_status(&ta_status); - printk(KERN_DEBUG "[TSP] ta_status is %d\n", ta_status); - mxt540e_ta_probe(ta_status); - } - check_resume_err = 2; - calibrate_chip(data); - schedule_delayed_work(&data->config_dwork, HZ * 30); - - for (i = 0; i < data->num_fingers; i++) - data->fingers[i].state = MXT540E_STATE_INACTIVE; - - ret = request_threaded_irq(client->irq, NULL, mxt540e_irq_thread, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, "mxt540e_ts", data); - - if (ret < 0) - goto err_irq; - - ret = sysfs_create_group(&client->dev.kobj, &mxt540e_attr_group); - if (ret) - printk(KERN_ERR "[TSP] sysfs_create_group()is falled\n"); - - sec_touchscreen = - device_create(sec_class, NULL, 0, NULL, "sec_touchscreen"); - dev_set_drvdata(sec_touchscreen, data); - if (IS_ERR(sec_touchscreen)) - printk(KERN_ERR - "[TSP] Failed to create device(sec_touchscreen)!\n"); - - if (device_create_file(sec_touchscreen, &dev_attr_tsp_firm_update) < 0) - printk(KERN_ERR "[TSP] Failed to create device file(%s)!\n", - dev_attr_tsp_firm_update.attr.name); - - if (device_create_file - (sec_touchscreen, &dev_attr_tsp_firm_update_status) < 0) - printk(KERN_ERR "[TSP] Failed to create device file(%s)!\n", - dev_attr_tsp_firm_update_status.attr.name); - - if (device_create_file(sec_touchscreen, &dev_attr_tsp_threshold) < 0) - printk(KERN_ERR "[TSP] Failed to create device file(%s)!\n", - dev_attr_tsp_threshold.attr.name); - - if (device_create_file - (sec_touchscreen, &dev_attr_tsp_firm_version_phone) < 0) - printk(KERN_ERR "[TSP] Failed to create device file(%s)!\n", - dev_attr_tsp_firm_version_phone.attr.name); - - if (device_create_file - (sec_touchscreen, &dev_attr_tsp_firm_version_panel) < 0) - printk(KERN_ERR "[TSP] Failed to create device file(%s)!\n", - dev_attr_tsp_firm_version_panel.attr.name); - - if (device_create_file(sec_touchscreen, &dev_attr_mxt_touchtype) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_mxt_touchtype.attr.name); - - mxt540e_noise_test = - device_create(sec_class, NULL, 0, NULL, "tsp_noise_test"); - - if (IS_ERR(mxt540e_noise_test)) - printk(KERN_ERR - "Failed to create device(mxt540e_noise_test)!\n"); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_refer0) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_refer0.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_delta0) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_delta0.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_refer1) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_refer1.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_delta1) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_delta1.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_refer2) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_refer2.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_delta2) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_delta2.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_refer3) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_refer3.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_delta3) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_delta3.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_refer4) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_refer4.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_delta4) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_delta4.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_all_refer) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_all_refer.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_disp_all_refdata) < - 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_disp_all_refdata.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_all_delta) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_all_delta.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_disp_all_deltadata) - < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_disp_all_deltadata.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_threshold) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_threshold.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_firm_version) < - 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_firm_version.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_module_off) < - 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_module_off.attr.name); - - if (device_create_file(mxt540e_noise_test, &dev_attr_set_module_on) < 0) - printk(KERN_ERR "Failed to create device file(%s)!\n", - dev_attr_set_module_on.attr.name); - -#ifdef CONFIG_HAS_EARLYSUSPEND - data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - data->early_suspend.suspend = mxt540e_early_suspend; - data->early_suspend.resume = mxt540e_late_resume; - register_early_suspend(&data->early_suspend); -#endif - return 0; - - err_irq: - err_reset: - err_backup: - err_config: - kfree(data->objects); - err_init_drv: - gpio_free(data->gpio_read_done); -/* err_gpio_req: - data->power_off(); - input_unregister_device(input_dev); */ - err_reg_dev: - err_alloc_dev: - kfree(data); - return ret; -} - -static int __devexit mxt540e_remove(struct i2c_client *client) -{ - struct mxt540e_data *data = i2c_get_clientdata(client); - -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&data->early_suspend); -#endif - free_irq(client->irq, data); - kfree(data->objects); - gpio_free(data->gpio_read_done); - data->power_off(); - input_unregister_device(data->input_dev); - kfree(data); - - return 0; -} - -static struct i2c_device_id mxt540e_idtable[] = { - {MXT540E_DEV_NAME, 0}, - {}, -}; - -MODULE_DEVICE_TABLE(i2c, mxt540e_idtable); - -static const struct dev_pm_ops mxt540e_pm_ops = { - .suspend = mxt540e_suspend, - .resume = mxt540e_resume, -}; - -static struct i2c_driver mxt540e_i2c_driver = { - .id_table = mxt540e_idtable, - .probe = mxt540e_probe, - .remove = __devexit_p(mxt540e_remove), - .driver = { - .owner = THIS_MODULE, - .name = MXT540E_DEV_NAME, - .pm = &mxt540e_pm_ops, - }, -}; - -static int __init mxt540e_init(void) -{ - return i2c_add_driver(&mxt540e_i2c_driver); -} - -static void __exit mxt540e_exit(void) -{ - i2c_del_driver(&mxt540e_i2c_driver); -} - -module_init(mxt540e_init); -module_exit(mxt540e_exit); - -MODULE_DESCRIPTION("Atmel MaXTouch 540E driver"); -MODULE_AUTHOR("Heetae Ahn <heetae82.ahn@samsung.com>"); -MODULE_LICENSE("GPL"); |