From 5b43c3279e3c3e6339612bbfed442f4fd2113ea6 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Sat, 3 Nov 2018 16:11:25 +0800 Subject: [PATCH] drivers/input/touchscreen: remove unused atmel mxt1386/mxt224 drivers Change-Id: Iadf4f95de2238b57e25eca6199403c02b22c1856 Signed-off-by: Tao Huang --- drivers/input/touchscreen/atmel_maxtouch.c | 2241 ----------------- drivers/input/touchscreen/atmel_mxt1386.c | 2625 -------------------- drivers/input/touchscreen/atmel_mxt1386.h | 295 --- drivers/input/touchscreen/atmel_mxt224.c | 1053 -------- include/linux/atmel_maxtouch.h | 314 --- 5 files changed, 6528 deletions(-) delete mode 100755 drivers/input/touchscreen/atmel_maxtouch.c delete mode 100644 drivers/input/touchscreen/atmel_mxt1386.c delete mode 100644 drivers/input/touchscreen/atmel_mxt1386.h delete mode 100644 drivers/input/touchscreen/atmel_mxt224.c delete mode 100644 include/linux/atmel_maxtouch.h diff --git a/drivers/input/touchscreen/atmel_maxtouch.c b/drivers/input/touchscreen/atmel_maxtouch.c deleted file mode 100755 index 9dcb15669df5..000000000000 --- a/drivers/input/touchscreen/atmel_maxtouch.c +++ /dev/null @@ -1,2241 +0,0 @@ -/* - * Atmel maXTouch Touchscreen Controller Driver - * - * - * Copyright (C) 2010 Atmel Corporation - * Copyright (C) 2010 Ulf Samuelsson (ulf@atmel.com) - * Copyright (C) 2009 Raphael Derosso Pereira - * - * 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; version 2 of the License - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * - * Driver for Atmel maXTouch family of touch controllers. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -#define DRIVER_VERSION "0.91a_mod" - -#define VERSION_20 - -static int debug = DEBUG_TRACE; -static int comms = 0; -module_param(debug, int, 0644); -module_param(comms, int, 0644); - -MODULE_PARM_DESC(debug, "Activate debugging output"); -MODULE_PARM_DESC(comms, "Select communications mode"); - -/* Device Info descriptor */ -/* Parsed from maXTouch "Id information" inside device */ -struct mxt_device_info { - u8 family_id; - u8 variant_id; - u8 major; - u8 minor; - u8 build; - u8 num_objs; - u8 x_size; - u8 y_size; - char family_name[16]; /* Family name */ - char variant_name[16]; /* Variant name */ - u16 num_nodes; /* Number of sensor nodes */ -}; - -/* object descriptor table, parsed from maXTouch "object table" */ -struct mxt_object { - u16 chip_addr; - u8 type; - u8 size; - u8 instances; - u8 num_report_ids; -}; - - -/* Mapping from report id to object type and instance */ -struct report_id_map { - u8 object; - u8 instance; -/* - * This is the first report ID belonging to object. It enables us to - * find out easily the touch number: each touch has different report - * ID (which are assigned to touches in increasing order). By - * subtracting the first report ID from current, we get the touch - * number. - */ - u8 first_rid; -}; - - -/* Driver datastructure */ -struct mxt_data { - struct i2c_client *client; - struct input_dev *input; - char phys_name[32]; - int irq; - - u16 last_read_addr; - bool new_msgs; - u8 *last_message; - - int valid_irq_counter; - int invalid_irq_counter; - int irq_counter; - int message_counter; - int read_fail_counter; - - - int bytes_to_read; - - struct delayed_work dwork; - u8 xpos_format; - u8 ypos_format; - - u8 numtouch; - - struct mxt_device_info device_info; - - u32 info_block_crc; - u32 configuration_crc; - u16 report_id_count; - struct report_id_map *rid_map; - struct mxt_object *object_table; - - u16 msg_proc_addr; - u8 message_size; - - u16 max_x_val; - u16 max_y_val; - - int (*init_hw)(struct i2c_client *client); - int (*exit_hw)(struct i2c_client *client); - u8 (*valid_interrupt)(void); - u8 (*read_chg)(void); - - /* debugfs variables */ - struct dentry *debug_dir; - int current_debug_datap; - - struct mutex debug_mutex; - u16 *debug_data; - - /* Character device variables */ - struct cdev cdev; - struct cdev cdev_messages; /* 2nd Char dev for messages */ - dev_t dev_num; - struct class *mxt_class; - - - u16 address_pointer; - bool valid_ap; - - /* Message buffer & pointers */ - char *messages; - int msg_buffer_startp, msg_buffer_endp; - /* Put only non-touch messages to buffer if this is set */ - char nontouch_msg_only; - struct mutex msg_mutex; -}; - -struct mxt_key_info{ - u32 start; - u32 end; - u32 code; -}; - -const struct mxt_key_info key_info[] = { - {0, 0, KEY_BACK}, - {0, 0, KEY_MENU}, - {0, 0, KEY_HOME}, - {0, 0, KEY_SEARCH}, -}; - -u32 last_key=0; - -u8 T9_cfg[31] = { - 0x83, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x1e, - 0x02, 0x06, 0x00, 0x03, 0x01, 0x0f, 0x0A, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, -}; - -static int mxt_read_block(struct i2c_client *client, u16 addr, u16 length, - u8 *value); -static int mxt_write_byte(struct i2c_client *client, u16 addr, u8 value); -static int mxt_write_block(struct i2c_client *client, u16 addr, u16 length, - u8 *value); -static u8 mxt_valid_interrupt_dummy(void) -{ - return 1; -} - -#define I2C_RETRY_COUNT 5 -#define I2C_PAYLOAD_SIZE 254 - -/* Returns the start address of object in mXT memory. */ -#define MXT_BASE_ADDR(object_type, mxt) \ - get_object_address(object_type, 0, mxt->object_table, \ - mxt->device_info.num_objs) - -/* Maps a report ID to an object type (object type number). */ -#define REPORT_ID_TO_OBJECT(rid, mxt) \ - (((rid) == 0xff) ? 0 : mxt->rid_map[rid].object) - -/* Maps a report ID to an object type (string). */ -#define REPORT_ID_TO_OBJECT_NAME(rid, mxt) \ - object_type_name[REPORT_ID_TO_OBJECT(rid, mxt)] - -/* Returns non-zero if given object is a touch object */ -#define IS_TOUCH_OBJECT(object) \ - ((object == MXT_TOUCH_MULTITOUCHSCREEN_T9) || \ - (object == MXT_TOUCH_KEYARRAY_T15) || \ - (object == MXT_TOUCH_PROXIMITY_T23) || \ - (object == MXT_TOUCH_SINGLETOUCHSCREEN_T10) || \ - (object == MXT_TOUCH_XSLIDER_T11) || \ - (object == MXT_TOUCH_YSLIDER_T12) || \ - (object == MXT_TOUCH_XWHEEL_T13) || \ - (object == MXT_TOUCH_YWHEEL_T14) || \ - (object == MXT_TOUCH_KEYSET_T31) || \ - (object == MXT_TOUCH_XSLIDERSET_T32) ? 1 : 0) -#if 1 -#define mxt_debug(level, ...) \ - do { \ - if (debug >= (level)) \ - pr_debug(__VA_ARGS__); \ - } while (0) -#else -#define mxt_debug(level, ...) \ - do { \ - printk(__VA_ARGS__); \ - } while (0) -#endif - -/* - * Check whether we have multi-touch enabled kernel; if not, report just the - * first touch (on mXT224, the maximum is 10 simultaneous touches). - * Because just the 1st one is reported, it might seem that the screen is not - * responding to touch if the first touch is removed while the screen is being - * touched by another finger, so beware. - * - */ - -#ifdef ABS_MT_TRACKING_ID -static inline void report_mt(int touch_number, int size, int x, int y, struct - mxt_data *mxt) { - input_report_abs(mxt->input, ABS_MT_TRACKING_ID, touch_number); - input_report_abs(mxt->input, ABS_MT_TOUCH_MAJOR, size); - input_report_abs(mxt->input, ABS_MT_POSITION_X, x); - input_report_abs(mxt->input, ABS_MT_POSITION_Y, y); - input_mt_sync(mxt->input); -} -#else -static inline void report_mt(int touch_number, int size, int x, int y, struct - mxt_data *mxt) { - if (touch_number == 0) { - input_report_abs(mxt->input, ABS_TOOL_WIDTH, size); - input_report_abs(mxt->input, ABS_X, x); - input_report_abs(mxt->input, ABS_Y, y); - } -} -#endif - - -static inline void report_gesture(int data, struct mxt_data *mxt) -{ - input_event(mxt->input, EV_MSC, MSC_GESTURE, data); -} - - -static const u8 *object_type_name[] = { - [0] = "Reserved", - [5] = "GEN_MESSAGEPROCESSOR_T5", - [6] = "GEN_COMMANDPROCESSOR_T6", - [7] = "GEN_POWERCONFIG_T7", - [8] = "GEN_ACQUIRECONFIG_T8", - [9] = "TOUCH_MULTITOUCHSCREEN_T9", - [15] = "TOUCH_KEYARRAY_T15", - [17] = "SPT_COMMSCONFIG_T18", - [19] = "SPT_GPIOPWM_T19", - [20] = "PROCI_GRIPFACESUPPRESSION_T20", - [22] = "PROCG_NOISESUPPRESSION_T22", - [23] = "TOUCH_PROXIMITY_T23", - [24] = "PROCI_ONETOUCHGESTUREPROCESSOR_T24", - [25] = "SPT_SELFTEST_T25", - [27] = "PROCI_TWOTOUCHGESTUREPROCESSOR_T27", - [28] = "SPT_CTECONFIG_T28", - [37] = "DEBUG_DIAGNOSTICS_T37", - [38] = "SPT_USER_DATA_T38", - [40] = "PROCI_GRIPSUPPRESSION_T40", - [41] = "PROCI_PALMSUPPRESSION_T41", - [42] = "PROCI_FACESUPPRESSION_T42", - [43] = "SPT_DIGITIZER_T43", - [44] = "SPT_MESSAGECOUNT_T44", -}; - - -static u16 get_object_address(uint8_t object_type, - uint8_t instance, - struct mxt_object *object_table, - int max_objs); - -int mxt_write_ap(struct mxt_data *mxt, u16 ap); - -static int mxt_read_block_wo_addr(struct i2c_client *client, - u16 length, - u8 *value); - -ssize_t debug_data_read(struct mxt_data *mxt, char *buf, size_t count, - loff_t *ppos, u8 debug_command){ - int i; - u16 *data; - u16 diagnostics_reg; - int offset = 0; - int size; - int read_size; - int error; - char *buf_start; - u16 debug_data_addr; - u16 page_address; - u8 page; - u8 debug_command_reg; - - data = mxt->debug_data; - if (data == NULL) - return -EIO; - - /* If first read after open, read all data to buffer. */ - if (mxt->current_debug_datap == 0){ - - diagnostics_reg = MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, - mxt) + - MXT_ADR_T6_DIAGNOSTIC; - if (count > (mxt->device_info.num_nodes * 2)) - count = mxt->device_info.num_nodes; - - debug_data_addr = MXT_BASE_ADDR(MXT_DEBUG_DIAGNOSTIC_T37, mxt)+ - MXT_ADR_T37_DATA; - page_address = MXT_BASE_ADDR(MXT_DEBUG_DIAGNOSTIC_T37, mxt) + - MXT_ADR_T37_PAGE; - error = mxt_read_block(mxt->client, page_address, 1, &page); - if (error < 0) - return error; - mxt_debug(DEBUG_TRACE, "debug data page = %d\n", page); - while (page != 0) { - error = mxt_write_byte(mxt->client, - diagnostics_reg, - MXT_CMD_T6_PAGE_DOWN); - if (error < 0) - return error; - /* Wait for command to be handled; when it has, the - register will be cleared. */ - debug_command_reg = 1; - while (debug_command_reg != 0) { - error = mxt_read_block(mxt->client, - diagnostics_reg, 1, - &debug_command_reg); - if (error < 0) - return error; - mxt_debug(DEBUG_TRACE, - "Waiting for debug diag command " - "to propagate...\n"); - - } - error = mxt_read_block(mxt->client, page_address, 1, - &page); - if (error < 0) - return error; - mxt_debug(DEBUG_TRACE, "debug data page = %d\n", page); - } - - /* - * Lock mutex to prevent writing some unwanted data to debug - * command register. User can still write through the char - * device interface though. TODO: fix? - */ - - mutex_lock(&mxt->debug_mutex); - /* Configure Debug Diagnostics object to show deltas/refs */ - error = mxt_write_byte(mxt->client, diagnostics_reg, - debug_command); - - /* Wait for command to be handled; when it has, the - * register will be cleared. */ - debug_command_reg = 1; - while (debug_command_reg != 0) { - error = mxt_read_block(mxt->client, - diagnostics_reg, 1, - &debug_command_reg); - if (error < 0) - return error; - mxt_debug(DEBUG_TRACE, "Waiting for debug diag command " - "to propagate...\n"); - - } - - if (error < 0) { - printk (KERN_WARNING - "Error writing to maXTouch device!\n"); - return error; - } - - size = mxt->device_info.num_nodes * sizeof(u16); - - while (size > 0) { - read_size = size > 128 ? 128 : size; - mxt_debug(DEBUG_TRACE, - "Debug data read loop, reading %d bytes...\n", - read_size); - error = mxt_read_block(mxt->client, - debug_data_addr, - read_size, - (u8 *) &data[offset]); - if (error < 0) { - printk(KERN_WARNING - "Error reading debug data\n"); - goto error; - } - offset += read_size/2; - size -= read_size; - - /* Select next page */ - error = mxt_write_byte(mxt->client, diagnostics_reg, - MXT_CMD_T6_PAGE_UP); - if (error < 0) { - printk(KERN_WARNING - "Error writing to maXTouch device!\n"); - goto error; - } - } - mutex_unlock(&mxt->debug_mutex); - } - - buf_start = buf; - i = mxt->current_debug_datap; - - while (((buf- buf_start) < (count - 6)) && - (i < mxt->device_info.num_nodes)){ - - mxt->current_debug_datap++; - if (debug_command == MXT_CMD_T6_REFERENCES_MODE) - buf += sprintf(buf, "%d: %5d\n", i, - (u16) le16_to_cpu(data[i])); - else if (debug_command == MXT_CMD_T6_DELTAS_MODE) - buf += sprintf(buf, "%d: %5d\n", i, - (s16) le16_to_cpu(data[i])); - i++; - } - - return (buf - buf_start); -error: - mutex_unlock(&mxt->debug_mutex); - return error; -} - -ssize_t deltas_read(struct file *file, char *buf, size_t count, loff_t *ppos) -{ - return debug_data_read(file->private_data, buf, count, ppos, - MXT_CMD_T6_DELTAS_MODE); -} - -ssize_t refs_read(struct file *file, char *buf, size_t count, - loff_t *ppos) -{ - return debug_data_read(file->private_data, buf, count, ppos, - MXT_CMD_T6_REFERENCES_MODE); -} - -int debug_data_open(struct inode *inode, struct file *file) -{ - struct mxt_data *mxt; - int i; - mxt = inode->i_private; - if (mxt == NULL) - return -EIO; - mxt->current_debug_datap = 0; - mxt->debug_data = kmalloc(mxt->device_info.num_nodes * sizeof(u16), - GFP_KERNEL); - if (mxt->debug_data == NULL) - return -ENOMEM; - - - for (i = 0; i < mxt->device_info.num_nodes; i++) - mxt->debug_data[i] = 7777; - - - file->private_data = mxt; - return 0; -} - -int debug_data_release(struct inode *inode, struct file *file) -{ - struct mxt_data *mxt; - mxt = file->private_data; - kfree(mxt->debug_data); - return 0; -} - -static struct file_operations delta_fops = { - .owner = THIS_MODULE, - .open = debug_data_open, - .release = debug_data_release, - .read = deltas_read, -}; - -static struct file_operations refs_fops = { - .owner = THIS_MODULE, - .open = debug_data_open, - .release = debug_data_release, - .read = refs_read, -}; - - -int mxt_memory_open(struct inode *inode, struct file *file) -{ - struct mxt_data *mxt; - mxt = container_of(inode->i_cdev, struct mxt_data, cdev); - if (mxt == NULL) - return -EIO; - file->private_data = mxt; - return 0; -} - -int mxt_message_open(struct inode *inode, struct file *file) -{ - struct mxt_data *mxt; - mxt = container_of(inode->i_cdev, struct mxt_data, cdev_messages); - if (mxt == NULL) - return -EIO; - file->private_data = mxt; - return 0; -} - - -ssize_t mxt_memory_read(struct file *file, char *buf, size_t count, - loff_t *ppos) -{ - int i; - struct mxt_data *mxt; - - mxt = file->private_data; - if (mxt->valid_ap){ - mxt_debug(DEBUG_TRACE, "Reading %d bytes from current ap\n", - (int) count); - i = mxt_read_block_wo_addr(mxt->client, count, (u8 *) buf); - } else { - mxt_debug(DEBUG_TRACE, "Address pointer changed since set;" - "writing AP (%d) before reading %d bytes", - mxt->address_pointer, (int) count); - i = mxt_read_block(mxt->client, mxt->address_pointer, count, - buf); - } - - return i; -} - -ssize_t mxt_memory_write(struct file *file, const char *buf, size_t count, - loff_t *ppos) -{ - int i; - int whole_blocks; - int last_block_size; - struct mxt_data *mxt; - u16 address; - - mxt = file->private_data; - address = mxt->address_pointer; - - mxt_debug(DEBUG_TRACE, "mxt_memory_write entered\n"); - whole_blocks = count / I2C_PAYLOAD_SIZE; - last_block_size = count % I2C_PAYLOAD_SIZE; - - for (i = 0; i < whole_blocks; i++) { - mxt_debug(DEBUG_TRACE, "About to write to %d...", - address); - mxt_write_block(mxt->client, address, I2C_PAYLOAD_SIZE, - (u8 *) buf); - address += I2C_PAYLOAD_SIZE; - buf += I2C_PAYLOAD_SIZE; - } - - mxt_write_block(mxt->client, address, last_block_size, (u8 *) buf); - - return count; -} - -static int mxt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int retval; - struct mxt_data *mxt; - - retval = 0; - mxt = file->private_data; - - switch (cmd) { - case MXT_SET_ADDRESS_IOCTL: - retval = mxt_write_ap(mxt, (u16) arg); - if (retval >= 0) { - mxt->address_pointer = (u16) arg; - mxt->valid_ap = 1; - } - break; - case MXT_RESET_IOCTL: - retval = mxt_write_byte(mxt->client, - MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) + - MXT_ADR_T6_RESET, - 1); - break; - case MXT_CALIBRATE_IOCTL: - retval = mxt_write_byte(mxt->client, - MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) + - MXT_ADR_T6_CALIBRATE, - 1); - - break; - case MXT_BACKUP_IOCTL: - retval = mxt_write_byte(mxt->client, - MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) + - MXT_ADR_T6_BACKUPNV, - MXT_CMD_T6_BACKUP); - break; - case MXT_NONTOUCH_MSG_IOCTL: - mxt->nontouch_msg_only = 1; - break; - case MXT_ALL_MSG_IOCTL: - mxt->nontouch_msg_only = 0; - break; - default: - return -EIO; - } - - return retval; -} - -/* - * Copies messages from buffer to user space. - * - * NOTE: if less than (mxt->message_size * 5 + 1) bytes requested, - * this will return 0! - * - */ -ssize_t mxt_message_read(struct file *file, char *buf, size_t count, - loff_t *ppos) -{ - int i; - struct mxt_data *mxt; - char *buf_start; - - mxt = file->private_data; - if (mxt == NULL) - return -EIO; - buf_start = buf; - - mutex_lock(&mxt->msg_mutex); - /* Copy messages until buffer empty, or 'count' bytes written */ - while ((mxt->msg_buffer_startp != mxt->msg_buffer_endp) && - ((buf - buf_start) < (count - (5 * mxt->message_size) - 1))){ - - for (i = 0; i < mxt->message_size; i++){ - buf += sprintf(buf, "[%2X] ", - *(mxt->messages + mxt->msg_buffer_endp * - mxt->message_size + i)); - } - buf += sprintf(buf, "\n"); - if (mxt->msg_buffer_endp < MXT_MESSAGE_BUFFER_SIZE) - mxt->msg_buffer_endp++; - else - mxt->msg_buffer_endp = 0; - } - mutex_unlock(&mxt->msg_mutex); - return (buf - buf_start); -} - -static struct file_operations mxt_message_fops = { - .owner = THIS_MODULE, - .open = mxt_message_open, - .read = mxt_message_read, -}; - -static struct file_operations mxt_memory_fops = { - .owner = THIS_MODULE, - .open = mxt_memory_open, - .read = mxt_memory_read, - .write = mxt_memory_write, - .ioctl = mxt_ioctl, -}; - - -/* Writes the address pointer (to set up following reads). */ - -int mxt_write_ap(struct mxt_data *mxt, u16 ap) -{ - struct i2c_client *client; - __le16 le_ap = cpu_to_le16(ap); - client = mxt->client; - if (mxt != NULL) - mxt->last_read_addr = -1; - if (i2c_master_send(client, (u8 *) &le_ap, 2) == 2) { - mxt_debug(DEBUG_TRACE, "Address pointer set to %d\n", ap); - return 0; - } else { - mxt_debug(DEBUG_INFO, "Error writing address pointer!\n"); - return -EIO; - } -} - - - -/* Calculates the 24-bit CRC sum. */ -static u32 CRC_24(u32 crc, u8 byte1, u8 byte2) -{ - static const u32 crcpoly = 0x80001B; - u32 result; - u32 data_word; - - data_word = ((((u16) byte2) << 8u) | byte1); - result = ((crc << 1u) ^ data_word); - if (result & 0x1000000) - result ^= crcpoly; - return result; -} - -/* Returns object address in mXT chip, or zero if object is not found */ -static u16 get_object_address(uint8_t object_type, - uint8_t instance, - struct mxt_object *object_table, - int max_objs) -{ - uint8_t object_table_index = 0; - uint8_t address_found = 0; - uint16_t address = 0; - struct mxt_object *obj; - - while ((object_table_index < max_objs) && !address_found) { - obj = &object_table[object_table_index]; - if (obj->type == object_type) { - address_found = 1; - /* Are there enough instances defined in the FW? */ - if (obj->instances >= instance) { - address = obj->chip_addr + - (obj->size + 1) * instance; - } else { - return 0; - } - } - object_table_index++; - } - return address; -} - - -/* - * Reads a block of bytes from given address from mXT chip. If we are - * reading from message window, and previous read was from message window, - * there's no need to write the address pointer: the mXT chip will - * automatically set the address pointer back to message window start. - */ - -static int mxt_read_block(struct i2c_client *client, - u16 addr, - u16 length, - u8 *value) -{ - struct i2c_adapter *adapter = client->adapter; - struct i2c_msg msg[2]; - __le16 le_addr; - struct mxt_data *mxt; - - mxt = i2c_get_clientdata(client); - - if (mxt != NULL) { - if ((mxt->last_read_addr == addr) && - (addr == mxt->msg_proc_addr)) { - if (i2c_master_recv(client, value, length) == length){ - return length; - }else{ - return -EIO; - } - } else { - mxt->last_read_addr = addr; - } - } - - mxt_debug(DEBUG_TRACE, "Writing address pointer & reading %d bytes " - "in on i2c transaction...\n", length); - - le_addr = cpu_to_le16(addr); - msg[0].addr = client->addr; - msg[0].flags = 0x00; - msg[0].len = 2; - msg[0].buf = (u8 *) &le_addr; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = length; - msg[1].buf = (u8 *) value; - if (i2c_transfer(adapter, msg, 2) == 2) - return length; - else - return -EIO; - -} - -/* Reads a block of bytes from current address from mXT chip. */ - -static int mxt_read_block_wo_addr(struct i2c_client *client, - u16 length, - u8 *value) -{ - - - if (i2c_master_recv(client, value, length) == length) { - mxt_debug(DEBUG_TRACE, "I2C block read ok\n"); - return length; - } else { - mxt_debug(DEBUG_INFO, "I2C block read failed\n"); - return -EIO; - } - -} - - -/* Writes one byte to given address in mXT chip. */ - -static int mxt_write_byte(struct i2c_client *client, u16 addr, u8 value) -{ - struct { - __le16 le_addr; - u8 data; - - } i2c_byte_transfer; - - struct mxt_data *mxt; - - mxt = i2c_get_clientdata(client); - if (mxt != NULL) - mxt->last_read_addr = -1; - i2c_byte_transfer.le_addr = cpu_to_le16(addr); - i2c_byte_transfer.data = value; - if (i2c_master_send(client, (u8 *) &i2c_byte_transfer, 3) == 3) - return 0; - else - return -EIO; -} - - -/* Writes a block of bytes (max 256) to given address in mXT chip. */ -static int mxt_write_block(struct i2c_client *client, - u16 addr, - u16 length, - u8 *value) -{ - int i; - struct { - __le16 le_addr; - u8 data[256]; - - } i2c_block_transfer; - - struct mxt_data *mxt; - - mxt_debug(DEBUG_TRACE, "Writing %d bytes to %d...", length, addr); - if (length > 256) - return -EINVAL; - mxt = i2c_get_clientdata(client); - if (mxt != NULL) - mxt->last_read_addr = -1; - for (i = 0; i < length; i++) - i2c_block_transfer.data[i] = *value++; - i2c_block_transfer.le_addr = cpu_to_le16(addr); - i = i2c_master_send(client, (u8 *) &i2c_block_transfer, length + 2); - if (i == (length + 2)) - return length; - else - return -EIO; -} - -/* Calculates the CRC value for mXT infoblock. */ -int calculate_infoblock_crc(u32 *crc_result, u8 *data, int crc_area_size) -{ - u32 crc = 0; - int i; - - for (i = 0; i < (crc_area_size - 1); i = i + 2) - crc = CRC_24(crc, *(data + i), *(data + i + 1)); - /* If uneven size, pad with zero */ - if (crc_area_size & 0x0001) - crc = CRC_24(crc, *(data + i), 0); - /* Return only 24 bits of CRC. */ - *crc_result = (crc & 0x00FFFFFF); - - return 0; -} - -/* Processes a touchscreen message. */ -void process_T9_message(u8 *message, struct mxt_data *mxt, int last_touch) -{ - - struct input_dev *input; - u8 status; - u16 xpos = 0xFFFF; - u16 ypos = 0xFFFF; - u8 touch_size = 255; - u8 touch_number; - u8 amplitude; - u8 report_id; - - static int stored_size[10]; - static int stored_x[10]; - static int stored_y[10]; - int i; - int active_touches = 0; - /* - * If the 'last_touch' flag is set, we have received all the touch - * messages - * there are available in this cycle, so send the events for touches - * that are - * active. - */ - if (last_touch){ - /* TODO: For compatibility with single-touch systems, send ABS_X & - * ABS_Y */ - /* - if (stored_size[0]){ - input_report_abs(mxt->input, ABS_X, stored_x[0]); - input_report_abs(mxt->input, ABS_Y, stored_y[0]); - }*/ - - - for (i = 0; i < 10; i++){ - if (stored_size[i]){ - active_touches++; - input_report_abs(mxt->input, - ABS_MT_TRACKING_ID, - i); - input_report_abs(mxt->input, - ABS_MT_TOUCH_MAJOR, - stored_size[i]); - input_report_abs(mxt->input, - ABS_MT_POSITION_X, - stored_x[i]); - input_report_abs(mxt->input, - ABS_MT_POSITION_Y, - stored_y[i]); - input_mt_sync(mxt->input); - } - } - if (active_touches == 0) { - input_mt_sync(mxt->input); - } - input_sync(mxt->input); - - }else{ - - input = mxt->input; - status = message[MXT_MSG_T9_STATUS]; - report_id = message[0]; - - if (status & MXT_MSGB_T9_SUPPRESS) { - /* Touch has been suppressed by grip/face */ - /* detection */ - mxt_debug(DEBUG_TRACE, "SUPRESS"); - } else { - /* Put together the 10-/12-bit coordinate values. */ - xpos = message[MXT_MSG_T9_XPOSMSB] * 16 + - ((message[MXT_MSG_T9_XYPOSLSB] >> 4) & 0xF); - ypos = message[MXT_MSG_T9_YPOSMSB] * 16 + - ((message[MXT_MSG_T9_XYPOSLSB] >> 0) & 0xF); - - if (mxt->max_x_val < 1024) - xpos >>= 2; - if (mxt->max_y_val < 1024) - ypos >>= 2; - - touch_number = message[MXT_MSG_REPORTID] - - mxt->rid_map[report_id].first_rid; - - stored_x[touch_number] = xpos; - stored_y[touch_number] = ypos; - - if (status & MXT_MSGB_T9_DETECT) { - /* - * mXT224 reports the number of touched nodes, - * so the exact value for touch ellipse major - * axis length in nodes would be 2*sqrt(touch_size/pi) - * (assuming round touch shape), which would then need - * to be scaled using information about how many sensor - * lines we do have. So this is very much simplified, - * but sufficient for most if not all apps? - */ - touch_size = message[MXT_MSG_T9_TCHAREA]; - touch_size = touch_size >> 2; - if (!touch_size) - touch_size = 1; - /* - * report_mt(touch_number, touch_size, xpos, ypos, mxt); - */ - - stored_size[touch_number] = touch_size; - - if (status & MXT_MSGB_T9_AMP) - /* Amplitude of touch has changed */ - amplitude = message[MXT_MSG_T9_TCHAMPLITUDE]; - } - - if (status & MXT_MSGB_T9_RELEASE) { - /* The previously reported touch has been removed.*/ - /* report_mt(touch_number, 0, xpos, ypos, mxt); */ - stored_size[touch_number] = 0; - } - - /* input_sync(input); */ - } - - if (status & MXT_MSGB_T9_SUPPRESS) { - mxt_debug(DEBUG_TRACE, "SUPRESS"); - } else { - if (status & MXT_MSGB_T9_DETECT) { - mxt_debug(DEBUG_TRACE, "DETECT:%s%s%s%s\n", - ((status & MXT_MSGB_T9_PRESS) ? " PRESS" : ""), - ((status & MXT_MSGB_T9_MOVE) ? " MOVE" : ""), - ((status & MXT_MSGB_T9_AMP) ? " AMP" : ""), - ((status & MXT_MSGB_T9_VECTOR) ? " VECT" : "")); - - } else if (status & MXT_MSGB_T9_RELEASE) { - mxt_debug(DEBUG_TRACE, "RELEASE\n"); - } - } - mxt_debug(DEBUG_TRACE,"X=%d, Y=%d, TOUCHSIZE=%d\n", - xpos, ypos, touch_size); - } - return; -} - - -int process_message(u8 *message, u8 object, struct mxt_data *mxt) -{ - struct i2c_client *client; - u8 status; - u16 xpos = 0xFFFF; - u16 ypos = 0xFFFF; - u8 event; - u8 direction; - u16 distance; - u8 length; - u8 report_id; - static u8 error_cond = 0; - int keyIndex; - - client = mxt->client; - length = mxt->message_size; - report_id = message[0]; - - if ((mxt->nontouch_msg_only == 0) || - (!IS_TOUCH_OBJECT(object))){ - mutex_lock(&mxt->msg_mutex); - /* Copy the message to buffer */ - if (mxt->msg_buffer_startp < MXT_MESSAGE_BUFFER_SIZE) { - mxt->msg_buffer_startp++; - } else { - mxt->msg_buffer_startp = 0; - } - - if (mxt->msg_buffer_startp == mxt->msg_buffer_endp) { - mxt_debug(DEBUG_TRACE, - "Message buf full, discarding last entry.\n"); - if (mxt->msg_buffer_endp < MXT_MESSAGE_BUFFER_SIZE) { - mxt->msg_buffer_endp++; - } else { - mxt->msg_buffer_endp = 0; - } - } - memcpy((mxt->messages + mxt->msg_buffer_startp * length), - message, - length); - mutex_unlock(&mxt->msg_mutex); - } - - switch (object) { - case MXT_GEN_COMMANDPROCESSOR_T6: - status = message[1]; - - if (status & MXT_MSGB_T6_COMSERR) { - if ((!error_cond) & MXT_MSGB_T6_COMSERR){ - dev_err(&client->dev, - "maXTouch checksum error\n"); - error_cond |= MXT_MSGB_T6_COMSERR; - } - } - if (status & MXT_MSGB_T6_CFGERR) { - /* - * Configuration error. A proper configuration - * needs to be written to chip and backed up. - */ - if ((!error_cond) & MXT_MSGB_T6_CFGERR){ - dev_err(&client->dev, - "maXTouch configuration error\n"); - error_cond |= MXT_MSGB_T6_CFGERR; - } - } - if (status & MXT_MSGB_T6_CAL) { - /* Calibration in action, no need to react */ - dev_info(&client->dev, - "maXTouch calibration in progress\n"); - } - if (status & MXT_MSGB_T6_SIGERR) { - /* - * Signal acquisition error, something is seriously - * wrong, not much we can in the driver to correct - * this - */ - if ((!error_cond) & MXT_MSGB_T6_SIGERR){ - dev_err(&client->dev, - "maXTouch acquisition error\n"); - error_cond |= MXT_MSGB_T6_SIGERR; - } - } - if (status & MXT_MSGB_T6_OFL) { - /* - * Cycle overflow, the acquisition interval is too - * short. - */ - dev_err(&client->dev, - "maXTouch cycle overflow\n"); - } - if (status & MXT_MSGB_T6_RESET) { - /* Chip has reseted, no need to react. */ - dev_info(&client->dev, - "maXTouch chip reset\n"); - } - if (status == 0) { - /* Chip status back to normal. */ - dev_info(&client->dev, - "maXTouch status normal\n"); - error_cond = 0; - } - break; - - case MXT_TOUCH_MULTITOUCHSCREEN_T9: - process_T9_message(message, mxt, 0); - break; - - case MXT_SPT_GPIOPWM_T19: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving GPIO message\n"); - break; - - case MXT_PROCI_GRIPFACESUPPRESSION_T20: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving face suppression msg\n"); - break; - - case MXT_PROCG_NOISESUPPRESSION_T22: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving noise suppression msg\n"); - status = message[MXT_MSG_T22_STATUS]; - if (status & MXT_MSGB_T22_FHCHG) { - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: Freq changed\n"); - } - if (status & MXT_MSGB_T22_GCAFERR) { - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: High noise " - "level\n"); - } - if (status & MXT_MSGB_T22_FHERR) { - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: Freq changed - " - "Noise level too high\n"); - } - break; - - case MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving one-touch gesture msg\n"); - - event = message[MXT_MSG_T24_STATUS] & 0x0F; - xpos = message[MXT_MSG_T24_XPOSMSB] * 16 + - ((message[MXT_MSG_T24_XYPOSLSB] >> 4) & 0x0F); - ypos = message[MXT_MSG_T24_YPOSMSB] * 16 + - ((message[MXT_MSG_T24_XYPOSLSB] >> 0) & 0x0F); - if (mxt->max_x_val < 1024) - xpos >>= 2; - if (mxt->max_y_val < 1024) - ypos >>= 2; - direction = message[MXT_MSG_T24_DIR]; - distance = message[MXT_MSG_T24_DIST] + - (message[MXT_MSG_T24_DIST + 1] << 16); - - report_gesture((event << 24) | (direction << 16) | distance, - mxt); - report_gesture((xpos << 16) | ypos, mxt); - - break; - - case MXT_SPT_SELFTEST_T25: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving Self-Test msg\n"); - - if (message[MXT_MSG_T25_STATUS] == MXT_MSGR_T25_OK) { - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: Self-Test OK\n"); - - } else { - dev_err(&client->dev, - "maXTouch: Self-Test Failed [%02x]:" - "{%02x,%02x,%02x,%02x,%02x}\n", - message[MXT_MSG_T25_STATUS], - message[MXT_MSG_T25_STATUS + 0], - message[MXT_MSG_T25_STATUS + 1], - message[MXT_MSG_T25_STATUS + 2], - message[MXT_MSG_T25_STATUS + 3], - message[MXT_MSG_T25_STATUS + 4] - ); - } - break; - - case MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving 2-touch gesture message\n"); - - event = message[MXT_MSG_T27_STATUS] & 0xF0; - xpos = message[MXT_MSG_T27_XPOSMSB] * 16 + - ((message[MXT_MSG_T27_XYPOSLSB] >> 4) & 0x0F); - ypos = message[MXT_MSG_T27_YPOSMSB] * 16 + - ((message[MXT_MSG_T27_XYPOSLSB] >> 0) & 0x0F); - if (mxt->max_x_val < 1024) - xpos >>= 2; - if (mxt->max_y_val < 1024) - ypos >>= 2; - - direction = message[MXT_MSG_T27_ANGLE]; - distance = message[MXT_MSG_T27_SEPARATION] + - (message[MXT_MSG_T27_SEPARATION + 1] << 16); - - report_gesture((event << 24) | (direction << 16) | distance, - mxt); - report_gesture((xpos << 16) | ypos, mxt); - - - break; - - case MXT_SPT_CTECONFIG_T28: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving CTE message...\n"); - status = message[MXT_MSG_T28_STATUS]; - if (status & MXT_MSGB_T28_CHKERR) - dev_err(&client->dev, - "maXTouch: Power-Up CRC failure\n"); - - break; - case MXT_TOUCH_KEYARRAY_T15: - - status = message[1] >> 7; - if(status) - last_key = message[2]; - - switch(last_key){ - case 1: - { - keyIndex = 0; - break; - } - case 2: - { - keyIndex = 1; - break; - } - case 4: - { - keyIndex = 2; - break; - } - case 8: - { - keyIndex = 3; - break; - } - default: - printk("%s: Default keyIndex [0x%x]\n", __func__, keyIndex); - break; - } - - input_report_key(mxt->input, key_info[keyIndex].code, status); - break; - default: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: Unknown message!\n"); - - break; - } - - return 0; -} - - -/* - * Processes messages when the interrupt line (CHG) is asserted. Keeps - * reading messages until a message with report ID 0xFF is received, - * which indicates that there is no more new messages. - * - */ - -static void mxt_worker(struct work_struct *work) -{ - struct mxt_data *mxt; - struct i2c_client *client; - - u8 *message; - u16 message_length; - u16 message_addr; - u8 report_id; - u8 object; - int error; - int i; - char *message_string; - char *message_start; - - message = NULL; - mxt = container_of(work, struct mxt_data, dwork.work); - disable_irq(mxt->irq); - client = mxt->client; - message_addr = mxt->msg_proc_addr; - message_length = mxt->message_size; - - if (message_length < 256) { - message = kmalloc(message_length, GFP_KERNEL); - if (message == NULL) { - dev_err(&client->dev, "Error allocating memory\n"); - return; - } - } else { - dev_err(&client->dev, - "Message length larger than 256 bytes not supported\n"); - return; - } - - mxt_debug(DEBUG_TRACE, "maXTouch worker active: \n"); - - do { - /* Read next message, reread on failure. */ - /* TODO: message length, CRC included? */ - mxt->message_counter++; - for (i = 1; i < I2C_RETRY_COUNT; i++) { - error = mxt_read_block(client, - message_addr, - message_length - 1, - message); - if (error >= 0) - break; - mxt->read_fail_counter++; - dev_err(&client->dev, - "Failure reading maxTouch device\n"); - } - if (error < 0) { - kfree(message); - return; - } - - if (mxt->address_pointer != message_addr) - mxt->valid_ap = 0; - report_id = message[0]; - - if (debug >= DEBUG_RAW) { - mxt_debug(DEBUG_RAW, "%s message [msg count: %08x]:", - REPORT_ID_TO_OBJECT_NAME(report_id, mxt), - mxt->message_counter - ); - /* 5 characters per one byte */ - message_string = kmalloc(message_length * 5, - GFP_KERNEL); - if (message_string == NULL) { - dev_err(&client->dev, - "Error allocating memory\n"); - kfree(message); - return; - } - message_start = message_string; - for (i = 0; i < message_length; i++) { - message_string += - sprintf(message_string, - "0x%02X ", message[i]); - } - mxt_debug(DEBUG_RAW, "%s", message_start); - kfree(message_start); - } - - if ((report_id != MXT_END_OF_MESSAGES) && (report_id != 0)) { - memcpy(mxt->last_message, message, message_length); - mxt->new_msgs = 1; - smp_wmb(); - /* Get type of object and process the message */ - object = mxt->rid_map[report_id].object; - process_message(message, object, mxt); - } - - mxt_debug(DEBUG_TRACE, "chgline: %d\n", mxt->read_chg()); - } while (comms ? (mxt->read_chg() == 0) : - ((report_id != MXT_END_OF_MESSAGES) && (report_id != 0))); - - /* All messages processed, send the events) */ - process_T9_message(NULL, mxt, 1); - - - kfree(message); - enable_irq(mxt->irq); - /* Make sure we just didn't miss a interrupt. */ - if (mxt->read_chg() == 0){ - schedule_delayed_work(&mxt->dwork, 0); - } -} - - -/* - * The maXTouch device will signal the host about a new message by asserting - * the CHG line. This ISR schedules a worker routine to read the message when - * that happens. - */ - -static irqreturn_t mxt_irq_handler(int irq, void *_mxt) -{ - struct mxt_data *mxt = _mxt; - - mxt->irq_counter++; - if (mxt->valid_interrupt()) { - /* Send the signal only if falling edge generated the irq. */ - cancel_delayed_work(&mxt->dwork); - schedule_delayed_work(&mxt->dwork, 0); - mxt->valid_irq_counter++; - } else { - mxt->invalid_irq_counter++; - return IRQ_NONE; - } - - return IRQ_HANDLED; -} - - - -/******************************************************************************/ -/* Initialization of driver */ -/******************************************************************************/ - -static int __devinit mxt_identify(struct i2c_client *client, - struct mxt_data *mxt, - u8 *id_block_data) -{ - u8 buf[MXT_ID_BLOCK_SIZE]; - int error; - int identified; - - identified = 0; - - /* Read Device info to check if chip is valid */ - error = mxt_read_block(client, MXT_ADDR_INFO_BLOCK, MXT_ID_BLOCK_SIZE, - (u8 *) buf); - - if (error < 0) { - mxt->read_fail_counter++; - dev_err(&client->dev, "Failure accessing maXTouch device\n"); - return -EIO; - } - - memcpy(id_block_data, buf, MXT_ID_BLOCK_SIZE); - - mxt->device_info.family_id = buf[0]; - mxt->device_info.variant_id = buf[1]; - mxt->device_info.major = ((buf[2] >> 4) & 0x0F); - mxt->device_info.minor = (buf[2] & 0x0F); - mxt->device_info.build = buf[3]; - mxt->device_info.x_size = buf[4]; - mxt->device_info.y_size = buf[5]; - mxt->device_info.num_objs = buf[6]; - mxt->device_info.num_nodes = mxt->device_info.x_size * - mxt->device_info.y_size; - - /* - * Check Family & Variant Info; warn if not recognized but - * still continue. - */ - - /* MXT224 */ - if (mxt->device_info.family_id == MXT224_FAMILYID) { - strcpy(mxt->device_info.family_name, "mXT224"); - - if (mxt->device_info.variant_id == MXT224_CAL_VARIANTID) { - strcpy(mxt->device_info.variant_name, "Calibrated"); - } else if (mxt->device_info.variant_id == - MXT224_UNCAL_VARIANTID) { - strcpy(mxt->device_info.variant_name, "Uncalibrated"); - } else { - dev_err(&client->dev, - "Warning: maXTouch Variant ID [%d] not " - "supported\n", - mxt->device_info.variant_id); - strcpy(mxt->device_info.variant_name, "UNKNOWN"); - /* identified = -ENXIO; */ - } - - /* MXT1386 */ - } else if (mxt->device_info.family_id == MXT1386_FAMILYID) { - strcpy(mxt->device_info.family_name, "mXT1386"); - - if (mxt->device_info.variant_id == MXT1386_CAL_VARIANTID) { - strcpy(mxt->device_info.variant_name, "Calibrated"); - } else { - dev_err(&client->dev, - "Warning: maXTouch Variant ID [%d] not " - "supported\n", - mxt->device_info.variant_id); - strcpy(mxt->device_info.variant_name, "UNKNOWN"); - /* identified = -ENXIO; */ - } - /* Unknown family ID! */ - } else { - dev_err(&client->dev, - "Warning: maXTouch Family ID [%d] not supported\n", - mxt->device_info.family_id); - strcpy(mxt->device_info.family_name, "UNKNOWN"); - strcpy(mxt->device_info.variant_name, "UNKNOWN"); - /* identified = -ENXIO; */ - } - - dev_info( - &client->dev, - "Atmel maXTouch (Family %s (%X), Variant %s (%X)) Firmware " - "version [%d.%d] Build %d\n", - mxt->device_info.family_name, - mxt->device_info.family_id, - mxt->device_info.variant_name, - mxt->device_info.variant_id, - mxt->device_info.major, - mxt->device_info.minor, - mxt->device_info.build - ); - dev_info( - &client->dev, - "Atmel maXTouch Configuration " - "[X: %d] x [Y: %d]\n", - mxt->device_info.x_size, - mxt->device_info.y_size - ); - return identified; -} - -/* - * Reads the object table from maXTouch chip to get object data like - * address, size, report id. For Info Block CRC calculation, already read - * id data is passed to this function too (Info Block consists of the ID - * block and object table). - * - */ -static int __devinit mxt_read_object_table(struct i2c_client *client, - struct mxt_data *mxt, - u8 *raw_id_data) -{ - u16 report_id_count; - u8 buf[MXT_OBJECT_TABLE_ELEMENT_SIZE]; - u8 *raw_ib_data; - u8 object_type; - u16 object_address; - u16 object_size; - u8 object_instances; - u8 object_report_ids; - u16 object_info_address; - u32 crc; - u32 calculated_crc; - int i; - int error; - - u8 object_instance; - u8 object_report_id; - u8 report_id; - int first_report_id; - int ib_pointer; - struct mxt_object *object_table; - - mxt_debug(DEBUG_TRACE, "maXTouch driver reading configuration\n"); - - object_table = kzalloc(sizeof(struct mxt_object) * - mxt->device_info.num_objs, - GFP_KERNEL); - if (object_table == NULL) { - printk(KERN_WARNING "maXTouch: Memory allocation failed!\n"); - error = -ENOMEM; - goto err_object_table_alloc; - } - - raw_ib_data = kmalloc(MXT_OBJECT_TABLE_ELEMENT_SIZE * - mxt->device_info.num_objs + MXT_ID_BLOCK_SIZE, - GFP_KERNEL); - if (raw_ib_data == NULL) { - printk(KERN_WARNING "maXTouch: Memory allocation failed!\n"); - error = -ENOMEM; - goto err_ib_alloc; - } - - /* Copy the ID data for CRC calculation. */ - memcpy(raw_ib_data, raw_id_data, MXT_ID_BLOCK_SIZE); - ib_pointer = MXT_ID_BLOCK_SIZE; - - mxt->object_table = object_table; - - mxt_debug(DEBUG_TRACE, "maXTouch driver Memory allocated\n"); - - object_info_address = MXT_ADDR_OBJECT_TABLE; - - report_id_count = 0; - for (i = 0; i < mxt->device_info.num_objs; i++) { - mxt_debug(DEBUG_TRACE, "Reading maXTouch at [0x%04x]: ", - object_info_address); - - error = mxt_read_block(client, object_info_address, - MXT_OBJECT_TABLE_ELEMENT_SIZE, buf); - - if (error < 0) { - mxt->read_fail_counter++; - dev_err(&client->dev, - "maXTouch Object %d could not be read\n", i); - error = -EIO; - goto err_object_read; - } - - memcpy(raw_ib_data + ib_pointer, buf, - MXT_OBJECT_TABLE_ELEMENT_SIZE); - ib_pointer += MXT_OBJECT_TABLE_ELEMENT_SIZE; - - object_type = buf[0]; - object_address = (buf[2] << 8) + buf[1]; - object_size = buf[3] + 1; - object_instances = buf[4] + 1; - object_report_ids = buf[5]; - mxt_debug(DEBUG_TRACE, "Type=%03d, Address=0x%04x, " - "Size=0x%02x, %d instances, %d report id's\n", - object_type, - object_address, - object_size, - object_instances, - object_report_ids - ); - - /* TODO: check whether object is known and supported? */ - - /* Save frequently needed info. */ - if (object_type == MXT_GEN_MESSAGEPROCESSOR_T5) { - mxt->msg_proc_addr = object_address; - mxt->message_size = object_size; - } - - object_table[i].type = object_type; - object_table[i].chip_addr = object_address; - object_table[i].size = object_size; - object_table[i].instances = object_instances; - object_table[i].num_report_ids = object_report_ids; - report_id_count += object_instances * object_report_ids; - - object_info_address += MXT_OBJECT_TABLE_ELEMENT_SIZE; - } - - mxt->rid_map = - kzalloc(sizeof(struct report_id_map) * (report_id_count + 1), - /* allocate for report_id 0, even if not used */ - GFP_KERNEL); - if (mxt->rid_map == NULL) { - printk(KERN_WARNING "maXTouch: Can't allocate memory!\n"); - error = -ENOMEM; - goto err_rid_map_alloc; - } - - mxt->messages = kzalloc(mxt->message_size * MXT_MESSAGE_BUFFER_SIZE, - GFP_KERNEL); - if (mxt->messages == NULL) { - printk(KERN_WARNING "maXTouch: Can't allocate memory!\n"); - error = -ENOMEM; - goto err_msg_alloc; - } - - mxt->last_message = kzalloc(mxt->message_size, GFP_KERNEL); - if (mxt->last_message == NULL) { - printk(KERN_WARNING "maXTouch: Can't allocate memory!\n"); - error = -ENOMEM; - goto err_msg_alloc; - } - - mxt->report_id_count = report_id_count; - if (report_id_count > 254) { /* 0 & 255 are reserved */ - dev_err(&client->dev, - "Too many maXTouch report id's [%d]\n", - report_id_count); - error = -ENXIO; - goto err_max_rid; - } - - /* Create a mapping from report id to object type */ - report_id = 1; /* Start from 1, 0 is reserved. */ - - /* Create table associating report id's with objects & instances */ - for (i = 0; i < mxt->device_info.num_objs; i++) { - for (object_instance = 0; - object_instance < object_table[i].instances; - object_instance++){ - first_report_id = report_id; - for (object_report_id = 0; - object_report_id < object_table[i].num_report_ids; - object_report_id++) { - mxt->rid_map[report_id].object = - object_table[i].type; - mxt->rid_map[report_id].instance = - object_instance; - mxt->rid_map[report_id].first_rid = - first_report_id; - report_id++; - } - } - } - - /* Read 3 byte CRC */ - error = mxt_read_block(client, object_info_address, 3, buf); - if (error < 0) { - mxt->read_fail_counter++; - dev_err(&client->dev, "Error reading CRC\n"); - } - - crc = (buf[2] << 16) | (buf[1] << 8) | buf[0]; - - if (calculate_infoblock_crc(&calculated_crc, raw_ib_data, - ib_pointer)) { - printk(KERN_WARNING "Error while calculating CRC!\n"); - calculated_crc = 0; - } - kfree(raw_ib_data); - - mxt_debug(DEBUG_TRACE, "\nReported info block CRC = 0x%6X\n", crc); - mxt_debug(DEBUG_TRACE, "Calculated info block CRC = 0x%6X\n\n", - calculated_crc); - - if (crc == calculated_crc) { - mxt->info_block_crc = crc; - } else { - mxt->info_block_crc = 0; - printk(KERN_ALERT "maXTouch: Info block CRC invalid!\n"); - } - - if (debug >= DEBUG_VERBOSE) { - - dev_info(&client->dev, "maXTouch: %d Objects\n", - mxt->device_info.num_objs); - - for (i = 0; i < mxt->device_info.num_objs; i++) { - dev_info(&client->dev, "Type:\t\t\t[%d]: %s\n", - object_table[i].type, - object_type_name[object_table[i].type]); - dev_info(&client->dev, "\tAddress:\t0x%04X\n", - object_table[i].chip_addr); - dev_info(&client->dev, "\tSize:\t\t%d Bytes\n", - object_table[i].size); - dev_info(&client->dev, "\tInstances:\t%d\n", - object_table[i].instances); - dev_info(&client->dev, "\tReport Id's:\t%d\n", - object_table[i].num_report_ids); - } - } - - return 0; - - -err_max_rid: - kfree(mxt->last_message); -err_msg_alloc: - kfree(mxt->rid_map); -err_rid_map_alloc: -err_object_read: - kfree(raw_ib_data); -err_ib_alloc: - kfree(object_table); -err_object_table_alloc: - return error; -} - -static int __devinit mxt_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct mxt_data *mxt; - struct mxt_platform_data *pdata; - struct input_dev *input; - u8 *id_data; - int error; - int index; - u8 buf[MXT_ACK_BUFFER_SIZE] = {0}; - u8 buf_size = MXT_MAKE_HIGH_CHG_SIZE_MIN; - char t7_buf[2] = {64, 32}; - - mxt_debug(DEBUG_INFO, "mXT224: mxt_probe\n"); - - if (client == NULL) { - pr_debug("maXTouch: client == NULL\n"); - return -EINVAL; - } else if (client->adapter == NULL) { - pr_debug("maXTouch: client->adapter == NULL\n"); - return -EINVAL; - } else if (&client->dev == NULL) { - pr_debug("maXTouch: client->dev == NULL\n"); - return -EINVAL; - } else if (&client->adapter->dev == NULL) { - pr_debug("maXTouch: client->adapter->dev == NULL\n"); - return -EINVAL; - } else if (id == NULL) { - pr_debug("maXTouch: id == NULL\n"); - return -EINVAL; - } - - mxt_debug(DEBUG_INFO, "maXTouch driver v. %s\n", DRIVER_VERSION); - mxt_debug(DEBUG_INFO, "\t \"%s\"\n", client->name); - mxt_debug(DEBUG_INFO, "\taddr:\t0x%04x\n", client->addr); - mxt_debug(DEBUG_INFO, "\tirq:\t%d\n", client->irq); - mxt_debug(DEBUG_INFO, "\tflags:\t0x%04x\n", client->flags); - mxt_debug(DEBUG_INFO, "\tadapter:\"%s\"\n", client->adapter->name); - mxt_debug(DEBUG_INFO, "\tdevice:\t\"%s\"\n", client->dev.init_name); - - mxt_debug(DEBUG_TRACE, "maXTouch driver functionality OK\n"); - - /* Allocate structure - we need it to identify device */ - mxt = kzalloc(sizeof(struct mxt_data), GFP_KERNEL); - if (mxt == NULL) { - dev_err(&client->dev, "insufficient memory\n"); - error = -ENOMEM; - goto err_mxt_alloc; - } - - id_data = kmalloc(MXT_ID_BLOCK_SIZE, GFP_KERNEL); - if (id_data == NULL) { - dev_err(&client->dev, "insufficient memory\n"); - error = -ENOMEM; - goto err_id_alloc; - } - - input = input_allocate_device(); - if (!input) { - dev_err(&client->dev, "error allocating input device\n"); - error = -ENOMEM; - goto err_input_dev_alloc; - } - - /* Initialize Platform data */ - - pdata = client->dev.platform_data; - if (pdata == NULL) { - dev_err(&client->dev, "platform data is required!\n"); - error = -EINVAL; - goto err_pdata; - } - if (debug >= DEBUG_TRACE) - printk(KERN_INFO "Platform OK: pdata = 0x%08x\n", - (unsigned int) pdata); - - mxt->read_fail_counter = 0; - mxt->message_counter = 0; - mxt->max_x_val = pdata->max_x; - mxt->max_y_val = pdata->max_y; - - /* Get data that is defined in board specific code. */ - mxt->init_hw = pdata->init_platform_hw; - mxt->exit_hw = pdata->exit_platform_hw; - mxt->read_chg = pdata->read_chg; - - if (pdata->valid_interrupt != NULL) - mxt->valid_interrupt = pdata->valid_interrupt; - else - mxt->valid_interrupt = mxt_valid_interrupt_dummy; - - if (mxt->init_hw != NULL) - mxt->init_hw(client); - - if (debug >= DEBUG_TRACE) - printk(KERN_INFO "maXTouch driver identifying chip\n"); - - if (mxt_identify(client, mxt, id_data) < 0) { - dev_err(&client->dev, "Chip could not be identified\n"); - error = -ENODEV; - goto err_identify; - } - /* Chip is valid and active. */ - if (debug >= DEBUG_TRACE) - printk(KERN_INFO "maXTouch driver allocating input device\n"); - - mxt->client = client; - mxt->input = input; - - INIT_DELAYED_WORK(&mxt->dwork, mxt_worker); - mutex_init(&mxt->debug_mutex); - mutex_init(&mxt->msg_mutex); - mxt_debug(DEBUG_TRACE, "maXTouch driver creating device name\n"); - - snprintf( - mxt->phys_name, - sizeof(mxt->phys_name), - "%s/input0", - dev_name(&client->dev) - ); - input->name = "Atmel maXTouch Touchscreen controller"; - input->phys = mxt->phys_name; - input->id.bustype = BUS_I2C; - input->dev.parent = &client->dev; - - mxt_debug(DEBUG_INFO, "maXTouch name: \"%s\"\n", input->name); - mxt_debug(DEBUG_INFO, "maXTouch phys: \"%s\"\n", input->phys); - mxt_debug(DEBUG_INFO, "maXTouch driver setting abs parameters\n"); - - set_bit(BTN_TOUCH, input->keybit); - - /* Single touch */ - input_set_abs_params(input, ABS_X, 0, mxt->max_x_val, 0, 0); - input_set_abs_params(input, ABS_Y, 0, mxt->max_y_val, 0, 0); - input_set_abs_params(input, ABS_PRESSURE, 0, MXT_MAX_REPORTED_PRESSURE, - 0, 0); - input_set_abs_params(input, ABS_TOOL_WIDTH, 0, MXT_MAX_REPORTED_WIDTH, - 0, 0); - - /* Multitouch */ - input_set_abs_params(input, ABS_MT_POSITION_X, 0, mxt->max_x_val, 0, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, 0, mxt->max_y_val, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, MXT_MAX_TOUCH_SIZE, - 0, 0); - input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, MXT_MAX_NUM_TOUCHES, - 0, 0); - - __set_bit(EV_ABS, input->evbit); - __set_bit(EV_SYN, input->evbit); - __set_bit(EV_KEY, input->evbit); - __set_bit(EV_MSC, input->evbit); - input->mscbit[0] = BIT_MASK(MSC_GESTURE); - - for(index=0; index<(sizeof(key_info)/sizeof(key_info[0])); index++) - { - input_set_capability(input, EV_KEY, key_info[index].code); - } - - mxt_debug(DEBUG_TRACE, "maXTouch driver setting client data\n"); - i2c_set_clientdata(client, mxt); - mxt_debug(DEBUG_TRACE, "maXTouch driver setting drv data\n"); - input_set_drvdata(input, mxt); - mxt_debug(DEBUG_TRACE, "maXTouch driver input register device\n"); - error = input_register_device(mxt->input); - if (error < 0) { - dev_err(&client->dev, - "Failed to register input device\n"); - goto err_register_device; - } - - error = mxt_read_object_table(client, mxt, id_data); - if (error < 0) - goto err_read_ot; - - - /* Create debugfs entries. */ - mxt->debug_dir = debugfs_create_dir("maXTouch", NULL); - if (mxt->debug_dir == ERR_PTR(-ENODEV)) { - /* debugfs is not enabled. */ - printk(KERN_WARNING "debugfs not enabled in kernel\n"); - } else if (mxt->debug_dir == NULL) { - printk(KERN_WARNING "error creating debugfs dir\n"); - } else { - mxt_debug(DEBUG_TRACE, "created \"maXTouch\" debugfs dir\n"); - - debugfs_create_file("deltas", S_IRUSR, mxt->debug_dir, mxt, - &delta_fops); - debugfs_create_file("refs", S_IRUSR, mxt->debug_dir, mxt, - &refs_fops); - } - - /* Create character device nodes for reading & writing registers */ - mxt->mxt_class = class_create(THIS_MODULE, "maXTouch_memory"); - if (IS_ERR(mxt->mxt_class)){ - printk(KERN_WARNING "class create failed! exiting..."); - goto err_read_ot; - - } - /* 2 numbers; one for memory and one for messages */ - error = alloc_chrdev_region(&mxt->dev_num, 0, 2, - "maXTouch_memory"); - mxt_debug(DEBUG_VERBOSE, - "device number %d allocated!\n", MAJOR(mxt->dev_num)); - if (error){ - printk(KERN_WARNING "Error registering device\n"); - } - cdev_init(&mxt->cdev, &mxt_memory_fops); - cdev_init(&mxt->cdev_messages, &mxt_message_fops); - - mxt_debug(DEBUG_VERBOSE, "cdev initialized\n"); - mxt->cdev.owner = THIS_MODULE; - mxt->cdev_messages.owner = THIS_MODULE; - - error = cdev_add(&mxt->cdev, mxt->dev_num, 1); - if (error){ - printk(KERN_WARNING "Bad cdev\n"); - } - - error = cdev_add(&mxt->cdev_messages, mxt->dev_num + 1, 1); - if (error){ - printk(KERN_WARNING "Bad cdev\n"); - } - - mxt_debug(DEBUG_VERBOSE, "cdev added\n"); - - device_create(mxt->mxt_class, NULL, MKDEV(MAJOR(mxt->dev_num), 0), NULL, - "maXTouch"); - - device_create(mxt->mxt_class, NULL, MKDEV(MAJOR(mxt->dev_num), 1), NULL, - "maXTouch_messages"); - - mxt->msg_buffer_startp = 0; - mxt->msg_buffer_endp = 0; - - /* Allocate the interrupt */ - mxt_debug(DEBUG_TRACE, "maXTouch driver allocating interrupt...\n"); - mxt->irq = gpio_to_irq(client->irq); - mxt->valid_irq_counter = 0; - mxt->invalid_irq_counter = 0; - mxt->irq_counter = 0; - - //mxt_write_byte(mxt->client, MXT_BASE_ADDR(MXT_TOUCH_MULTITOUCHSCREEN_T9, mxt)+9, 0); - -{ - int ii; - u8 t9_buf[64]; - #if 0 - mxt_read_block(mxt->client, MXT_BASE_ADDR(MXT_TOUCH_MULTITOUCHSCREEN_T9, mxt), 31, t9_buf); - printk("Enter:%s, %d mxt 224 T9 Value!==============\n"); - for(ii=1; ii<32;ii++) { - - printk("%02X ", t9_buf[ii-1]); - if((ii%8)==0){ - printk("\n"); - } - } - printk("\n"); - #endif - for(ii=0; iiclient, MXT_BASE_ADDR(MXT_TOUCH_MULTITOUCHSCREEN_T9, mxt)+ii, T9_cfg[ii]); - - mxt_write_block(client, MXT_BASE_ADDR(MXT_GEN_POWERCONFIG_T7, mxt), 2, t7_buf); -} - - if (mxt->irq) { - /* Try to request IRQ with falling edge first. This is - * not always supported. If it fails, try with any edge. */ - - error = request_irq(mxt->irq, - mxt_irq_handler, - IRQF_TRIGGER_FALLING, - client->dev.driver->name, - mxt); - if (error < 0) { - /* TODO: why only 0 works on STK1000? */ - error = request_irq(mxt->irq, - mxt_irq_handler, - 0, - client->dev.driver->name, - mxt); - } - - if (error < 0) { - dev_err(&client->dev, - "failed to allocate irq %d\n", mxt->irq); - goto err_irq; - } - } - - if (debug > DEBUG_INFO) - dev_info(&client->dev, "touchscreen, irq %d\n", mxt->irq); - - - /* Schedule a worker routine to read any messages that might have - * been sent before interrupts were enabled. */ - cancel_delayed_work(&mxt->dwork); - schedule_delayed_work(&mxt->dwork, 0); - kfree(id_data); - - return 0; - - -err_irq: - kfree(mxt->rid_map); - kfree(mxt->object_table); - kfree(mxt->last_message); -err_read_ot: -err_register_device: -err_identify: -err_pdata: - input_free_device(input); -err_input_dev_alloc: - kfree(id_data); -err_id_alloc: - if (mxt->exit_hw != NULL) - mxt->exit_hw(client); - kfree(mxt); -err_mxt_alloc: - return error; -} - -static int __devexit mxt_remove(struct i2c_client *client) -{ - struct mxt_data *mxt; - - mxt = i2c_get_clientdata(client); - - /* Remove debug dir entries */ - debugfs_remove_recursive(mxt->debug_dir); - - if (mxt != NULL) { - - if (mxt->exit_hw != NULL) - mxt->exit_hw(client); - - if (mxt->irq) { - free_irq(mxt->irq, mxt); - } - - unregister_chrdev_region(mxt->dev_num, 2); - device_destroy(mxt->mxt_class, MKDEV(MAJOR(mxt->dev_num), 0)); - device_destroy(mxt->mxt_class, MKDEV(MAJOR(mxt->dev_num), 1)); - cdev_del(&mxt->cdev); - cdev_del(&mxt->cdev_messages); - cancel_delayed_work_sync(&mxt->dwork); - input_unregister_device(mxt->input); - class_destroy(mxt->mxt_class); - debugfs_remove(mxt->debug_dir); - - kfree(mxt->rid_map); - kfree(mxt->object_table); - kfree(mxt->last_message); - } - kfree(mxt); - - i2c_set_clientdata(client, NULL); - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, "Touchscreen unregistered\n"); - - return 0; -} - -#if defined(CONFIG_PM) -static int mxt_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct mxt_data *mxt = i2c_get_clientdata(client); - char t7_buf[2] = {0, 0}; - - printk("Enter:%s, %d\n", __FUNCTION__, __LINE__); - - mxt_write_block(client, MXT_BASE_ADDR(MXT_GEN_POWERCONFIG_T7, mxt), 2, t7_buf); - if (device_may_wakeup(&client->dev)) - enable_irq_wake(mxt->irq); - - return 0; -} - -static int mxt_resume(struct i2c_client *client) -{ - struct mxt_data *mxt = i2c_get_clientdata(client); - char t5_buf[16]; - char t7_buf[2] = {64, 32}; - - printk("Enter:%s, %d\n", __FUNCTION__, __LINE__); - - mxt_write_block(client, MXT_BASE_ADDR(MXT_GEN_POWERCONFIG_T7, mxt), 2, t7_buf); - mxt_read_block(client, MXT_BASE_ADDR(MXT_GEN_MESSAGEPROCESSOR_T5, mxt), 10, t5_buf); - - if (device_may_wakeup(&client->dev)) - disable_irq_wake(mxt->irq); - - return 0; -} -#else -#define mxt_suspend NULL -#define mxt_resume NULL -#endif - -static const struct i2c_device_id mxt_idtable[] = { - {"maXTouch", 0,}, - { } -}; - -MODULE_DEVICE_TABLE(i2c, mxt_idtable); - -static struct i2c_driver mxt_driver = { - .driver = { - .name = "maXTouch", - .owner = THIS_MODULE, - }, - - .id_table = mxt_idtable, - .probe = mxt_probe, - .remove = __devexit_p(mxt_remove), - .suspend = mxt_suspend, - .resume = mxt_resume, - -}; - -static int __init mxt_init(void) -{ - int err; - err = i2c_add_driver(&mxt_driver); - if (err) { - printk(KERN_WARNING "Adding maXTouch driver failed " - "(errno = %d)\n", err); - } else { - mxt_debug(DEBUG_TRACE, "Successfully added driver %s\n", - mxt_driver.driver.name); - } - return err; -} - -static void __exit mxt_cleanup(void) -{ - i2c_del_driver(&mxt_driver); -} - - -module_init(mxt_init); -module_exit(mxt_cleanup); - -MODULE_AUTHOR("Iiro Valkonen"); -MODULE_DESCRIPTION("Driver for Atmel maXTouch Touchscreen Controller"); -MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/atmel_mxt1386.c b/drivers/input/touchscreen/atmel_mxt1386.c deleted file mode 100644 index 391db401056c..000000000000 --- a/drivers/input/touchscreen/atmel_mxt1386.c +++ /dev/null @@ -1,2625 +0,0 @@ -/* - * Atmel maXTouch Touchscreen Controller Driver - * - * - * Copyright (C) 2010 Atmel Corporation - * Copyright (C) 2009 Raphael Derosso Pereira - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * - * Driver for Atmel maXTouch family of touch controllers. - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "atmel_mxt1386.h" - -//#define YANSEN_DEBUG //yansen 20101230 regulator is under control in kernel (sbl too) -#ifdef YANSEN_DEBUG -#include -#endif - -#define DRIVER_VERSION "0.9a" -#define CONFIG_ABS_MT_TRACKING_ID - -static int debug = 0; -static int comms = 1; -static int ts_irq = 0; -static u32 last_key=0; - -module_param(debug, int, 0644); -module_param(comms, int, 0644); - -MODULE_PARM_DESC(debug, "Activate debugging output"); -MODULE_PARM_DESC(comms, "Select communications mode"); - -static int mxt_read_block(struct i2c_client *client, u16 addr, u16 length, - u8 *value); -static int mxt_write_byte(struct i2c_client *client, u16 addr, u8 value); -static int mxt_write_block(struct i2c_client *client, u16 addr, u16 length, - u8 *value); - -/* Device Info descriptor */ -/* Parsed from maXTouch "Id information" inside device */ -struct mxt_device_info { - u8 family_id; - u8 variant_id; - u8 major; - u8 minor; - u8 build; - u8 num_objs; - u8 x_size; - u8 y_size; - char family_name[16]; /* Family name */ - char variant_name[16]; /* Variant name */ - u16 num_nodes; /* Number of sensor nodes */ -}; - -/* object descriptor table, parsed from maXTouch "object table" */ -struct mxt_object { - u16 chip_addr; - u8 type; - u8 size; - u8 instances; - u8 num_report_ids; -}; - - -/* Mapping from report id to object type and instance */ -struct report_id_map { - u8 object; - u8 instance; -/* - * This is the first report ID belonging to object. It enables us to - * find out easily the touch number: each touch has different report - * ID (which are assigned to touches in increasing order). By - * subtracting the first report ID from current, we get the touch - * number. - */ - u8 first_rid; -}; - -/* Driver datastructure */ -struct mxt_data { - struct i2c_client *client; - struct input_dev *input; - char phys_name[32]; - int irq; - - u16 last_read_addr; - bool new_msgs; - u8 *last_message; - - int valid_irq_counter; - int invalid_irq_counter; - int irq_counter; - int message_counter; - int read_fail_counter; - - int bytes_to_read; - - struct delayed_work dwork; - struct work_struct work; - struct workqueue_struct *queue; - - u8 xpos_format; - u8 ypos_format; - - u8 numtouch; - - struct mxt_device_info device_info; - - u32 info_block_crc; - u32 configuration_crc; - u16 report_id_count; - struct report_id_map *rid_map; - struct mxt_object *object_table; - - u16 msg_proc_addr; - u8 message_size; - - u16 max_x_val; - u16 max_y_val; - - int (*init_hw)(struct device *dev); - void (*exit_hw)(struct device *dev); - u8 (*valid_interrupt)(void); - u8 (*read_chg)(void); - - /* debugfs variables */ - struct dentry *debug_dir; - int current_debug_datap; - - struct mutex debug_mutex; - u16 *debug_data; - - /* Character device variables */ - struct cdev cdev; - struct cdev cdev_messages; /* 2nd Char dev for messages */ - dev_t dev_num; - struct class *mxt_class; - - u16 address_pointer; - bool valid_ap; - - /* Message buffer & pointers */ - char *messages; - int msg_buffer_startp, msg_buffer_endp; - /* Put only non-touch messages to buffer if this is set */ - char nontouch_msg_only; - struct mutex msg_mutex; -}; - -static struct mxt_data *atmel_mxt; - - -#define I2C_RETRY_COUNT 5 -#define I2C_PAYLOAD_SIZE 254 - -/* Returns the start address of object in mXT memory. */ -#define MXT_BASE_ADDR(object_type, mxt) \ - get_object_address(object_type, 0, mxt->object_table, \ - mxt->device_info.num_objs) - -/* Maps a report ID to an object type (object type number). */ -#define REPORT_ID_TO_OBJECT(rid, mxt) \ - (((rid) == 0xff) ? 0 : mxt->rid_map[rid].object) - -/* Maps a report ID to an object type (string). */ -#define REPORT_ID_TO_OBJECT_NAME(rid, mxt) \ - object_type_name[REPORT_ID_TO_OBJECT(rid, mxt)] - -/* Returns non-zero if given object is a touch object */ -#define IS_TOUCH_OBJECT(object) \ - ((object == MXT_TOUCH_MULTITOUCHSCREEN_T9) || \ - (object == MXT_TOUCH_KEYARRAY_T15) || \ - (object == MXT_TOUCH_PROXIMITY_T23) || \ - (object == MXT_TOUCH_SINGLETOUCHSCREEN_T10) || \ - (object == MXT_TOUCH_XSLIDER_T11) || \ - (object == MXT_TOUCH_YSLIDER_T12) || \ - (object == MXT_TOUCH_XWHEEL_T13) || \ - (object == MXT_TOUCH_YWHEEL_T14) || \ - (object == MXT_TOUCH_KEYSET_T31) || \ - (object == MXT_TOUCH_XSLIDERSET_T32) ? 1 : 0) - -#define print_ts(level, ...) \ - do { \ - if (debug >= (level)) \ - printk(__VA_ARGS__); \ - } while (0) - -/* following are debug infomation switch, add by acgzx */ -#define TOUCH_RESET_PIN RK29_PIN6_PC3 -#define TOUCH_INT_PIN RK29_PIN0_PA2 -#define LCDC_STANDBY_PIN RK29_PIN6_PD1 -//#define TS_PEN_IRQ_GPIO RK29_PIN0_PA2//61 - -#define WORKQ_RIGHTNOW 1 -#define TOUCH_KEY_EN 1 - -/* macro switch for debug log */ -#define MXT1386_DEBUG_LOG_EN 0// 1 -#if MXT1386_DEBUG_LOG_EN -#define MXT1386_LOG printk -#else -#define MXT1386_LOG -#endif - -#define WRITE_MT_CONFIG 1//0 - -struct mxt_key_info{ - u32 start; - u32 end; - u32 virtual_x; - u32 virtual_y; - u32 code; -}; - -const struct mxt_key_info key_info[] = { - {980, 1280, 3100, 4200, KEY_SEARCH}, - {1600, 1900, 3000, 4200, KEY_HOME}, - {2200, 2500, 1100, 4200, KEY_MENU}, - {2750, 3100, 1000, 4200, KEY_BACK}, -}; - -/* - * Check whether we have multi-touch enabled kernel; if not, report just the - * first touch (on mXT224, the maximum is 10 simultaneous touches). - * Because just the 1st one is reported, it might seem that the screen is not - * responding to touch if the first touch is removed while the screen is being - * touched by another finger, so beware. - * - * TODO: investigate if there is any standard set of input events that uppper - * layers are expecting from a touchscreen? These can however be different for - * different platforms, and customers may have different opinions too about - * what should be interpreted as right-click, for example. - * - */ -#ifdef EFFICIENT_REPORT -static void report_sync(struct mxt_data *mxt) -{ - input_sync(mxt->input); -} - -static inline void report_mt(int touch_number, int size, int x, int y, struct - mxt_data *mxt) { - input_report_abs(mxt->input, ABS_MT_TRACKING_ID, touch_number); - - if(size != 0) - { - input_report_abs(mxt->input, ABS_MT_POSITION_X, x); - input_report_abs(mxt->input, ABS_MT_POSITION_Y, y); - input_report_abs(mxt->input, ABS_MT_TOUCH_MAJOR, 10); - input_report_abs(mxt->input, ABS_MT_WIDTH_MAJOR, 20); - } - else - { - input_report_abs(mxt->input, ABS_MT_TOUCH_MAJOR, 0); - input_report_abs(mxt->input, ABS_MT_WIDTH_MAJOR, 0); - } - input_mt_sync(mxt->input); -} -#else -#define MAX_FINGERS 5 -struct finger { - int x; - int y; - int size; -}; - -static struct finger fingers[MAX_FINGERS] = {}; - -static void report_mt(int touch_number, int size, int x, int y, struct - mxt_data *mxt) -{ - MXT1386_LOG(KERN_INFO "report_mt touch_number=%d, size=%d, x=%d, t=%d\n", __func__, - touch_number, size, x, y); - if (touch_number > MAX_FINGERS || touch_number < 0) { - return; - } - fingers[touch_number].x = x; - fingers[touch_number].y = y; - fingers[touch_number].size = size; - MXT1386_LOG(KERN_INFO "report_mt() OUT\n", __func__); -} - -static void report_sync(struct mxt_data *mxt) -{ - int i; - int fin = 0; - - MXT1386_LOG(KERN_INFO "report_sync() IN\n", __func__); - - for (i = 0; i < MAX_FINGERS; i++) { - if (fingers[i].size != 0) { - fin++; - MXT1386_LOG(KERN_INFO "report_sync touch_number=%d, x=%d, y=%d, width=%d\n", - i, fingers[i].x, fingers[i].y, fingers[i].size); - input_report_abs(mxt->input, ABS_MT_POSITION_X, fingers[i].x); - input_report_abs(mxt->input, ABS_MT_POSITION_Y, fingers[i].y); - input_report_abs(mxt->input, ABS_MT_TOUCH_MAJOR, 10); - input_report_abs(mxt->input, ABS_MT_WIDTH_MAJOR, 20); - input_mt_sync(mxt->input); - } - } - - if (fin == 0) { - MXT1386_LOG(KERN_INFO "report_sync no fingler\n", __func__); - input_report_abs(mxt->input, ABS_MT_TOUCH_MAJOR, 0); - input_report_abs(mxt->input, ABS_MT_WIDTH_MAJOR, 0); - input_mt_sync(mxt->input); - } - - input_sync(mxt->input); - MXT1386_LOG(KERN_INFO "report_sync() OUT\n", __func__); -} -#endif - -static inline void report_gesture(int data, struct mxt_data *mxt) -{ - //input_event(mxt->input, EV_MSC, MSC_GESTURE, data); -} - -static const u8 *object_type_name[] = { - [0] = "Reserved", - [5] = "GEN_MESSAGEPROCESSOR_T5", - [6] = "GEN_COMMANDPROCESSOR_T6", - [7] = "GEN_POWERCONFIG_T7", - [8] = "GEN_ACQUIRECONFIG_T8", - [9] = "TOUCH_MULTITOUCHSCREEN_T9", - [15] = "TOUCH_KEYARRAY_T15", - [17] = "SPT_COMMSCONFIG_T18", - [19] = "SPT_GPIOPWM_T19", - [20] = "PROCI_GRIPFACESUPPRESSION_T20", - [22] = "PROCG_NOISESUPPRESSION_T22", - [23] = "TOUCH_PROXIMITY_T23", - [24] = "PROCI_ONETOUCHGESTUREPROCESSOR_T24", - [25] = "SPT_SELFTEST_T25", - [27] = "PROCI_TWOTOUCHGESTUREPROCESSOR_T27", - [28] = "SPT_CTECONFIG_T28", - [37] = "DEBUG_DIAGNOSTICS_T37", - [38] = "SPT_USER_DATA_T38", - [40] = "PROCI_GRIPSUPPRESSION_T40", - [41] = "PROCI_PALMSUPPRESSION_T41", - [42] = "PROCI_FACESUPPRESSION_T42", - [43] = "SPT_DIGITIZER_T43", - [44] = "SPT_MESSAGECOUNT_T44", -}; - -static u16 get_object_address(uint8_t object_type, - uint8_t instance, - struct mxt_object *object_table, - int max_objs); - -int mxt_write_ap(struct mxt_data *mxt, u16 ap); - -static int mxt_read_block_wo_addr(struct i2c_client *client, - u16 length, - u8 *value); - -#if WRITE_MT_CONFIG -static const u8 atmel_1386_T7_config[] = { -140, //IDLEACQINT -25, //ACTVACQINT -60, //ACTV2IDLETO -}; - -static const u8 atmel_1386_T9_config[] = { -0x03, //CTRL 03 -0, //XORIGIN -0, //YORIGIN -28, //XSIZE -42, //YSIZE -0, //AKSCFG -32, //BLEN -60, //TCHTHR -3, //TCHDI -7, //1,//7, //ORIENT//xhh -0, //MRGTIMEOUT -5, //MOVHYSTI -5, //MOVHYSTN -18, //MOVFILTER -10, //NUMTOUCH -10, //MRGHYST -10, //MRGTHR -10, //AMPHYST -0xff, //XRANGE low -0x0f, //XRANGE high -0xff, //YRANGE low -0x0f, //YRANGE high -0, //XLOCLIP -0, //XHICLIP -0, //YLOCLIP -0, //YHICLIP -0, //XEDGECTRL -0, //XEDGEDIST -0, //YEDGECTRL -0, //YEDGEDIST -0, //JUMPLIMIT -0, //TCHHYST -45, //XPITCH -46, //YPITCH -}; - -static int atmel_1386_write_T7(struct mxt_data *mxt) -{ - int ret, i; - int size = sizeof(atmel_1386_T7_config); - for(i = 0; iclient, - MXT_BASE_ADDR(MXT_GEN_POWERCONFIG_T7, mxt) + - i, - atmel_1386_T7_config[i]); - - if (ret < 0) { - MXT1386_LOG(KERN_INFO "%s, Error writing to atmel T7!\n", __func__); - } - } - return ret; -} - -static int atmel_1386_write_T9(struct mxt_data *mxt) -{ - int ret, i; - int size = sizeof(atmel_1386_T9_config); - - for(i = 0; iclient, - MXT_BASE_ADDR(MXT_TOUCH_MULTITOUCHSCREEN_T9, mxt) + - i, - atmel_1386_T9_config[i]); - - if (ret < 0) { - MXT1386_LOG(KERN_INFO "%s, Error writing to atmel T9!\n", __func__); - } - } - return ret; -} - -static int atmel_1386_write_config(struct mxt_data *mxt) -{ - atmel_1386_write_T7(mxt); - //atmel_1386_write_T9(mxt); - - mxt_write_byte(mxt->client, - MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) + - MXT_ADR_T6_BACKUPNV, - MXT_CMD_T6_BACKUP); - /* - mxt_write_byte(mxt->client, - MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) + - MXT_ADR_T6_RESET, - 1); - */ - return 0; -} -#endif - -static u8 mxt_valid_interrupt_dummy(void) -{ - return 0; -} - -static int mxt_buf_test(const u8 *src, u8 length) -{ - u8 i; - u8 *pbuf = (u8*)src; - - MXT1386_LOG(KERN_INFO "%s, buf test start..., length = %d\n", __func__, length); - for(i=0; idebug_data; - if (data == NULL) - return -EIO; - - /* If first read after open, read all data to buffer. */ - if (mxt->current_debug_datap == 0){ - - diagnostics_reg = MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, - mxt) + - MXT_ADR_T6_DIAGNOSTIC; - if (count > (mxt->device_info.num_nodes * 2)) - count = mxt->device_info.num_nodes; - - debug_data_addr = MXT_BASE_ADDR(MXT_DEBUG_DIAGNOSTIC_T37, mxt)+ - MXT_ADR_T37_DATA; - page_address = MXT_BASE_ADDR(MXT_DEBUG_DIAGNOSTIC_T37, mxt) + - MXT_ADR_T37_PAGE; - error = mxt_read_block(mxt->client, page_address, 1, &page); - if (error < 0) - return error; - MXT1386_LOG(KERN_INFO "debug data page = %d\n", __func__, page); - while (page != 0) { - error = mxt_write_byte(mxt->client, - diagnostics_reg, - MXT_CMD_T6_PAGE_DOWN); - if (error < 0) - return error; - /* Wait for command to be handled; when it has, the - register will be cleared. */ - debug_command_reg = 1; - while (debug_command_reg != 0) { - error = mxt_read_block(mxt->client, - diagnostics_reg, 1, - &debug_command_reg); - if (error < 0) - return error; - MXT1386_LOG(KERN_INFO "Waiting for debug diag command " - "to propagate...\n", __func__); - - } - error = mxt_read_block(mxt->client, page_address, 1, - &page); - if (error < 0) - return error; - MXT1386_LOG(KERN_INFO "debug data page = %d\n", __func__, page); - } - - /* - * Lock mutex to prevent writing some unwanted data to debug - * command register. User can still write through the char - * device interface though. TODO: fix? - */ - - mutex_lock(&mxt->debug_mutex); - /* Configure Debug Diagnostics object to show deltas/refs */ - error = mxt_write_byte(mxt->client, diagnostics_reg, - debug_command); - - /* Wait for command to be handled; when it has, the - * register will be cleared. */ - debug_command_reg = 1; - while (debug_command_reg != 0) { - error = mxt_read_block(mxt->client, - diagnostics_reg, 1, - &debug_command_reg); - if (error < 0) - return error; - MXT1386_LOG(KERN_INFO "Waiting for debug diag command " - "to propagate...\n", __func__); - - } - - if (error < 0) { - MXT1386_LOG(KERN_INFO "Error writing to maXTouch device!\n", __func__); - return error; - } - - size = mxt->device_info.num_nodes * sizeof(u16); - - while (size > 0) { - read_size = size > 128 ? 128 : size; - MXT1386_LOG(KERN_INFO "Debug data read loop, reading %d bytes...\n", __func__, - read_size); - error = mxt_read_block(mxt->client, - debug_data_addr, - read_size, - (u8 *) &data[offset]); - if (error < 0) { - MXT1386_LOG(KERN_INFO "Error reading debug data\n", __func__); - goto error; - } - offset += read_size/2; - size -= read_size; - - /* Select next page */ - error = mxt_write_byte(mxt->client, diagnostics_reg, - MXT_CMD_T6_PAGE_UP); - if (error < 0) { - MXT1386_LOG(KERN_INFO "Error writing to maXTouch device!\n", __func__); - goto error; - } - } - mutex_unlock(&mxt->debug_mutex); - } - - buf_start = buf; - i = mxt->current_debug_datap; - - while (((buf- buf_start) < (count - 6)) && - (i < mxt->device_info.num_nodes)){ - - mxt->current_debug_datap++; - if (debug_command == MXT_CMD_T6_REFERENCES_MODE) - buf += sprintf(buf, "%d: %5d\n", i, - (u16) le16_to_cpu(data[i])); - else if (debug_command == MXT_CMD_T6_DELTAS_MODE) - buf += sprintf(buf, "%d: %5d\n", i, - (s16) le16_to_cpu(data[i])); - i++; - } - - return (buf - buf_start); -error: - mutex_unlock(&mxt->debug_mutex); - return error; -} - -ssize_t deltas_read(struct file *file, char *buf, size_t count, loff_t *ppos) -{ - return debug_data_read(file->private_data, buf, count, ppos, - MXT_CMD_T6_DELTAS_MODE); -} - -ssize_t refs_read(struct file *file, char *buf, size_t count, - loff_t *ppos) -{ - return debug_data_read(file->private_data, buf, count, ppos, - MXT_CMD_T6_REFERENCES_MODE); -} - -int debug_data_open(struct inode *inode, struct file *file) -{ - struct mxt_data *mxt; - int i; - mxt = inode->i_private; - if (mxt == NULL) - return -EIO; - mxt->current_debug_datap = 0; - mxt->debug_data = kmalloc(mxt->device_info.num_nodes * sizeof(u16), - GFP_KERNEL); - if (mxt->debug_data == NULL) - return -ENOMEM; - - - for (i = 0; i < mxt->device_info.num_nodes; i++) - mxt->debug_data[i] = 7777; - - - file->private_data = mxt; - return 0; -} - -int debug_data_release(struct inode *inode, struct file *file) -{ - struct mxt_data *mxt; - mxt = file->private_data; - kfree(mxt->debug_data); - return 0; -} - -static struct file_operations delta_fops = { - .owner = THIS_MODULE, - .open = debug_data_open, - .release = debug_data_release, - .read = deltas_read, -}; - -static struct file_operations refs_fops = { - .owner = THIS_MODULE, - .open = debug_data_open, - .release = debug_data_release, - .read = refs_read, -}; - - -int mxt_memory_open(struct inode *inode, struct file *file) -{ - struct mxt_data *mxt; - mxt = container_of(inode->i_cdev, struct mxt_data, cdev); - if (mxt == NULL) - return -EIO; - file->private_data = mxt; - return 0; -} - -int mxt_message_open(struct inode *inode, struct file *file) -{ - struct mxt_data *mxt; - mxt = container_of(inode->i_cdev, struct mxt_data, cdev_messages); - if (mxt == NULL) - return -EIO; - file->private_data = mxt; - return 0; -} - - -ssize_t mxt_memory_read(struct file *file, char *buf, size_t count, - loff_t *ppos) -{ - int i; - struct mxt_data *mxt; - - mxt = file->private_data; - if (mxt->valid_ap){ - MXT1386_LOG(KERN_INFO "Reading %d bytes from current ap\n", __func__, - (int) count); - i = mxt_read_block_wo_addr(mxt->client, count, (u8 *) buf); - } else { - MXT1386_LOG(KERN_INFO "Address pointer changed since set;" - "writing AP (%d) before reading %d bytes", __func__, - mxt->address_pointer, (int) count); - i = mxt_read_block(mxt->client, mxt->address_pointer, count, - buf); - } - - return i; -} - -ssize_t mxt_memory_write(struct file *file, const char *buf, size_t count, - loff_t *ppos) -{ - int i; - int whole_blocks; - int last_block_size; - struct mxt_data *mxt; - u16 address; - - mxt = file->private_data; - address = mxt->address_pointer; - - MXT1386_LOG(KERN_INFO "mxt_memory_write entered\n", __func__); - whole_blocks = count / I2C_PAYLOAD_SIZE; - last_block_size = count % I2C_PAYLOAD_SIZE; - - for (i = 0; i < whole_blocks; i++) { - MXT1386_LOG(KERN_INFO "About to write to %d...\n", __func__, - address); - mxt_write_block(mxt->client, address, I2C_PAYLOAD_SIZE, - (u8 *) buf); - address += I2C_PAYLOAD_SIZE; - buf += I2C_PAYLOAD_SIZE; - } - - mxt_write_block(mxt->client, address, last_block_size, (u8 *) buf); - - return count; -} - - -#define MXT_SET_ADDRESS 0 -#define MXT_RESET 1 -#define MXT_CALIBRATE 2 -#define MXT_BACKUP 3 -#define MXT_NONTOUCH_MSG 4 -#define MXT_ALL_MSG 5 - -static int mxt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int retval; - struct mxt_data *mxt; - - retval = 0; - mxt = file->private_data; - - switch (cmd) { - case MXT_SET_ADDRESS: - retval = mxt_write_ap(mxt, (u16) arg); - if (retval >= 0) { - mxt->address_pointer = (u16) arg; - mxt->valid_ap = 1; - } - break; - case MXT_RESET: - retval = mxt_write_byte(mxt->client, - MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) + - MXT_ADR_T6_RESET, - 1); - break; - case MXT_CALIBRATE: - retval = mxt_write_byte(mxt->client, - MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) + - MXT_ADR_T6_CALIBRATE, - 1); - - break; - case MXT_BACKUP: - retval = mxt_write_byte(mxt->client, - MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) + - MXT_ADR_T6_BACKUPNV, - MXT_CMD_T6_BACKUP); - break; - case MXT_NONTOUCH_MSG: - mxt->nontouch_msg_only = 1; - break; - case MXT_ALL_MSG: - mxt->nontouch_msg_only = 0; - break; - default: - return -EIO; - } - - return retval; -} - -/* - * Copies messages from buffer to user space. - * - * NOTE: if less than (mxt->message_size * 5 + 1) bytes requested, - * this will return 0! - * - */ -ssize_t mxt_message_read(struct file *file, char *buf, size_t count, - loff_t *ppos) -{ - int i; - struct mxt_data *mxt; - char *buf_start; - - mxt = file->private_data; - if (mxt == NULL) - return -EIO; - buf_start = buf; - - mutex_lock(&mxt->msg_mutex); - /* Copy messages until buffer empty, or 'count' bytes written */ - while ((mxt->msg_buffer_startp != mxt->msg_buffer_endp) && - ((buf - buf_start) < (count - 5 * mxt->message_size - 1))){ - - for (i = 0; i < mxt->message_size; i++){ - buf += sprintf(buf, "[%2X] ", - *(mxt->messages + mxt->msg_buffer_endp * - mxt->message_size + i)); - } - buf += sprintf(buf, "\n"); - if (mxt->msg_buffer_endp < MXT_MESSAGE_BUFFER_SIZE) - mxt->msg_buffer_endp++; - else - mxt->msg_buffer_endp = 0; - } - mutex_unlock(&mxt->msg_mutex); - return (buf - buf_start); -} - -static struct file_operations mxt_message_fops = { - .owner = THIS_MODULE, - .open = mxt_message_open, - .read = mxt_message_read, -}; - -static struct file_operations mxt_memory_fops = { - .owner = THIS_MODULE, - .open = mxt_memory_open, - .read = mxt_memory_read, - .write = mxt_memory_write, - .ioctl = mxt_ioctl, -}; - - -/* Writes the address pointer (to set up following reads). */ - -int mxt_write_ap(struct mxt_data *mxt, u16 ap) -{ - struct i2c_client *client; - __le16 le_ap = cpu_to_le16(ap); - client = mxt->client; - if (mxt != NULL) - mxt->last_read_addr = -1; - if (i2c_master_send(client, (u8 *) &le_ap, 2) == 2) { - MXT1386_LOG(KERN_INFO "Address pointer set to %d\n", __func__, ap); - return 0; - } else { - MXT1386_LOG(KERN_INFO "Error writing address pointer!\n", __func__); - return -EIO; - } -} - -/* Calculates the 24-bit CRC sum. */ -static u32 CRC_24(u32 crc, u8 byte1, u8 byte2) -{ - static const u32 crcpoly = 0x80001B; - u32 result; - u32 data_word; - - data_word = ((((u16) byte2) << 8u) | byte1); - result = ((crc << 1u) ^ data_word); - if (result & 0x1000000) - result ^= crcpoly; - return result; -} - -/* Returns object address in mXT chip, or zero if object is not found */ -static u16 get_object_address(uint8_t object_type, - uint8_t instance, - struct mxt_object *object_table, - int max_objs) -{ - uint8_t object_table_index = 0; - uint8_t address_found = 0; - uint16_t address = 0; - struct mxt_object *obj; - - while ((object_table_index < max_objs) && !address_found) { - obj = &object_table[object_table_index]; - if (obj->type == object_type) { - address_found = 1; - /* Are there enough instances defined in the FW? */ - if (obj->instances >= instance) { - address = obj->chip_addr + - (obj->size + 1) * instance; - } else { - return 0; - } - } - object_table_index++; - } - return address; -} - - -/* - * Reads a block of bytes from given address from mXT chip. If we are - * reading from message window, and previous read was from message window, - * there's no need to write the address pointer: the mXT chip will - * automatically set the address pointer back to message window start. - */ - -static int mxt_read_block(struct i2c_client *client, - u16 addr, - u16 length, - u8 *value) -{ - struct i2c_adapter *adapter = client->adapter; - struct i2c_msg msg[2]; - __le16 le_addr; - struct mxt_data *mxt; - - mxt = i2c_get_clientdata(client); - - if (mxt != NULL) { - MXT1386_LOG(KERN_INFO "%s: msg addr test, mxt->msg_proc_addr = 0x%x, mxt->last_read_addr = 0x%x, current addr = 0x%x\n", - __func__, mxt->msg_proc_addr, mxt->last_read_addr, addr); - - if ((mxt->last_read_addr == addr) && - (addr == mxt->msg_proc_addr)) { - if (i2c_master_recv(client, value, length) == length) { - MXT1386_LOG(KERN_INFO "%s: Host is reading from chip, addr = 0x%x, length = %d, *value = %d\n", - __func__, addr, length, *value); - return length; - } - else { - MXT1386_LOG(KERN_INFO "%s: Host read failed!\n", __func__); - return -EIO; - } - } else { - mxt->last_read_addr = addr; - } - } - - le_addr = cpu_to_le16(addr); - MXT1386_LOG(KERN_INFO "%s: Writing address pointer & reading, addr = 0x%02x, , le_addr = 0x%02x, length = %d, *value = %d\n", - __func__, addr, le_addr, length, *value); - - msg[0].addr = client->addr; - msg[0].flags = 0x00; - msg[0].len = 2; - msg[0].buf = (u8 *) &le_addr; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = length; - msg[1].buf = (u8 *) value; - if (i2c_transfer(adapter, msg, 2) == 2) - return length; - else - return -EIO; -} - -/* Reads a block of bytes from current address from mXT chip. */ -static int mxt_read_block_wo_addr(struct i2c_client *client, - u16 length, - u8 *value) -{ - if (i2c_master_recv(client, value, length) == length) { - MXT1386_LOG(KERN_INFO "%s: I2C block read ok\n", __func__); - return length; - } else { - MXT1386_LOG(KERN_INFO "%s: I2C block read failed\n", __func__); - return -EIO; - } -} - -/* Writes one byte to given address in mXT chip. */ -static int mxt_write_byte(struct i2c_client *client, u16 addr, u8 value) -{ - struct { - __le16 le_addr; - u8 data; - - } i2c_byte_transfer; - - struct mxt_data *mxt; - - mxt = i2c_get_clientdata(client); - if (mxt != NULL) - mxt->last_read_addr = -1; - i2c_byte_transfer.le_addr = cpu_to_le16(addr); - i2c_byte_transfer.data = value; - if (i2c_master_send(client, (u8 *) &i2c_byte_transfer, 3) == 3) - return 0; - else - return -EIO; -} - -/* Writes a block of bytes (max 256) to given address in mXT chip. */ -static int mxt_write_block(struct i2c_client *client, - u16 addr, - u16 length, - u8 *value) -{ - int i; - struct { - __le16 le_addr; - u8 data[256]; - - } i2c_block_transfer; - - struct mxt_data *mxt; - - MXT1386_LOG("Writing %d bytes to %d...\n", length, addr); - if (length > 256) - return -EINVAL; - mxt = i2c_get_clientdata(client); - if (mxt != NULL) - mxt->last_read_addr = -1; - for (i = 0; i < length; i++) - i2c_block_transfer.data[i] = *value++; - i2c_block_transfer.le_addr = cpu_to_le16(addr); - i = i2c_master_send(client, (u8 *) &i2c_block_transfer, length + 2); - if (i == (length + 2)) - return length; - else - return -EIO; -} - -/* Calculates the CRC value for mXT infoblock. */ -int calculate_infoblock_crc(u32 *crc_result, u8 *data, int crc_area_size) -{ - u32 crc = 0; - int i; - - for (i = 0; i < (crc_area_size - 1); i = i + 2) - crc = CRC_24(crc, *(data + i), *(data + i + 1)); - /* If uneven size, pad with zero */ - if (crc_area_size & 0x0001) - crc = CRC_24(crc, *(data + i), 0); - /* Return only 24 bits of CRC. */ - *crc_result = (crc & 0x00FFFFFF); - - return 0; -} - -int find_touch_key_value( struct mxt_data *mxt, int status, u16 ypos) -{ - int i = 0; - for(i=0; i key_info[i].start) && (ypos < key_info[i].end)) - { - printk("%s key_code = %d \n",__func__,key_info[i].code); - if(status & MXT_MSGB_T9_DETECT) - { - input_report_key(mxt->input, key_info[i].code, 1); - input_sync(mxt->input); - last_key = key_info[i].code; - } - else - { - printk("%s key_code = %d relase\n",__func__,key_info[i].code); - input_report_key(mxt->input, key_info[i].code, 0); - input_sync(mxt->input); - last_key = 0; - - } - break; - } - } - - - return 0; -} - - -void process_T9_message(u8 *message, struct mxt_data *mxt) -{ - struct input_dev *input; - u8 status; - u16 xpos = 0xFFFF; - u16 ypos = 0xFFFF; - u8 touch_size = 255; - u8 touch_number; - u8 amplitude; - u8 report_id; - u32 key_code = 0; - - input = mxt->input; - status = message[MXT_MSG_T9_STATUS]; - report_id = message[0]; - - if (status & MXT_MSGB_T9_SUPPRESS) { - /* Touch has been suppressed by grip/face */ - /* detection */ - MXT1386_LOG(KERN_INFO "SUPRESS\n", __func__); - } else { - MXT1386_LOG("XPOSMSB = 0x%02x, YPOSMSB = 0x%02x, XYPOSLSB = 0x%02x\n", - message[MXT_MSG_T9_XPOSMSB], message[MXT_MSG_T9_YPOSMSB], message[MXT_MSG_T9_XYPOSLSB]); - - xpos = message[MXT_MSG_T9_XPOSMSB] * 16 + - ((message[MXT_MSG_T9_XYPOSLSB] >> 4) & 0xF); - ypos = message[MXT_MSG_T9_YPOSMSB] * 16 + - ((message[MXT_MSG_T9_XYPOSLSB] >> 0) & 0xF); - - MXT1386_LOG("Before Reverse: xpos = %d, ypos = %d\n", xpos, ypos); - #if 0 //xhh - //颠倒X坐标 - if( xpos < CONFIG_ATMEL_MXT1386_MAX_X) - xpos = CONFIG_ATMEL_MXT1386_MAX_X - xpos; - else - xpos = 0; - - //颠倒Y坐标 - if( ypos < CONFIG_ATMEL_MXT1386_MAX_Y) - ypos = CONFIG_ATMEL_MXT1386_MAX_Y - ypos; - else - ypos = 0; - #endif - - #if TOUCH_KEY_EN - if( xpos < 8 && xpos >= 0) - { - find_touch_key_value(mxt, status, ypos); - return; - } - else if(last_key) - { - - printk("%s key_code = %d relase\n",__func__,last_key); - input_report_key(mxt->input, last_key, 0); - input_sync(mxt->input); - last_key = 0; - } - #endif - - MXT1386_LOG("After Reverse: xpos = %d, ypos = %d\n", xpos, ypos); - - touch_number = message[MXT_MSG_REPORTID] - - mxt->rid_map[report_id].first_rid; - - if (status & MXT_MSGB_T9_DETECT) { - /* - * TODO: more precise touch size calculation? - * mXT224 reports the number of touched nodes, - * so the exact value for touch ellipse major - * axis length would be 2*sqrt(touch_size/pi) - * (assuming round touch shape). - */ - MXT1386_LOG(KERN_INFO " ----process_T9_message --MXT_MSGB_T9_DETECT--- \n", __func__); - touch_size = message[MXT_MSG_T9_TCHAREA]; - touch_size = touch_size >> 2; - if (!touch_size) - touch_size = 1; - report_mt(touch_number, touch_size, xpos, ypos, mxt); - if (status & MXT_MSGB_T9_AMP) - /* Amplitude of touch has changed */ - amplitude = message[MXT_MSG_T9_TCHAMPLITUDE]; - } else if (status & MXT_MSGB_T9_RELEASE) { - /* The previously reported touch has been removed.*/ - MXT1386_LOG(KERN_INFO " ----process_T9_message --MXT_MSGB_T9_RELEASE--- \n", __func__); - report_mt(touch_number, 0, xpos, ypos, mxt); - } - #ifdef EFFICIENT_REPORT - #else - report_sync(mxt); - #endif - } - - if (status & MXT_MSGB_T9_SUPPRESS) { - MXT1386_LOG(KERN_INFO "SUPRESS", __func__); - } else { - if (status & MXT_MSGB_T9_DETECT) { - MXT1386_LOG(KERN_INFO "DETECT:%s%s%s%s", __func__, - ((status & MXT_MSGB_T9_PRESS) ? " PRESS" : ""), - ((status & MXT_MSGB_T9_MOVE) ? " MOVE" : ""), - ((status & MXT_MSGB_T9_AMP) ? " AMP" : ""), - ((status & MXT_MSGB_T9_VECTOR) ? " VECT" : "")); - - } else if (status & MXT_MSGB_T9_RELEASE) { - MXT1386_LOG(KERN_INFO "RELEASE"); - } - } - MXT1386_LOG(KERN_INFO "X=%d, Y=%d, TOUCHSIZE=%d", __func__, - xpos, ypos, touch_size); - - return; -} - -int process_message(u8 *message, u8 object, struct mxt_data *mxt) -{ - struct i2c_client *client; - u8 status; - u16 xpos = 0xFFFF; - u16 ypos = 0xFFFF; - u8 event; - u8 direction; - u16 distance; - u8 length; - u8 report_id; - int keyIndex; - - client = mxt->client; - length = mxt->message_size; - report_id = message[0]; - - if ((mxt->nontouch_msg_only == 0) || - (!IS_TOUCH_OBJECT(object))){ - mutex_lock(&mxt->msg_mutex); - /* Copy the message to buffer */ - if (mxt->msg_buffer_startp < MXT_MESSAGE_BUFFER_SIZE) { - mxt->msg_buffer_startp++; - } else { - mxt->msg_buffer_startp = 0; - } - - if (mxt->msg_buffer_startp == mxt->msg_buffer_endp) { - MXT1386_LOG(KERN_INFO "Message buf full, discarding last entry.\n", __func__); - if (mxt->msg_buffer_endp < MXT_MESSAGE_BUFFER_SIZE) { - mxt->msg_buffer_endp++; - } else { - mxt->msg_buffer_endp = 0; - } - } - memcpy((mxt->messages + mxt->msg_buffer_startp * length), - message, - length); - mutex_unlock(&mxt->msg_mutex); - } - - switch (object) { - case MXT_GEN_COMMANDPROCESSOR_T6: - status = message[1]; - if (status & MXT_MSGB_T6_COMSERR) { - dev_err(&client->dev, - "maXTouch checksum error\n"); - } - if (status & MXT_MSGB_T6_CFGERR) { - /* - * Configuration error. A proper configuration - * needs to be written to chip and backed up. Refer - * to protocol document for further info. - */ - dev_err(&client->dev, - "maXTouch configuration error\n"); - } - if (status & MXT_MSGB_T6_CAL) { - /* Calibration in action, no need to react */ - dev_info(&client->dev, - "maXTouch calibration in progress\n"); - } - if (status & MXT_MSGB_T6_SIGERR) { - /* - * Signal acquisition error, something is seriously - * wrong, not much we can in the driver to correct - * this - */ - dev_err(&client->dev, - "maXTouch acquisition error\n"); - } - if (status & MXT_MSGB_T6_OFL) { - /* - * Cycle overflow, the acquisition is too short. - * Can happen temporarily when there's a complex - * touch shape on the screen requiring lots of - * processing. - */ - dev_err(&client->dev, - "maXTouch cycle overflow\n"); - } - if (status & MXT_MSGB_T6_RESET) { - /* Chip has reseted, no need to react. */ - dev_info(&client->dev, - "maXTouch chip reset\n"); - } - if (status == 0) { - /* Chip status back to normal. */ - dev_info(&client->dev, - "maXTouch status normal\n"); - } - break; - - case MXT_TOUCH_MULTITOUCHSCREEN_T9: - process_T9_message(message, mxt); - break; - - case MXT_SPT_GPIOPWM_T19: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving GPIO message\n"); - break; - - case MXT_PROCI_GRIPFACESUPPRESSION_T20: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving face suppression msg\n"); - break; - - case MXT_PROCG_NOISESUPPRESSION_T22: - printk("--------- MXT_PROCG_NOISESUPPRESSION_T22 enter! ---------\n"); - //if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving noise suppression msg\n"); - status = message[MXT_MSG_T22_STATUS]; - if (status & MXT_MSGB_T22_FHCHG) { - //if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: Freq changed\n"); - } - if (status & MXT_MSGB_T22_GCAFERR) { - //if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: High noise " - "level\n"); - } - if (status & MXT_MSGB_T22_FHERR) { - //if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: Freq changed - " - "Noise level too high\n"); - } - break; - - case MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving one-touch gesture msg\n"); - - event = message[MXT_MSG_T24_STATUS] & 0x0F; - xpos = message[MXT_MSG_T24_XPOSMSB] * 16 + - ((message[MXT_MSG_T24_XYPOSLSB] >> 4) & 0x0F); - ypos = message[MXT_MSG_T24_YPOSMSB] * 16 + - ((message[MXT_MSG_T24_XYPOSLSB] >> 0) & 0x0F); - xpos >>= 2; - ypos >>= 2; - direction = message[MXT_MSG_T24_DIR]; - distance = message[MXT_MSG_T24_DIST] + - (message[MXT_MSG_T24_DIST + 1] << 16); - - report_gesture((event << 24) | (direction << 16) | distance, - mxt); - report_gesture((xpos << 16) | ypos, mxt); - - break; - - case MXT_SPT_SELFTEST_T25: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving Self-Test msg\n"); - - if (message[MXT_MSG_T25_STATUS] == MXT_MSGR_T25_OK) { - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: Self-Test OK\n"); - - } else { - dev_err(&client->dev, - "maXTouch: Self-Test Failed [%02x]:" - "{%02x,%02x,%02x,%02x,%02x}\n", - message[MXT_MSG_T25_STATUS], - message[MXT_MSG_T25_STATUS + 0], - message[MXT_MSG_T25_STATUS + 1], - message[MXT_MSG_T25_STATUS + 2], - message[MXT_MSG_T25_STATUS + 3], - message[MXT_MSG_T25_STATUS + 4] - ); - } - break; - - case MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving 2-touch gesture message\n"); - - event = message[MXT_MSG_T27_STATUS] & 0xF0; - xpos = message[MXT_MSG_T27_XPOSMSB] * 16 + - ((message[MXT_MSG_T27_XYPOSLSB] >> 4) & 0x0F); - ypos = message[MXT_MSG_T27_YPOSMSB] * 16 + - ((message[MXT_MSG_T27_XYPOSLSB] >> 0) & 0x0F); - xpos >>= 2; - ypos >>= 2; - direction = message[MXT_MSG_T27_ANGLE]; - distance = message[MXT_MSG_T27_SEPARATION] + - (message[MXT_MSG_T27_SEPARATION + 1] << 16); - - report_gesture((event << 24) | (direction << 16) | distance, - mxt); - report_gesture((xpos << 16) | ypos, mxt); - - - break; - - case MXT_SPT_CTECONFIG_T28: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "Receiving CTE message...\n"); - status = message[MXT_MSG_T28_STATUS]; - if (status & MXT_MSGB_T28_CHKERR) - dev_err(&client->dev, - "maXTouch: Power-Up CRC failure\n"); - - break; - - default: - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, - "maXTouch: Unknown message!\n"); - - break; - } - - return 0; -} - - -/* - * Processes messages when the interrupt line (CHG) is asserted. Keeps - * reading messages until a message with report ID 0xFF is received, - * which indicates that there is no more new messages. - * - */ - -static void ts_thread_1386(struct work_struct *work) -{ - struct mxt_data *mxt; - struct i2c_client *client; - - u8 *message; - u16 message_length; - u16 message_addr; - u8 report_id = 0; - u8 object = 0; - #ifdef EFFICIENT_REPORT - u8 has_multitouch_msg = 0; - #endif - int error; - int i; - char *message_string; - char *message_start; - static u32 count; - - message = NULL; - //mxt = container_of(work, struct mxt_data, dwork.work); - mxt = atmel_mxt; - //disable_irq(mxt->irq); - client = mxt->client; - message_addr = mxt->msg_proc_addr; - message_length = mxt->message_size; - - MXT1386_LOG(KERN_INFO "%s: ts_thread_1386 entry %d times!\n", __func__, ++count); - - if (message_length < 256) { - message = kmalloc(message_length, GFP_KERNEL); - if (message == NULL) { - dev_err(&client->dev, "Error allocating memory\n"); - return; - } - } else { - dev_err(&client->dev, - "Message length larger than 256 bytes not supported\n"); - return; - } - - do { - /* Read next message, reread on failure. */ - mxt->message_counter++; - for (i = 1; i < I2C_RETRY_COUNT; i++) { - error = mxt_read_block(client, - message_addr, - message_length, - message); - if (error >= 0) - break; - mxt->read_fail_counter++; - dev_err(&client->dev, - "Failure reading maxTouch device\n"); - } - if (error < 0) { - kfree(message); - return; - } - - if (mxt->address_pointer != message_addr) - mxt->valid_ap = 0; - report_id = message[0]; - - if (debug >= DEBUG_RAW) { - MXT1386_LOG(KERN_INFO "%s: %s message [msg count: %08x]:", __func__, - REPORT_ID_TO_OBJECT_NAME(report_id, mxt), - mxt->message_counter - ); - /* 5 characters per one byte */ - message_string = kmalloc(message_length * 5, - GFP_KERNEL); - if (message_string == NULL) { - dev_err(&client->dev, - "Error allocating memory\n"); - kfree(message); - return; - } - message_start = message_string; - for (i = 0; i < message_length; i++) { - message_string += - sprintf(message_string, - "0x%02X ", message[i]); - } - MXT1386_LOG(KERN_INFO "%s", message_start, __func__); - kfree(message_start); - } - - if ((report_id != MXT_END_OF_MESSAGES) && (report_id != 0)) { - memcpy(mxt->last_message, message, message_length); - mxt->new_msgs = 1; - smp_wmb(); - /* Get type of object and process the message */ - object = mxt->rid_map[report_id].object; - - MXT1386_LOG(KERN_INFO "current value: mxt->rid_map[%d].object = %d, object = %d\n", - __func__, report_id, mxt->rid_map[report_id].object, object); - mxt_buf_test(message, message_length); - - process_message(message, object, mxt); - MXT1386_LOG(KERN_INFO "trace 0\n", __func__); - } - - #ifdef EFFICIENT_REPORT - if(object == MXT_TOUCH_MULTITOUCHSCREEN_T9) - { - has_multitouch_msg = 1; - } - else if( has_multitouch_msg == 1) - { - has_multitouch_msg = 0; - report_sync(mxt); - } - object = 0; - #endif - - } while (comms ? (mxt->read_chg() == 0) : - ((report_id != MXT_END_OF_MESSAGES) && (report_id != 0))); - //} while ((report_id != MXT_END_OF_MESSAGES) && (report_id != 0)); - - /* - #ifdef EFFICIENT_REPORT - report_sync(mxt); - #endif - */ - - kfree(message); - - MXT1386_LOG(KERN_INFO "%s: Now will enable the irq, ts_irq = %d\n", __func__, ts_irq); - enable_irq(mxt->irq); - //printk("%s, int_pin = %d \n",__func__,gpio_get_value(client->irq)); -} - -/* - * The maXTouch device will signal the host about a new message by asserting - * the CHG line. This ISR schedules a worker routine to read the message when - * that happens. - */ - -//static struct workqueue_struct *queue = NULL; -//static struct work_struct work; - -static irqreturn_t mxt_irq_handler(int irq, void *dev_id) -{ - struct mxt_data *mxt = (struct mxt_data *)dev_id; - struct i2c_client *client = mxt->client; - int int_value = client->irq; - static u8 wakeup_flag; - static u32 counter; - /* 目前TP的中断行为如下: 当LCD进入standby模式后,背光控制脚LCDC_CS将拉低,此时LCDC_CS控制的背光升压输入端(DCtoDC输入端)TPVCC也将被拉低, - 使背光关闭;由于TPVCC同时也作为TP的电源输入端,此时系统若在TPVCC为低电平的情况下进入TP的ISR函数,TP设备将不应答,并且将不被唤醒。 因此, - 在此增加一个静态标志,判断当LCDS脚为低时,不启动工作队列,同时将wakeup_flag标志置1,下次进入中断时,不再禁止中断,直接启动工作队列*/ - -#if 0 - MXT1386_LOG(KERN_INFO "mxt_irq_handler() IN\n"); - - mxt->irq_counter++; - if (mxt->valid_interrupt()) { - /* Send the signal only if falling edge generated the irq. */ - cancel_delayed_work(&mxt->dwork); - schedule_delayed_work(&mxt->dwork, 0); - mxt->valid_irq_counter++; - } else { - mxt->invalid_irq_counter++; - return IRQ_NONE; - } - - MXT1386_LOG(KERN_INFO "-------------- Be carefull MXC_touchscreen interrupt comes! --------------\n", __func__); - MXT1386_LOG(KERN_INFO "interrupt counter road\n"); - disable_irq_nosync(mxt->irq); - - queue_work(mxt->queue,&mxt->work); - -#else - - MXT1386_LOG(KERN_INFO "-------------- Be carefull MXC_touchscreen interrupt comes! --------------\n", __func__); - MXT1386_LOG(KERN_INFO "ts_irq = %d, irq = %d, mxt->irq = %d, TOUCH_INT_PIN = %d\n", __func__, ts_irq, irq, mxt->irq, int_value); - - if(gpio_get_value(LCDC_STANDBY_PIN)) { - MXT1386_LOG(KERN_INFO "%s: LCDC_STANDBY_PIN test, value is high\n", __func__); - - if (0==wakeup_flag) { - disable_irq_nosync(mxt->irq); - } - else { - wakeup_flag = 0; - } - -#if WORKQ_RIGHTNOW - MXT1386_LOG(KERN_INFO "%s: queue_work start\n", __func__); - queue_work(mxt->queue,&mxt->work); -#else - MXT1386_LOG(KERN_INFO "%s: queue_delayed_work start\n", __func__); - queue_delayed_work(mxt->queue, &mxt->dwork, 0); -#endif - } - else { - MXT1386_LOG(KERN_INFO "%s: LCDC_STANDBY_PIN test, value is low\n", __func__); - wakeup_flag = 1; - return IRQ_NONE; - } -#endif - return IRQ_HANDLED; -} - -/******************************************************************************/ -/* Initialization of driver */ -/******************************************************************************/ - -static int __devinit mxt_identify(struct i2c_client *client, - struct mxt_data *mxt, - u8 *id_block_data) -{ - u8 buf[7]; - int error; - int identified; - - identified = 0; - - /* Read Device info to check if chip is valid */ - error = mxt_read_block(client, MXT_ADDR_INFO_BLOCK, MXT_ID_BLOCK_SIZE, - (u8 *) buf); - - if (error < 0) { - mxt->read_fail_counter++; - dev_err(&client->dev, "Failure accessing maXTouch device\n"); - return -EIO; - } - - memcpy(id_block_data, buf, MXT_ID_BLOCK_SIZE); - - mxt->device_info.family_id = buf[0]; - mxt->device_info.variant_id = buf[1]; - mxt->device_info.major = ((buf[2] >> 4) & 0x0F); - mxt->device_info.minor = (buf[2] & 0x0F); - mxt->device_info.build = buf[3]; - mxt->device_info.x_size = buf[4]; - mxt->device_info.y_size = buf[5]; - mxt->device_info.num_objs = buf[6]; - mxt->device_info.num_nodes = mxt->device_info.x_size * - mxt->device_info.y_size; - - /* - * Check Family & Variant Info; warn if not recognized but - * still continue. - */ - - /* MXT224 */ - if (mxt->device_info.family_id == MXT224_FAMILYID) { - strcpy(mxt->device_info.family_name, "mXT224"); - - if (mxt->device_info.variant_id == MXT224_CAL_VARIANTID) { - strcpy(mxt->device_info.variant_name, "Calibrated"); - } else if (mxt->device_info.variant_id == - MXT224_UNCAL_VARIANTID) { - strcpy(mxt->device_info.variant_name, "Uncalibrated"); - } else { - dev_err(&client->dev, - "Warning: maXTouch Variant ID [%d] not " - "supported\n", - mxt->device_info.variant_id); - strcpy(mxt->device_info.variant_name, "UNKNOWN"); - /* identified = -ENXIO; */ - } - - /* MXT1386 */ - } else if (mxt->device_info.family_id == MXT1386_FAMILYID) { - strcpy(mxt->device_info.family_name, "mXT1386"); - - if (mxt->device_info.variant_id == MXT1386_CAL_VARIANTID) { - strcpy(mxt->device_info.variant_name, "Calibrated"); - } else { - dev_err(&client->dev, - "Warning: maXTouch Variant ID [%d] not " - "supported\n", - mxt->device_info.variant_id); - strcpy(mxt->device_info.variant_name, "UNKNOWN"); - /* identified = -ENXIO; */ - } - /* Unknown family ID! */ - } else { - dev_err(&client->dev, - "Warning: maXTouch Family ID [%d] not supported\n", - mxt->device_info.family_id); - strcpy(mxt->device_info.family_name, "UNKNOWN"); - strcpy(mxt->device_info.variant_name, "UNKNOWN"); - /* identified = -ENXIO; */ - } - - dev_info( - &client->dev, - "Atmel maXTouch (Family %s (%X), Variant %s (%X)) Firmware " - "version [%d.%d] Build %d, num_objs = %d\n", - mxt->device_info.family_name, - mxt->device_info.family_id, - mxt->device_info.variant_name, - mxt->device_info.variant_id, - mxt->device_info.major, - mxt->device_info.minor, - mxt->device_info.build, - mxt->device_info.num_objs - ); - dev_info( - &client->dev, - "Atmel maXTouch Configuration " - "[X: %d] x [Y: %d]\n", - mxt->device_info.x_size, - mxt->device_info.y_size - ); - return identified; -} - -/* - * Reads the object table from maXTouch chip to get object data like - * address, size, report id. For Info Block CRC calculation, already read - * id data is passed to this function too (Info Block consists of the ID - * block and object table). - * - */ -static int __devinit mxt_read_object_table(struct i2c_client *client, - struct mxt_data *mxt, - u8 *raw_id_data) -{ - u16 report_id_count; - u8 buf[MXT_OBJECT_TABLE_ELEMENT_SIZE]; - u8 *raw_ib_data; - u8 object_type; - u16 object_address; - u16 object_size; - u8 object_instances; - u8 object_report_ids; - u16 object_info_address; - u32 crc; - u32 calculated_crc; - int i; - int error; - - u8 object_instance; - u8 object_report_id; - u8 report_id; - int first_report_id; - int ib_pointer; - struct mxt_object *object_table; - - MXT1386_LOG(KERN_INFO "maXTouch driver reading configuration\n", __func__); - - object_table = kzalloc(sizeof(struct mxt_object) * - mxt->device_info.num_objs, - GFP_KERNEL); - if (object_table == NULL) { - MXT1386_LOG(KERN_INFO "maXTouch: Memory allocation failed!\n", __func__); - error = -ENOMEM; - goto err_object_table_alloc; - } - - raw_ib_data = kmalloc(MXT_OBJECT_TABLE_ELEMENT_SIZE * - mxt->device_info.num_objs + MXT_ID_BLOCK_SIZE, - GFP_KERNEL); - if (raw_ib_data == NULL) { - MXT1386_LOG(KERN_INFO "maXTouch: Memory allocation failed!\n", __func__); - error = -ENOMEM; - goto err_ib_alloc; - } - - /* Copy the ID data for CRC calculation. */ - memcpy(raw_ib_data, raw_id_data, MXT_ID_BLOCK_SIZE); - ib_pointer = MXT_ID_BLOCK_SIZE; - - mxt->object_table = object_table; - - MXT1386_LOG(KERN_INFO "maXTouch driver Memory allocated\n", __func__); - - object_info_address = MXT_ADDR_OBJECT_TABLE; - - report_id_count = 0; - for (i = 0; i < mxt->device_info.num_objs; i++) { - MXT1386_LOG(KERN_INFO "Reading maXTouch at [0x%04x]: ", __func__, - object_info_address); - - error = mxt_read_block(client, object_info_address, - MXT_OBJECT_TABLE_ELEMENT_SIZE, buf); - - if (error < 0) { - mxt->read_fail_counter++; - dev_err(&client->dev, - "maXTouch Object %d could not be read\n", __func__, i); - error = -EIO; - goto err_object_read; - } - - memcpy(raw_ib_data + ib_pointer, buf, - MXT_OBJECT_TABLE_ELEMENT_SIZE); - ib_pointer += MXT_OBJECT_TABLE_ELEMENT_SIZE; - - object_type = buf[0]; - object_address = (buf[2] << 8) + buf[1]; - object_size = buf[3] + 1; - object_instances = buf[4] + 1; - object_report_ids = buf[5]; - MXT1386_LOG(KERN_INFO "Type=%03d, Address=0x%04x, " - "Size=0x%02x, %d instances, %d report id's\n", __func__, - object_type, - object_address, - object_size, - object_instances, - object_report_ids - ); - - /* TODO: check whether object is known and supported? */ - - /* Save frequently needed info. */ - if (object_type == MXT_GEN_MESSAGEPROCESSOR_T5) { - mxt->msg_proc_addr = object_address; - mxt->message_size = object_size; - } - - object_table[i].type = object_type; - object_table[i].chip_addr = object_address; - object_table[i].size = object_size; - object_table[i].instances = object_instances; - object_table[i].num_report_ids = object_report_ids; - report_id_count += object_instances * object_report_ids; - - object_info_address += MXT_OBJECT_TABLE_ELEMENT_SIZE; - } - - mxt->rid_map = - kzalloc(sizeof(struct report_id_map) * (report_id_count + 1), - /* allocate for report_id 0, even if not used */ - GFP_KERNEL); - if (mxt->rid_map == NULL) { - MXT1386_LOG(KERN_INFO "maXTouch: Can't allocate memory!\n", __func__); - error = -ENOMEM; - goto err_rid_map_alloc; - } - - mxt->messages = kzalloc(mxt->message_size * MXT_MESSAGE_BUFFER_SIZE, - GFP_KERNEL); - if (mxt->messages == NULL) { - MXT1386_LOG(KERN_INFO "maXTouch: Can't allocate memory!\n", __func__); - error = -ENOMEM; - goto err_msg_alloc; - } - - mxt->last_message = kzalloc(mxt->message_size, GFP_KERNEL); - if (mxt->last_message == NULL) { - MXT1386_LOG(KERN_INFO "maXTouch: Can't allocate memory!\n", __func__); - error = -ENOMEM; - goto err_msg_alloc; - } - - mxt->report_id_count = report_id_count; - if (report_id_count > 254) { /* 0 & 255 are reserved */ - dev_err(&client->dev, - "Too many maXTouch report id's [%d]\n", - report_id_count); - error = -ENXIO; - goto err_max_rid; - } - - /* Create a mapping from report id to object type */ - report_id = 1; /* Start from 1, 0 is reserved. */ - - /* Create table associating report id's with objects & instances */ - for (i = 0; i < mxt->device_info.num_objs; i++) { - for (object_instance = 0; - object_instance < object_table[i].instances; - object_instance++){ - first_report_id = report_id; - for (object_report_id = 0; - object_report_id < object_table[i].num_report_ids; - object_report_id++) { - mxt->rid_map[report_id].object = - object_table[i].type; - mxt->rid_map[report_id].instance = - object_instance; - mxt->rid_map[report_id].first_rid = - first_report_id; - report_id++; - } - } - } - - /* Read 3 byte CRC */ - error = mxt_read_block(client, object_info_address, 3, buf); - if (error < 0) { - mxt->read_fail_counter++; - dev_err(&client->dev, "Error reading CRC\n"); - } - - crc = (buf[2] << 16) | (buf[1] << 8) | buf[0]; - - if (calculate_infoblock_crc(&calculated_crc, raw_ib_data, - ib_pointer)) { - MXT1386_LOG(KERN_INFO "Error while calculating CRC!\n"); - calculated_crc = 0; - } - kfree(raw_ib_data); - - MXT1386_LOG(KERN_INFO "Reported info block CRC = 0x%6X\n", __func__, crc); - MXT1386_LOG(KERN_INFO "Calculated info block CRC = 0x%6X\n\n", __func__, calculated_crc); - - if (crc == calculated_crc) { - mxt->info_block_crc = crc; - } else { - mxt->info_block_crc = 0; - MXT1386_LOG(KERN_INFO "maXTouch: Info block CRC invalid!\n"), __func__; - } - - if (debug >= DEBUG_VERBOSE) { - - dev_info(&client->dev, "maXTouch: %d Objects\n", - mxt->device_info.num_objs); - - for (i = 0; i < mxt->device_info.num_objs; i++) { - dev_info(&client->dev, "Type:\t\t\t[%d]: %s\n", - object_table[i].type, - object_type_name[object_table[i].type]); - dev_info(&client->dev, "\tAddress:\t0x%04X\n", - object_table[i].chip_addr); - dev_info(&client->dev, "\tSize:\t\t%d Bytes\n", - object_table[i].size); - dev_info(&client->dev, "\tInstances:\t%d\n", - object_table[i].instances); - dev_info(&client->dev, "\tReport Id's:\t%d\n", - object_table[i].num_report_ids); - } - } - - return 0; - -err_max_rid: - kfree(mxt->last_message); -err_msg_alloc: - kfree(mxt->rid_map); -err_rid_map_alloc: -err_object_read: - kfree(raw_ib_data); -err_ib_alloc: - kfree(object_table); -err_object_table_alloc: - return error; -} - -//#define TS_PEN_IRQ_GPIO RK29_PIN0_PA2//61 - -static int Gpio_TS_request_irq(struct mxt_data *mxt) -{ - int rc; - struct i2c_client *client = mxt->client; - - MXT1386_LOG(KERN_INFO "Gpio_TS_request_irq enter!\n", __func__); - MXT1386_LOG(KERN_INFO "%s: times 1 ts_irq value is %d\n", __func__, ts_irq); - - if (gpio_get_value(client->irq)) { - MXT1386_LOG(KERN_INFO "%s: mxt1386 GPIO value is high\n", __func__); - } - else { - MXT1386_LOG(KERN_INFO "%s: mxt1386 GPIO value is low\n", __func__); - } - - MXT1386_LOG(KERN_INFO "%s: times 2 ts_irq value is %d\n", __func__, ts_irq); - rc = request_irq(mxt->irq, mxt_irq_handler, - IRQF_TRIGGER_LOW,//IRQF_TRIGGER_FALLING, // - "mxc_ts_i2c", mxt); - if (rc) { - pr_err("could not request irq\n"); - goto error_req_irq_fail; - } - - MXT1386_LOG(KERN_INFO "Gpio_TS_request_irq ok!\n", __func__); - return 0; - -error_req_irq_fail: -error_irq_gpio_dir: - gpio_free(client->irq); -error_irq_gpio_req: - if (client->irq >= 0) - gpio_free(client->irq); - return rc; -} - -static int mxt1386_platform_data_init(struct atmel_1386_platform_data *pdata) -{ - MXT1386_LOG(KERN_INFO "%s: mxt1386_platform_data_init enter!\n", __func__); - - pdata->max_x = CONFIG_ATMEL_MXT1386_MAX_X; - pdata->max_y = CONFIG_ATMEL_MXT1386_MAX_Y; - - return 0; -} - -static int __devinit mxt_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct atmel_1386_platform_data *pdata = (struct atmel_1386_platform_data *)client->dev.platform_data; - struct mxt_data *mxt; - struct input_dev *input; - u8 *id_data; - int error; - u8 buf[MXT_ACK_BUFFER_SIZE] = {0}; - u8 buf_size = MXT_MAKE_HIGH_CHG_SIZE_MIN; - int index; - - MXT1386_LOG(" ---------------- mxt_probe start ------------ \n"); - MXT1386_LOG(KERN_INFO "%s: mxt_probe enter, debug level is = %d\n", __func__, debug); - - if (client == NULL) { - MXT1386_LOG("maXTouch: client == NULL\n"); - return -EINVAL; - } else if (client->adapter == NULL) { - MXT1386_LOG("maXTouch: client->adapter == NULL\n"); - return -EINVAL; - } else if (&client->dev == NULL) { - MXT1386_LOG("maXTouch: client->dev == NULL\n"); - return -EINVAL; - } else if (&client->adapter->dev == NULL) { - MXT1386_LOG("maXTouch: client->adapter->dev == NULL\n"); - return -EINVAL; - } else if (id == NULL) { - MXT1386_LOG("maXTouch: id == NULL\n"); - return -EINVAL; - } - - mxt1386_platform_data_init(pdata); - - MXT1386_LOG(KERN_INFO "%s: maXTouch driver v. %s\n", __func__, DRIVER_VERSION); - MXT1386_LOG(KERN_INFO "%s: \t \"%s\"\n", __func__, client->name); - MXT1386_LOG(KERN_INFO "%s: \taddr:\t0x%04x\n", __func__, client->addr); - MXT1386_LOG(KERN_INFO "%s: \tirq:\t%d\n", __func__, client->irq); - MXT1386_LOG(KERN_INFO "%s: \tflags:\t0x%04x\n", __func__, client->flags); - MXT1386_LOG(KERN_INFO "%s: \tadapter:\"%s\"\n", __func__, client->adapter->name); - MXT1386_LOG(KERN_INFO "%s: \tdevice:\t\"%s\"\n", __func__, client->dev.init_name); - - if (!pdata) { - MXT1386_LOG("TS i2c_probe no platform data\n"); - } - else { - MXT1386_LOG("TS i2c_probe platform data OK\n"); - } - - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { - MXT1386_LOG("TS i2c_probe I2C_FUNC_I2C Failed\n"); - } - else { - MXT1386_LOG("TS i2c_probe I2C_FUNC_I2C OK\n"); - } - - if (pdata->init_platform_hw != NULL) { - error = pdata->init_platform_hw(&(client->dev)); - if (error < 0) { - MXT1386_LOG("TS i2c_probe power on Failed\n"); - return error; - } - else { - MXT1386_LOG("TS i2c_probe power on OK\n"); - } - } - else { /* ---------------- add by acgzx test ---------------- */ - MXT1386_LOG("TS init_platform_hw is NULL\n"); - } - - /* Allocate structure - we need it to identify device */ - mxt = kzalloc(sizeof(struct mxt_data), GFP_KERNEL); - if (mxt == NULL) { - dev_err(&client->dev, "insufficient memory\n"); - error = -ENOMEM; - goto err_mxt_alloc; - } - - id_data = kmalloc(MXT_ID_BLOCK_SIZE, GFP_KERNEL); - if (id_data == NULL) { - dev_err(&client->dev, "insufficient memory\n"); - error = -ENOMEM; - goto err_id_alloc; - } - - input = input_allocate_device(); - if (!input) { - dev_err(&client->dev, "error allocating input device\n"); - error = -ENOMEM; - goto err_input_dev_alloc; - } - - atmel_mxt = mxt; - - mxt->read_fail_counter = 0; - mxt->message_counter = 0; - mxt->max_x_val = pdata->max_x; - mxt->max_y_val = pdata->max_y; - - /* Get data that is defined in board specific code. */ - mxt->init_hw = pdata->init_platform_hw; - mxt->exit_hw = pdata->exit_platform_hw; - mxt->read_chg = pdata->read_chg; - - if (pdata->valid_interrupt != NULL) - mxt->valid_interrupt = pdata->valid_interrupt; - else - { - mxt->valid_interrupt = mxt_valid_interrupt_dummy; - MXT1386_LOG("TS valid_interrupt is dummy\n"); /* ---------------- add by acgzx test ---------------- */ - } - - if (debug >= DEBUG_TRACE) - MXT1386_LOG("maXTouch driver identifying chip\n"); - - if (mxt_identify(client, mxt, id_data) < 0) { - dev_err(&client->dev, "Chip could not be identified\n"); - error = -ENODEV; - goto err_identify; - } - /* Chip is valid and active. */ - if (debug >= DEBUG_TRACE) - MXT1386_LOG("maXTouch driver allocating input device\n"); - - mxt->client = client; - mxt->input = input; - - mutex_init(&mxt->debug_mutex); - mutex_init(&mxt->msg_mutex); - MXT1386_LOG("maXTouch driver creating device name\n"); - - snprintf( - mxt->phys_name, - sizeof(mxt->phys_name), - "%s/input0", - dev_name(&client->dev) - ); - input->name = "mxc_ts_i2c"; // "Atmel maXTouch Touchscreen controller"; - input->phys = mxt->phys_name; - input->id.bustype = BUS_I2C; - input->dev.parent = &client->dev; - - MXT1386_LOG("maXTouch name: \"%s\"\n", input->name); - MXT1386_LOG("maXTouch phys: \"%s\"\n", input->phys); - MXT1386_LOG("maXTouch driver setting abs parameters\n"); - - MXT1386_LOG(KERN_INFO "%s: mxt->max_x_val = %d\n", __func__, mxt->max_x_val); - MXT1386_LOG(KERN_INFO "%s: mxt->max_y_val = %d\n", __func__, mxt->max_y_val); - - /* Single touch */ - input_set_abs_params(input, ABS_X, 0, mxt->max_x_val, 0, 0); - input_set_abs_params(input, ABS_Y, 0, mxt->max_y_val, 0, 0); - input_set_abs_params(input, ABS_PRESSURE, 0, MXT_MAX_REPORTED_PRESSURE, - 0, 0); - input_set_abs_params(input, ABS_TOOL_WIDTH, 0, MXT_MAX_REPORTED_WIDTH, - 0, 0); - - /* Multitouch */ - input_set_abs_params(input, ABS_MT_POSITION_X, 0, mxt->max_x_val, 0, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, 0, mxt->max_y_val, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, MXT_MAX_TOUCH_SIZE, - 0, 0); - input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, MXT_MAX_NUM_TOUCHES, - 0, 0); - - __set_bit(EV_ABS, input->evbit); - __set_bit(EV_SYN, input->evbit); - __set_bit(EV_KEY, input->evbit); - __set_bit(EV_MSC, input->evbit); - -#if TOUCH_KEY_EN - __set_bit(KEY_SEARCH, input->keybit); - __set_bit(KEY_HOME, input->keybit); - __set_bit(KEY_MENU, input->keybit); - __set_bit(KEY_BACK, input->keybit); -#endif - - input->mscbit[0] = BIT_MASK(MSC_GESTURE); - - MXT1386_LOG("maXTouch driver setting client data\n"); - i2c_set_clientdata(client, mxt); - MXT1386_LOG("maXTouch driver setting drv data\n"); - input_set_drvdata(input, mxt); - MXT1386_LOG("maXTouch driver input register device\n"); - error = input_register_device(mxt->input); - if (error < 0) { - dev_err(&client->dev, - "Failed to register input device\n"); - goto err_register_device; - } - - error = mxt_read_object_table(client, mxt, id_data); - if (error < 0) - goto err_read_ot; - - /* Create debugfs entries. */ - mxt->debug_dir = debugfs_create_dir("maXTouch", NULL); - if (mxt->debug_dir == ERR_PTR(-ENODEV)){ - /* debugfs is not enabled. */ - MXT1386_LOG("debugfs not enabled in kernel\n"); - } else if (mxt->debug_dir == NULL) { - MXT1386_LOG("error creating debugfs dir\n"); - } else { - MXT1386_LOG("created \"maXTouch\" debugfs dir\n"); - - debugfs_create_file("deltas", S_IRUSR, mxt->debug_dir, mxt, - &delta_fops); - debugfs_create_file("refs", S_IRUSR, mxt->debug_dir, mxt, - &refs_fops); - } - - /* Create character device nodes for reading & writing registers */ - mxt->mxt_class = class_create(THIS_MODULE, "maXTouch_memory"); - /* 2 numbers; one for memory and one for messages */ - error = alloc_chrdev_region(&mxt->dev_num, 0, 2, - "maXTouch_memory"); - MXT1386_LOG("device number %d allocated!\n", MAJOR(mxt->dev_num)); - if (error){ - MXT1386_LOG("Error registering device\n"); - } - cdev_init(&mxt->cdev, &mxt_memory_fops); - cdev_init(&mxt->cdev_messages, &mxt_message_fops); - - MXT1386_LOG("cdev initialized\n"); - mxt->cdev.owner = THIS_MODULE; - mxt->cdev_messages.owner = THIS_MODULE; - - error = cdev_add(&mxt->cdev, mxt->dev_num, 1); - if (error){ - MXT1386_LOG("Bad cdev\n"); - } - - error = cdev_add(&mxt->cdev_messages, mxt->dev_num + 1, 1); - if (error){ - MXT1386_LOG("Bad cdev\n"); - } - - MXT1386_LOG("cdev added\n"); - - device_create(mxt->mxt_class, NULL, MKDEV(MAJOR(mxt->dev_num), 0), NULL, - "maXTouch"); - - device_create(mxt->mxt_class, NULL, MKDEV(MAJOR(mxt->dev_num), 1), NULL, - "maXTouch_messages"); - - mxt->msg_buffer_startp = 0; - mxt->msg_buffer_endp = 0; - - /* Allocate the interrupt */ - MXT1386_LOG("maXTouch driver allocating interrupt...\n"); - mxt->irq = gpio_to_irq(client->irq); - ts_irq = mxt->irq; - mxt->valid_irq_counter = 0; - mxt->invalid_irq_counter = 0; - mxt->irq_counter = 0; - -//WRITE_MT_CONFIG - -#if WORKQ_RIGHTNOW - MXT1386_LOG(KERN_INFO "%s: INIT_WORK set\n", __func__); - mxt->queue = create_singlethread_workqueue("mxc_ts_handler"); /*创建一个单线程的工作队列*/ - INIT_WORK(&mxt->work, ts_thread_1386); -#else - MXT1386_LOG(KERN_INFO "%s: INIT_DELAYED_WORK set\n", __func__); - mxt->queue = create_rt_workqueue("mxc_ts_handler"); /*创建一个实时的工作队列*/ - INIT_DELAYED_WORK(&mxt->dwork, ts_thread_1386); -#endif - -/*--------------------------------------------------------------------------------*/ - /* Now the chip pull the irq pin to down waiting the host ack */ - if(gpio_get_value(client->irq)) { - MXT1386_LOG(KERN_INFO "%s: TOUCH_INT_PIN test, value is high, error\n", __func__); - goto err_irq; - } - else { - MXT1386_LOG(KERN_INFO "%s: TOUCH_INT_PIN test, value is low, need host ack\n", __func__); - } - - /* TP MCU 硬件复位后,此时INT引脚为低电平,主控需从T5寄存器读一段至少10bytes大小(不能小于此值)的数据反馈给MCU,此时INT引脚才拉高 acgzx 2011.03.30 */ - /* Read dummy message to make high CHG pin (Make CHG line high after the interrupts are enabled) */ - error = mxt_read_block(client, mxt->msg_proc_addr, buf_size, (u8 *)buf); /* ---!!!!!!!!!!!!!!!!!!!!!!!!!!!!!--- */ - if (error < 0) { - MXT1386_LOG(KERN_INFO "%s: host first ack msg err!\n", __func__); - } - else { - MXT1386_LOG(KERN_INFO "%s: host first ack msg ok!\n", __func__); - } - mxt_buf_test(buf, buf_size); - msleep(20); - - if(gpio_get_value(client->irq)) { - MXT1386_LOG(KERN_INFO "%s: TOUCH_INT_PIN test, value is high, host acked chip successively\n", __func__); - } - else { - MXT1386_LOG(KERN_INFO "%s: TOUCH_INT_PIN test, value is low, host acked chip fail\n", __func__); - goto err_irq; - } -/*--------------------------------------------------------------------------------*/ - atmel_1386_write_config(mxt); - - error = Gpio_TS_request_irq(mxt); - if (error != 0) { - MXT1386_LOG("TS i2c_probe request irq failed\n"); - goto err_irq; - } - else { - MXT1386_LOG("TS i2c_probe request irq ok\n"); - } - -#ifdef CONFIG_PM - device_init_wakeup(&client->dev, 0); -#endif - - if (debug > DEBUG_INFO) - dev_info(&client->dev, "touchscreen, irq %d\n", mxt->irq); - - kfree(id_data); - - MXT1386_LOG(KERN_INFO "%s: mxt_probe init ok\n", __func__); - MXT1386_LOG(" ---------------- mxt_probe end ------------ \n"); - return 0; - -err_irq: - kfree(mxt->rid_map); - kfree(mxt->object_table); - kfree(mxt->last_message); -err_read_ot: -err_register_device: -err_identify: -err_input_dev_alloc: - kfree(id_data); -err_id_alloc: - if (mxt->exit_hw != NULL) - mxt->exit_hw(&(client->dev)); - kfree(mxt); -err_mxt_alloc: - return error; -} - -static int __devexit mxt_remove(struct i2c_client *client) -{ - struct mxt_data *mxt; - - MXT1386_LOG(KERN_INFO "%s: ----------- mxt_remove enter now -----------\n", __func__); - - mxt = i2c_get_clientdata(client); - - /* Remove debug dir entries */ - debugfs_remove_recursive(mxt->debug_dir); - - if (mxt != NULL) { - - if (mxt->exit_hw != NULL) - mxt->exit_hw(&(client->dev)); - - if (mxt->irq) { - free_irq(mxt->irq, mxt); - } - -#if (!WORKQ_RIGHTNOW) - if (cancel_delayed_work_sync(&mxt->dwork)) { - /* - * Work was pending, therefore we need to enable - * IRQ here to balance the disable_irq() done in the - * interrupt handler. - */ - MXT1386_LOG(KERN_INFO "%s: cancel_delayed_work_sync set\n", __func__); - enable_irq(mxt->irq); - } -#endif - - unregister_chrdev_region(mxt->dev_num, 2); - device_destroy(mxt->mxt_class, MKDEV(MAJOR(mxt->dev_num), 0)); - device_destroy(mxt->mxt_class, MKDEV(MAJOR(mxt->dev_num), 1)); - cdev_del(&mxt->cdev); - cdev_del(&mxt->cdev_messages); - cancel_delayed_work_sync(&mxt->dwork); - input_unregister_device(mxt->input); - class_destroy(mxt->mxt_class); - debugfs_remove(mxt->debug_dir); - - kfree(mxt->rid_map); - kfree(mxt->object_table); - kfree(mxt->last_message); - } - kfree(mxt); - - i2c_set_clientdata(client, NULL); - if (debug >= DEBUG_TRACE) - dev_info(&client->dev, "Touchscreen unregistered\n"); - - return 0; -} - -#if defined(CONFIG_PM) -static int mxt_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct mxt_data *mxt = i2c_get_clientdata(client); - - MXT1386_LOG(KERN_INFO "%s: ----------- mxt_suspend enter now -----------\n", __func__); - -#if 1 - if (device_may_wakeup(&client->dev)) { - MXT1386_LOG(KERN_INFO "%s: mxt_suspend ok\n", __func__); - enable_irq_wake(mxt->irq); - } else { - MXT1386_LOG(KERN_INFO "%s: mxt_suspend failed\n", __func__); - } -#else - disable_irq(mxt->irq); - cancel_work_sync(&mxt->work); - - if (device_may_wakeup(&client->dev)) { - printk(KERN_INFO "%s: mxt_suspend ok\n", __func__); - enable_irq_wake(mxt->irq); - } else { - printk(KERN_INFO "%s: mxt_suspend failed\n", __func__); - } -#endif - - return 0; -} - -static int mxt_wakeup_controller(int gpio) -{ - int ret=0, i; - - gpio_free(gpio); - - if((ret = gpio_request(gpio, "mxc_irq_gpio"))!=0) { - MXT1386_LOG(KERN_INFO "Failed to request GPIO for mxc_irq_gpio. Err:%d\n", ret); - ret = -EFAULT; - } else { - gpio_direction_output(gpio, 0); - - for(i=0; i<100; i++); - gpio_direction_input(gpio); - MXT1386_LOG(KERN_INFO "INT wakeup touch controller done\n"); - } - - return ret; -} - - -static int mxt_resume(struct i2c_client *client) -{ - struct mxt_data *mxt = i2c_get_clientdata(client); - - MXT1386_LOG(KERN_INFO "%s: ----------- mxt_resume enter now ----------- \n", __func__); - -#if 1 - if (device_may_wakeup(&client->dev)) { - MXT1386_LOG(KERN_INFO "%s: mxt_resume ok\n", __func__); - disable_irq_wake(mxt->irq); - } else { - MXT1386_LOG(KERN_INFO "%s: mxt_resume failed\n", __func__); - } -#else - if (device_may_wakeup(&client->dev)) { - printk(KERN_INFO "%s: mxt_resume ok\n", __func__); - disable_irq_wake(mxt->irq); - } else { - printk(KERN_INFO "%s: mxt_resume failed\n", __func__); - } - mxt_wakeup_controller(irq_to_gpio(mxt->irq)); - enable_irq(mxt->irq); -#endif - - return 0; -} -#else -#define mxt_suspend NULL -#define mxt_resume NULL -#endif - -static const struct i2c_device_id mxt_idtable[] = { - {"mxc_ts_i2c", 0,}, - { } -}; - -MODULE_DEVICE_TABLE(i2c, mxt_idtable); - -static struct i2c_driver mxt_driver = { - .driver = { - .name = "mxc_ts_i2c", - .owner = THIS_MODULE, - }, - - .id_table = mxt_idtable, - .probe = mxt_probe, - .remove = __devexit_p(mxt_remove), - .suspend = mxt_suspend, - .resume = mxt_resume, - -}; - -#if 0 -static void __init mxt_init_async(void *unused, async_cookie_t cookie) -{ - int err; - - MXT1386_LOG(KERN_INFO "%s: ----------- mxt_init_async enter now ----------- \n", __func__); - - err = i2c_add_driver(&mxt_driver); - if (err) { - MXT1386_LOG("Adding maXTouch driver failed " - "(errno = %d)\n", err); - } else { - MXT1386_LOG(KERN_INFO "Successfully added driver %s\n", __func__, - mxt_driver.driver.name); - } -} -static int __init mxt_init(void) -{ - MXT1386_LOG(KERN_INFO "%s: ----------- mxt_init enter now ----------- \n", __func__); - - async_schedule(mxt_init_async, NULL); - return 0; -} -#else -static int __init mxt_init(void) -{ - int err; - - MXT1386_LOG(KERN_INFO "%s: ----------- mxt_init enter now ----------- \n", __func__); - - err = i2c_add_driver(&mxt_driver); - if (err) { - MXT1386_LOG("Adding maXTouch driver failed " - "(errno = %d)\n", err); - } else { - MXT1386_LOG(KERN_INFO "Successfully added driver %s\n", __func__, - mxt_driver.driver.name); - } - - MXT1386_LOG(KERN_INFO "Adding maXTouch driver \n"); - - return err; -} -#endif - -static void __exit mxt_cleanup(void) -{ - MXT1386_LOG(KERN_INFO "%s: ----------- mxt_cleanup enter now ----------- \n", __func__); - i2c_del_driver(&mxt_driver); -} - -module_init(mxt_init); -module_exit(mxt_cleanup); - -MODULE_AUTHOR("Iiro Valkonen"); -MODULE_DESCRIPTION("Driver for Atmel maXTouch Touchscreen Controller"); -MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/atmel_mxt1386.h b/drivers/input/touchscreen/atmel_mxt1386.h deleted file mode 100644 index 251fb9ebdea2..000000000000 --- a/drivers/input/touchscreen/atmel_mxt1386.h +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Atmel maXTouch header file - * - * Copyright (c) 2010 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 or 3 as - * published by the Free Software Foundation. - * See the file "COPYING" in the main directory of this archive - * for more details. - * - */ - #include - - -#define MXT224_I2C_ADDR1 0x4A -#define MXT224_I2C_ADDR2 0x4B -#define MXT1386_I2C_ADDR1 0x4C -#define MXT1386_I2C_ADDR2 0x4D -#define MXT1386_I2C_ADDR3 0x5A -#define MXT1386_I2C_ADDR4 0x5B - -/* - * Select this address from above depending on what maXTouch - * chip you have and how it's address pins are configured; - * see datasheet. - */ - -#define MXT_I2C_ADDRESS MXT1386_I2C_ADDR1 - -#define MXT_BL_ADDRESS 0x25 - -#define MXT224_FAMILYID 0x80 -#define MXT1386_FAMILYID 0xA0 - -#define MXT224_CAL_VARIANTID 0x01 -#define MXT224_UNCAL_VARIANTID 0x00 -#define MXT1386_CAL_VARIANTID 0x00 - -#define MXT_MAX_REPORTED_WIDTH 255 -#define MXT_MAX_REPORTED_PRESSURE 255 -#define MXT_MAX_TOUCH_SIZE 255 -#define MXT_MAX_NUM_TOUCHES 10 - -/* Fixed addresses inside maXTouch device */ -#define MXT_ADDR_INFO_BLOCK 0 -#define MXT_ADDR_OBJECT_TABLE 7 -#define MXT_ID_BLOCK_SIZE 7 -#define MXT_OBJECT_TABLE_ELEMENT_SIZE 6 - -/* Object types */ -#define MXT_DEBUG_DELTAS_T2 2 -#define MXT_DEBUG_REFERENCES_T3 3 -#define MXT_GEN_MESSAGEPROCESSOR_T5 5 -#define MXT_GEN_COMMANDPROCESSOR_T6 6 -#define MXT_GEN_POWERCONFIG_T7 7 -#define MXT_GEN_ACQUIRECONFIG_T8 8 -#define MXT_TOUCH_MULTITOUCHSCREEN_T9 9 -#define MXT_TOUCH_SINGLETOUCHSCREEN_T10 10 -#define MXT_TOUCH_XSLIDER_T11 11 -#define MXT_TOUCH_YSLIDER_T12 12 -#define MXT_TOUCH_XWHEEL_T13 13 -#define MXT_TOUCH_YWHEEL_T14 14 -#define MXT_TOUCH_KEYARRAY_T15 15 -#define MXT_SPT_COMMSCONFIG_T18 18 -#define MXT_SPT_GPIOPWM_T19 19 -#define MXT_PROCI_GRIPFACESUPPRESSION_T20 20 -#define MXT_PROCG_NOISESUPPRESSION_T22 22 -#define MXT_TOUCH_PROXIMITY_T23 23 -#define MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24 24 -#define MXT_SPT_SELFTEST_T25 25 -#define MXT_DEBUG_CTERANGE_T26 26 -#define MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27 27 -#define MXT_SPT_CTECONFIG_T28 28 -#define MXT_TOUCH_KEYSET_T31 31 -#define MXT_TOUCH_XSLIDERSET_T32 32 -#define MXT_DEBUG_DIAGNOSTIC_T37 37 -#define MXT_USER_INFO_T38 38 -#define MXT_PROCI_GRIPSUPPRESSION_T40 40 -#define MXT_PROCI_PALMSUPPRESSION_T41 41 -#define MXT_SPT_DIGITIZER_T43 43 - - - -/* - * If a message is read from mXT when there's no new messages available, - * the report ID of the message will be 0xFF. - */ -#define MXT_END_OF_MESSAGES 0xFF - - -/* GEN_COMMANDPROCESSOR_T6 Register offsets from T6 base address */ -#define MXT_ADR_T6_RESET 0x00 -#define MXT_ADR_T6_BACKUPNV 0x01 -#define MXT_ADR_T6_CALIBRATE 0x02 -#define MXT_ADR_T6_REPORTALL 0x03 -#define MXT_ADR_T6_RESERVED 0x04 -#define MXT_ADR_T6_DIAGNOSTIC 0x05 - -/* T6 Debug Diagnostics Commands */ -#define MXT_CMD_T6_PAGE_UP 0x01 -#define MXT_CMD_T6_PAGE_DOWN 0x02 -#define MXT_CMD_T6_DELTAS_MODE 0x10 -#define MXT_CMD_T6_REFERENCES_MODE 0x11 -#define MXT_CMD_T6_CTE_MODE 0x31 - -/* T6 Backup Command */ -#define MXT_CMD_T6_BACKUP 0x55 - -/* SPT_DEBUG_DIAGNOSTIC_T37 Register offsets from T37 base address */ -#define MXT_ADR_T37_PAGE 0x01 -#define MXT_ADR_T37_DATA 0x02 - - - -/************************************************************************ - * MESSAGE OBJECTS ADDRESS FIELDS - * - ************************************************************************/ -#define MXT_MSG_REPORTID 0x00 - - -/* MXT_GEN_MESSAGEPROCESSOR_T5 Message address definitions */ -#define MXT_MSG_T5_REPORTID 0x00 -#define MXT_MSG_T5_MESSAGE 0x01 -#define MXT_MSG_T5_CHECKSUM 0x08 - -/* MXT_GEN_COMMANDPROCESSOR_T6 Message address definitions */ -#define MXT_MSG_T6_STATUS 0x01 -#define MXT_MSGB_T6_COMSERR 0x04 -#define MXT_MSGB_T6_CFGERR 0x08 -#define MXT_MSGB_T6_CAL 0x10 -#define MXT_MSGB_T6_SIGERR 0x20 -#define MXT_MSGB_T6_OFL 0x40 -#define MXT_MSGB_T6_RESET 0x80 -/* Three bytes */ -#define MXT_MSG_T6_CHECKSUM 0x02 - -/* MXT_GEN_POWERCONFIG_T7 NO Message address definitions */ -/* MXT_GEN_ACQUIRECONFIG_T8 Message address definitions */ -/* MXT_TOUCH_MULTITOUCHSCREEN_T9 Message address definitions */ - -#define MXT_MSG_T9_STATUS 0x01 -/* Status bit field */ -#define MXT_MSGB_T9_SUPPRESS 0x02 -#define MXT_MSGB_T9_AMP 0x04 -#define MXT_MSGB_T9_VECTOR 0x08 -#define MXT_MSGB_T9_MOVE 0x10 -#define MXT_MSGB_T9_RELEASE 0x20 -#define MXT_MSGB_T9_PRESS 0x40 -#define MXT_MSGB_T9_DETECT 0x80 - -#define MXT_MSG_T9_XPOSMSB 0x02 -#define MXT_MSG_T9_YPOSMSB 0x03 -#define MXT_MSG_T9_XYPOSLSB 0x04 -#define MXT_MSG_T9_TCHAREA 0x05 -#define MXT_MSG_T9_TCHAMPLITUDE 0x06 -#define MXT_MSG_T9_TCHVECTOR 0x07 - - -/* MXT_SPT_GPIOPWM_T19 Message address definitions */ -#define MXT_MSG_T19_STATUS 0x01 - -/* MXT_PROCI_GRIPFACESUPPRESSION_T20 Message address definitions */ -#define MXT_MSG_T20_STATUS 0x01 -#define MXT_MSGB_T20_FACE_SUPPRESS 0x01 -/* MXT_PROCG_NOISESUPPRESSION_T22 Message address definitions */ -#define MXT_MSG_T22_STATUS 0x01 -#define MXT_MSGB_T22_FHCHG 0x01 -#define MXT_MSGB_T22_GCAFERR 0x04 -#define MXT_MSGB_T22_FHERR 0x08 -#define MXT_MSG_T22_GCAFDEPTH 0x02 - -/* MXT_TOUCH_PROXIMITY_T23 Message address definitions */ -#define MXT_MSG_T23_STATUS 0x01 -#define MXT_MSGB_T23_FALL 0x20 -#define MXT_MSGB_T23_RISE 0x40 -#define MXT_MSGB_T23_DETECT 0x80 -/* 16 bit */ -#define MXT_MSG_T23_PROXDELTA 0x02 - -/* MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24 Message address definitions */ -#define MXT_MSG_T24_STATUS 0x01 -#define MXT_MSG_T24_XPOSMSB 0x02 -#define MXT_MSG_T24_YPOSMSB 0x03 -#define MXT_MSG_T24_XYPOSLSB 0x04 -#define MXT_MSG_T24_DIR 0x05 -/* 16 bit */ -#define MXT_MSG_T24_DIST 0x06 - -/* MXT_SPT_SELFTEST_T25 Message address definitions */ -#define MXT_MSG_T25_STATUS 0x01 -/* 5 Bytes */ -#define MXT_MSGR_T25_OK 0xFE -#define MXT_MSGR_T25_INVALID_TEST 0xFD -#define MXT_MSGR_T25_PIN_FAULT 0x11 -#define MXT_MSGR_T25_SIGNAL_LIMIT_FAULT 0x17 -#define MXT_MSGR_T25_GAIN_ERROR 0x20 -#define MXT_MSG_T25_INFO 0x02 - -/* MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27 Message address definitions */ -#define MXT_MSG_T27_STATUS 0x01 -#define MXT_MSGB_T27_ROTATEDIR 0x10 -#define MXT_MSGB_T27_PINCH 0x20 -#define MXT_MSGB_T27_ROTATE 0x40 -#define MXT_MSGB_T27_STRETCH 0x80 -#define MXT_MSG_T27_XPOSMSB 0x02 -#define MXT_MSG_T27_YPOSMSB 0x03 -#define MXT_MSG_T27_XYPOSLSB 0x04 -#define MXT_MSG_T27_ANGLE 0x05 - -/* 16 bit */ -#define MXT_MSG_T27_SEPARATION 0x06 - -/* MXT_SPT_CTECONFIG_T28 Message address definitions */ -#define MXT_MSG_T28_STATUS 0x01 -#define MXT_MSGB_T28_CHKERR 0x01 - -/* One Touch Events */ -#define MXT_GESTURE_RESERVED 0x00 -#define MXT_GESTURE_PRESS 0x01 -#define MXT_GESTURE_RELEASE 0x02 -#define MXT_GESTURE_TAP 0x03 -#define MXT_GESTURE_DOUBLE_TAP 0x04 -#define MXT_GESTURE_FLICK 0x05 -#define MXT_GESTURE_DRAG 0x06 -#define MXT_GESTURE_SHORT_PRESS 0x07 -#define MXT_GESTURE_LONG_PRESS 0x08 -#define MXT_GESTURE_REPEAT_PRESS 0x09 -#define MXT_GESTURE_TAP_AND_PRESS 0x0a -#define MXT_GESTURE_THROW 0x0b - -/* Two-touch events */ -#define MXT_GESTURE_STRETCH (1 << 7) -#define MXT_GESTURE_ROTATE (1 << 6) -#define MXT_GESTURE_PINCH (1 << 5) -#define MXT_GESTURE_ROTATEDIR (1 << 4) - -/* Bootloader states */ -#define WAITING_BOOTLOAD_COMMAND 0xC0 -#define WAITING_FRAME_DATA 0x80 -#define APP_CRC_FAIL 0x40 -#define FRAME_CRC_CHECK 0x02 -#define FRAME_CRC_PASS 0x04 -#define FRAME_CRC_FAIL 0x03 - -#define MXT_MAX_FRAME_SIZE 276 - -/* Debug levels */ -#define DEBUG_INFO 1 -#define DEBUG_VERBOSE 2 -#define DEBUG_MESSAGES 5 -#define DEBUG_RAW 8 -#define DEBUG_TRACE 10 - -/* IOCTL commands */ -/* TODO: get correct numbers! */ -#define MXT_SET_ADDRESS_IOCTL ('x' + 1) /* Sets the internal address pointer */ -#define MXT_RESET_IOCTL ('x' + 2) /* Resets the device */ -#define MXT_CALIBRATE_IOCTL ('x' + 3) /* Calibrates the device */ -#define MXT_BACKUP_IOCTL ('x' + 4) /* Backups the current state of registers to - NVM */ -#define MXT_NONTOUCH_MSG_IOCTL ('x' + 5) /* Only non-touch messages can be read from - the message buffer (/dev/maXTouch_messages)*/ -#define MXT_ALL_MSG_IOCTL ('x' + 6) /* All messages can be read from the message - buffer */ - -/* Message buffer size. This is a ring buffer, and when full, the oldest entry - will be overwritten. */ -#define MXT_MESSAGE_BUFFER_SIZE 128 - -/*-------------- following added by acgzx 2011.03.30 --------------*/ - -/* Read dummy message to make high CHG pin of minimumvalue */ -#define MXT_MAKE_HIGH_CHG_SIZE_MIN 10 -#define MXT_ACK_BUFFER_SIZE 16 - - -/** - * struct mxt_platform_data - includes platform specific informatio - * related to Atmel maXTouch touchscreen controller. - * - * @numtouch: Number of simultaneous touches supported - * @init_platform_hw(): Initialization function, which can for example - * trigger a hardware reset by toggling a GPIO pin - * @exit_platform_hw(): Function to run when the driver is unloaded. - * @valid_interrupt(): Function that checks the validity of the interrupt - - * function that check the validity of a interrupt (by - * reading the changeline interrupt pin and checking that - * it really is low for example). - * @max_x: Reported X range - * @max_y: Reported Y range - */ - - diff --git a/drivers/input/touchscreen/atmel_mxt224.c b/drivers/input/touchscreen/atmel_mxt224.c deleted file mode 100644 index a52e419e072e..000000000000 --- a/drivers/input/touchscreen/atmel_mxt224.c +++ /dev/null @@ -1,1053 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/**************************************************************************************** - * driver/input/touchscreen/atmel_mxt224.c - *Copyright :ROCKCHIP Inc - *Author : dqz - *Date : 2011.2.28 - * - *description: - ********************************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define FEATURE_CFG_DUMP - -static int mxt224_i2c_write(struct i2c_client *client, u16 offset,void *buf,int size); -static int mxt224_i2c_read(struct i2c_client *client, u16 offset,void *buf,int size); -static int mXT224_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int mXT224_remove(struct i2c_client *client); - -#ifdef FEATURE_CFG_DUMP -static int total_size = 0; -static u8 *cfg_dmup; -#endif -#define VERSION_20 - -#define local_debug //printk - -#define ID_INFORMATION_SIZE 0x7 -#define OBJECT_TABLE_ELEMENT_SIZE 0x6 -#define CRC_SIZE 0x3 -#define TABLE_SIZE_ADDR ID_INFORMATION_SIZE-1 -#define MESSAGE_T5 0x5 - -#define MXT224_REPORTID_T9_OFFSET 9 -#define MXT224_MT_SCAN_POINTS 2 - -struct mxt224_id_info{ - u8 family_id; - u8 variant_id; - u8 version; - u8 build; - u8 matrix_x_size; - u8 matrix_y_size; - u8 object_num; -}__packed; - -struct mxt224_table_info{ - u8 obj_type; - u8 start_addr_lsb; - u8 start_addr_msb; - u8 size; - u8 instance; - u8 report_id; -}__packed; - -#define CFGERR_MASK (0x01<<3) - -union msg_body{ - u8 msg[7]; - struct{ - u8 status; - u32 checksum:24; - }t6; - struct{ - u8 status; - u8 x_msb; - u8 y_msb; - u8 xy_poslisb; - u8 area; - u8 tchamplitude; - u8 tchvector; - }t9; -}__packed; - - -struct message_t5{ - u8 report_id; - union msg_body body; -#ifndef VERSION_20 - u8 checksum; -#endif -}__packed; - -struct mxt224_obj{ - struct mxt224_id_info id_info; - u8 *table_info_byte; - struct mxt224_table_info *table_info; - u8 table_size; - u16 msg_t5_addr; - u32 info_crc; -}; - -struct mXT224_info { - int int_gpio; - int reset_gpio; - int cfg_delay; - int last_key_index; - u16 last_read_addr; - - char phys[32]; - //struct hrtimer timer; - struct i2c_client *client; - struct input_dev *input_dev; - struct delayed_work work; - struct workqueue_struct *mxt224_wq; - - int (*power)(int on); - /* Object table relation */ - struct mxt224_obj obj; -}; - -static struct mXT224_info ts_data = { - .int_gpio = RK29_PIN0_PA2, - .reset_gpio = RK29_PIN6_PC3, - .cfg_delay = 0, - .last_key_index = 0, - .last_read_addr = 0, -}; - -struct report_id_table{ - u8 report_start; - u8 report_end; - u8 obj_type; -}; - -static struct report_id_table* id_table = NULL; -static u8 T9_cfg[31] = {0}; -struct mxt224_cfg{ - u8 type; - const u8* data; - int size; -}; - - -struct mxt224_key_info{ - u32 start; - u32 end; - u32 code; -}; -const struct mxt224_key_info key_info[] = { - {0, 0, KEY_BACK}, - {0, 0, KEY_MENU}, - {0, 0, KEY_HOME}, - {0, 0, KEY_SEARCH}, -}; - -#if 1 -const u8 T7[] = {0xff, 0xff, 0x32}; -const u8 T8[] = {0x08, 0x05, 0x14, 0x14, 0x00, 0x00, 0x0a, 0x0f}; -const u8 T9[] = {0x83, 0x00, 0x00, 0x0D, 0x0A, 0x00, 0x11, 0x28, - 0x02, 0x01, 0x00, 0x01, 0x01, 0x00, 0x0A, 0x0A, - 0x0A, 0x0A, 0x01, 0x5A, 0x00, 0xEF, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /////////////////////////////////////// - //0x83, 0x0D, 0x0A, 0x03, 0x03, 0x00, 0x11, 0x28, - //0x02, 0x03, 0x00, 0x01, 0x01, 0x00, 0x0A, 0x0A, - //0x0A, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - //0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; -const u8 T15[] = {0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x41, 0x1E, - 0x02, 0x00, 0x00 }; -const u8 T18[] = {0x00, 0x00 }; -const u8 T19[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -const u8 T20[] = {0x00, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; -const u8 T22[] = {0x15, 0x00, 0x00, 0x00, 0x19, 0xFF, 0xE7, 0x04, - 0x32, 0x00, 0x01, 0x0A, 0x0F, 0x14, 0x19, 0x1E, - 0x04, - ///////////////////////////////////// - //0x15, 0x00, 0x00, 0x00, 0x19, 0xff, 0xe7, 0x04, - //0x32, 0x00, 0x01, 0x0a, 0x0f, 0x14, 0x19, 0x1e, - //0x04, - }; -const u8 T23[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 }; -const u8 T24[] = {0x03, 0x04, 0x03, 0xFF, 0x00, 0x64, 0x64, 0x01, - 0x0A, 0x14, 0x28, 0x00, 0x4B, 0x00, 0x02, 0x00, - 0x64, 0x00, 0x19 }; -const u8 T25[] = {0x00, 0x00, 0x2E, 0xE0, 0x1B, 0x58, 0x36, 0xB0, - 0x01, 0xF4, 0x00, 0x00, 0x00, 0x00 }; -const u8 T27[] = {0x03, 0x02, 0x00, 0xE0, 0x03, 0x00, 0x23}; -const u8 T28[] = {0x00, 0x00, 0x00, 0x04, 0x08, 0xF6 }; -const u8 T38[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -const struct mxt224_cfg cfg_table[] = { - {7, T7, sizeof(T7)}, - {8, T8, sizeof(T8)}, - {9, T9, sizeof(T9)}, - {15, T15, sizeof(T15)}, - {18, T18, sizeof(T18)}, - {19, T19, sizeof(T19)}, - {20, T20, sizeof(T20)}, - {22, T22, sizeof(T22)}, - {23, T23, sizeof(T23)}, - {24, T24, sizeof(T24)}, - {25, T25, sizeof(T25)}, - {27, T27, sizeof(T27)}, - {28, T28, sizeof(T28)}, - {38, T38, sizeof(T38)} -}; -#endif - - -enum mXT224_type{ - MSG_T9_MT_1 = 1, - MSG_T9_MT_2, - MSG_T9_MT_3, - MSG_T9_MT_4, - MSG_T9_MT_5, - MSG_T9_MT_6, - MSG_T9_MT_7, - MSG_T9_MT_8, - MSG_T9_MT_9, - MSG_T9_KEY_PRESS, - - MSG_T6, -}; - -enum mXT224_touch_status{ - STATUS_RELEASE = 0, - STATUS_PRESS, -}; - - -u32 static crc24(u32 crc, u8 firstbyte, u8 secondbyte) -{ - const u32 crcpoly = 0x80001b; - u32 result; - u16 data_word; - - data_word = (u16)((u16)(secondbyte<<8u)|firstbyte); - result = ((crc<<1u)^(u32)data_word); - if(result & 0x1000000){ - result ^= crcpoly; - } - return result; -} - -u32 static get_crc24(const u8* src, int cnt) -{ - int index = 0; - u32 crc = 0; - - while(index < (cnt-1)){ - crc = crc24(crc, *(src+index), *(src+index+1)); - index += 2; - } - //1 TODO: - if(index != cnt){ - crc = crc24(crc, *(src+index), 0); - } - crc = (crc & 0x00ffffff); - return crc; -} - -static u32 mXT224_cfg_crc(void) -{ - int index; - int sub_index = 0; - u32 crc = 0; - - /* Remove T38 */ - for(index=0; index<((sizeof(cfg_table)/sizeof(cfg_table[0]))-1); index++){ - const u8* data = cfg_table[index].data; - while(sub_index <(cfg_table[index].size-1)){ - crc = crc24(crc, *(data+sub_index), *(data+sub_index+1)); - sub_index += 2; - } - if(sub_index != cfg_table[index].size){ - if(index == ((sizeof(cfg_table)/sizeof(cfg_table[0]))-1)){ - crc = crc24(crc, *(data+sub_index), 0); - }else{ - const u8* next_data = cfg_table[index+1].data; - crc = crc24(crc, *(data+sub_index), *(next_data)); - crc = (crc & 0x00ffffff); - sub_index = 1; - continue; - } - } - sub_index = 0; - crc = (crc & 0x00ffffff); - } - //1 TODO: - //crc = crc24(crc, 0, 0); - crc = (crc & 0x00ffffff); - return crc; -} - -static void mxt224_mem_dbg(const void *src, int cnt) -{ -#if 0 - int index; - const u8* disp = (u8*)src; - local_debug(KERN_INFO "%s: start...\n", __func__); - for(index=0; index < cnt; index++){ - local_debug(KERN_INFO "0x%2x ", disp[index]); - } - local_debug(KERN_INFO "\n%s: ...end\n", __func__); -#endif -} - - - -static irqreturn_t mXT224_ts_interrupt(int irq, void *handle) -{ - struct mXT224_info *ts = handle; - local_debug(KERN_INFO "%s\n", __func__); - - disable_irq_nosync(ts->int_gpio); - queue_delayed_work(ts->mxt224_wq, &ts->work, 0); - - return IRQ_HANDLED; -} - - -static u16 mXT224_get_obj_addr(u8 type, struct mxt224_table_info *info, u8 info_size) -{ - int index; - u16 addr = 0; - - for(index=0; index < info_size; index++){ - if(type == info[index].obj_type){ - addr = info[index].start_addr_msb; - addr <<= 8; - addr |= info[index].start_addr_lsb; - return addr; - } - } - return addr; -} - - -static struct report_id_table* mXT224_build_report_id_table( - struct mxt224_table_info *info, u8 info_size) -{ - int index; - int write_index; - u8 offset = 0; - id_table = (struct report_id_table*)kzalloc(info_size*sizeof(struct report_id_table), GFP_KERNEL); - - if(!id_table){ - local_debug(KERN_INFO "%s: Can't get memory!\n", __func__); - return NULL; - } - - write_index = 0; - - for(index = 0; index < info_size; index++){ -#ifdef FEATURE_CFG_DUMP - total_size += ((info[index].size+1)*(info[index].instance+1)); -#endif - if(info[index].obj_type == 0x5) - continue; - if(info[index].report_id == 0x00) - continue; - - id_table[write_index].obj_type = info[index].obj_type; - id_table[write_index].report_start = (offset+1); - id_table[write_index].report_end = id_table[write_index].report_start+ - info[index].report_id*(info[index].instance+1)-1; - - offset = id_table[write_index].report_end; - write_index++; - } - -#ifdef FEATURE_CFG_DUMP - for(index = 0; index < info_size; index++){ - local_debug(KERN_INFO "%s: Object type:%d, size:[%d]\n", __func__, - info[index].obj_type, info[index].size+1); - } -#endif - - return id_table; -} - - -static u8 mXT224_get_obj_type(u8 id, struct report_id_table* table, u8 table_size) -{ - int index; - - for(index=0; index < table_size; index++){ - local_debug(KERN_INFO "%s: ID:%d, start:[%d], end:[%d], type:[%d]\n", __func__, - id, table[index].report_start, table[index].report_end, - table[index].obj_type); - if(id>=table[index].report_start && id<=table[index].report_end){ - break; - } - } - - switch(table[index].obj_type){ - case 6: - return MSG_T6; - - case 9: - { - int t9_offset = id-table[index].report_start; - if(t9_offset < MXT224_REPORTID_T9_OFFSET){ - return MSG_T9_MT_1+t9_offset; - }else{ - return 0; - } - } - case 15: - { - return MSG_T9_KEY_PRESS; - } - default: - return 0; - } -} - - -#define TS_POLL_PERIOD 10000*1000 - - - -static void mXT224_load_cfg(void) -{ - int index; - u8 buf[6] = {0}; - u16 addr; - int rc; - - local_debug(KERN_INFO "%s\n", __func__); - - if(ts_data.cfg_delay){ - return; - } - ts_data.cfg_delay = 1; - - // hrtimer_start(&ts_data.timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_MODE_REL); - - for(index=0; index<(sizeof(cfg_table)/sizeof(cfg_table[0])); index++){ - - const u8* data = cfg_table[index].data; - u16 addr = mXT224_get_obj_addr(cfg_table[index].type, ts_data.obj.table_info, - ts_data.obj.table_size); - rc = mxt224_i2c_write(ts_data.client, addr, data, cfg_table[index].size); - if(rc){ - local_debug(KERN_INFO "%s: Load mXT224 config failed, addr: 0x%x!\n", __func__, addr); - } - } - - addr = mXT224_get_obj_addr(6, ts_data.obj.table_info, ts_data.obj.table_size); - - //buf[0] = 0x05; - buf[1] = 0x55; - - rc = mxt224_i2c_write(ts_data.client, addr, buf, 6); - - if(rc){ - local_debug(KERN_INFO "%s: Back up NV failed!\n", __func__); - } - - /* Reset mXT224 */ - msleep(5); - - gpio_set_value(ts_data.reset_gpio, 0); - msleep(1); - - gpio_set_value(ts_data.reset_gpio, 1); - msleep(50); - -} - - - -#define DETECT_MASK (0x01<<7) -#define RELEASE_MASK (0x01<<5) -#define MOVE_MASK (0x01<<4) - - -static u32 cfg_crc; - - -static int mXT224_process_msg(u8 id, u8 *msg) -{ - - switch(id){ - case MSG_T6: - { - local_debug(KERN_INFO "%s: Process mXT224 msg MSG_T6!\n", __func__); - u32 checksum = ((union msg_body*)msg)->t6.checksum; - - u8 status = ((union msg_body*)msg)->t6.status; - - if(status & CFGERR_MASK){ - local_debug(KERN_INFO "%s: Process mXT224 cfg error!\n", __func__); - // mXT224_load_cfg(); - } - /* - if(checksum!=cfg_crc){ - local_debug(KERN_INFO "%s: Process mXT224 cfg CRC error!\n", __func__); - local_debug(KERN_INFO "%s: Read CRC:[0x%x], Our CRC:[0x%x]\n", __func__, checksum, cfg_crc); - mXT224_load_cfg(); - } - */ - break; - } - - case MSG_T9_MT_1: - - case MSG_T9_MT_2: - - case MSG_T9_MT_3: - case MSG_T9_MT_4: - case MSG_T9_MT_5: - { - local_debug(KERN_INFO "%s: Process mXT224 msg MSG_T9_MT!\n", __func__); - u32 x, y; - int tcStatus = 0; - x = ((union msg_body*)msg)->t9.x_msb; - x <<= 4; - x |= (((union msg_body*)msg)->t9.xy_poslisb>>4); - - y = ((union msg_body*)msg)->t9.y_msb; - y <<= 4; - ((union msg_body*)msg)->t9.xy_poslisb &= 0x0f; - - y |= ((union msg_body*)msg)->t9.xy_poslisb; - - local_debug(KERN_INFO "%s: X[%d], Y[%d]\n", __func__, x, y); - - if(((union msg_body*)msg)->t9.status & DETECT_MASK) - { - tcStatus = STATUS_PRESS; - }else if(((union msg_body*)msg)->t9.status & RELEASE_MASK) - { - tcStatus = STATUS_RELEASE; - } - - input_report_abs(ts_data.input_dev, ABS_MT_TRACKING_ID, id - 1); - input_report_abs(ts_data.input_dev, ABS_MT_TOUCH_MAJOR, tcStatus); - input_report_abs(ts_data.input_dev, ABS_MT_WIDTH_MAJOR, 0); - input_report_abs(ts_data.input_dev, ABS_MT_POSITION_X, x); - input_report_abs(ts_data.input_dev, ABS_MT_POSITION_Y, y); - input_mt_sync(ts_data.input_dev); - local_debug(KERN_INFO "%s,input_report_abs x is %d,y is %d. status is [%d].\n", __func__, x, y, tcStatus); - break; - } - case MSG_T9_KEY_PRESS: - { - int keyStatus, keyIndex; - - keyStatus = ((union msg_body*)msg)->t9.status >> 7; - if(keyStatus) //press. - { - keyIndex = ((union msg_body*)msg)->t9.x_msb; - ts_data.last_key_index = keyIndex; - }else{ - keyIndex = ts_data.last_key_index; - } - switch(keyIndex){ - case 1: - { - keyIndex = 0; - break; - } - case 2: - { - keyIndex = 1; - break; - } - case 4: - { - keyIndex = 2; - break; - } - case 8: - { - keyIndex = 3; - break; - } - default: - local_debug(KERN_INFO "%s: Default keyIndex [0x%x]\n", __func__, keyIndex); - break; - } - - local_debug(KERN_INFO "%s: Touch KEY code is [%d], keyStatus is [%d]\n", __func__, key_info[keyIndex].code, keyStatus); - - input_report_key(ts_data.input_dev, key_info[keyIndex].code, keyStatus); - - break; - } - - - default: - local_debug(KERN_INFO "%s: Default id[0x%x]\n", __func__, id); - - break; - } - - return 0; -} - - - -static void mXT224_work_func(struct work_struct *work) -{ - u8 track[MXT224_MT_SCAN_POINTS]; - int index, ret, read_points; - struct message_t5 msg_t5_array[MXT224_MT_SCAN_POINTS]; - - local_debug(KERN_INFO "%s\n", __func__); - - - ret = mxt224_i2c_read(ts_data.client, ts_data.obj.msg_t5_addr, - (u8*)&msg_t5_array[0], sizeof(struct message_t5) * MXT224_MT_SCAN_POINTS); - read_points = ret / sizeof(struct message_t5); - - local_debug(KERN_INFO "%s, this time read_points is %d\n", __func__, read_points); - mxt224_mem_dbg((u8*)&msg_t5_array[0], sizeof(struct message_t5) * read_points); - - for(index = 0; index < read_points; index++) - { - if(msg_t5_array[index].report_id == 0xFF) // dirty message, don't process. - { - track[index] = 0xFF; - continue; - } - track[index] = mXT224_get_obj_type(msg_t5_array[index].report_id, id_table, ts_data.obj.table_size); - - if(track[index] == 0){ - local_debug(KERN_INFO "%s: Get object type failed!, report id[0x%x]\n", __func__, msg_t5_array[index].report_id); - goto end; - } - - local_debug(KERN_INFO "%s,object's msg type is %d.\n", __func__, track[index]); - } - - for(index = 0; index < read_points; index++) - { - if(track[index] == 0xFF) - continue; - mXT224_process_msg(track[index], (u8*)&msg_t5_array[index].body); - if(track[index] == track[read_points - 1] || track[read_points - 1] == 0xFF) - { - input_sync(ts_data.input_dev); - local_debug(KERN_INFO "%s,input_sync ts_data.input_dev.\n", __func__); - } - } - -end: - enable_irq(ts_data.int_gpio); -} - - -static int mxt224_i2c_write(struct i2c_client *client, u16 offset,void *buf,int size) -{ - unsigned char objectAddr[2+size]; - int retlen; - - objectAddr[0] = offset & 0x00FF; - objectAddr[1] = offset >> 8; - memcpy(&objectAddr[2], (char *)buf, size); - retlen = i2c_master_normal_send(client, objectAddr,2 + size, 200*1000); - - return retlen; -} - -static int mxt224_i2c_read(struct i2c_client *client, u16 offset,void *buf,int size) -{ - unsigned char objectAddr[2]; - int retlen; - - if(ts_data.last_read_addr != offset) - { - ts_data.last_read_addr = offset; - objectAddr[0] = offset & 0x00FF; - objectAddr[1] = offset >> 8; - retlen = i2c_master_normal_send(client, objectAddr,2, 200*1000); - if(retlen <= 0) - return retlen; - } - retlen = i2c_master_normal_recv(client, (char *)buf, size, 200*1000); - - return retlen; -} - -static int mXT224_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - int rc; - int index; - int info_size; - u32 crc; - u16 object_addr; - - struct message_t5 msg_t5; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - return -EIO; - /* Try get GPIO */ - rc = gpio_request(ts_data.int_gpio, "Touch_int"); - - if(rc) - { - local_debug(KERN_INFO "%s: Request GPIO failed!\n", __func__); - goto failed; - } - - rc = gpio_request(ts_data.reset_gpio, "Touch_reset"); - - if(rc) - { - local_debug(KERN_INFO "%s: Request mXT224 reset GPIO failed!\n", __func__); - goto failed; - } - - /* store the value */ - i2c_set_clientdata(client, &ts_data); - ts_data.client = client; - ts_data.int_gpio= client->irq; - //client->driver = &mXT224_driver; - - ts_data.mxt224_wq = create_rt_workqueue("mxt224_wq"); - INIT_DELAYED_WORK(&ts_data.work, mXT224_work_func); - - /* Reset mXT224 */ - gpio_pull_updown(ts_data.int_gpio, 1); - - gpio_direction_output(ts_data.reset_gpio, 0); - gpio_set_value(ts_data.reset_gpio, GPIO_LOW); - msleep(10); - gpio_set_value(ts_data.reset_gpio, GPIO_HIGH); - msleep(500); - - /* Try get mXT224 table size */ - - rc = mxt224_i2c_read(client, TABLE_SIZE_ADDR, &ts_data.obj.table_size, 1); - - if(rc <= 0) - { - local_debug(KERN_INFO "%s: Get table size failed!\n", __func__); - goto failed; - } - - - - /* Try get mXT224 device info */ - info_size = CRC_SIZE+ID_INFORMATION_SIZE+ts_data.obj.table_size*OBJECT_TABLE_ELEMENT_SIZE; - - ts_data.obj.table_info_byte = (u8*)kzalloc(info_size, GFP_KERNEL); - - if(!ts_data.obj.table_info_byte) - { - local_debug(KERN_INFO "%s: Can't get memory!\n", __func__); - rc = -1; - goto failed; - } - - rc = mxt224_i2c_read(client, 0, ts_data.obj.table_info_byte, info_size); - - if(rc <= 0) - { - local_debug(KERN_INFO "%s: Get mXT224 info failed!\n", __func__); - goto get_info_failed; - } - - ts_data.obj.table_info = (struct mxt224_table_info*)(ts_data.obj.table_info_byte+ID_INFORMATION_SIZE); - mxt224_mem_dbg(ts_data.obj.table_info_byte, info_size); - - - -#if 0 - /* Try get and check CRC */ - ts_data.obj.info_crc = (ts_data.obj.table_info_byte[info_size-3])| - (ts_data.obj.table_info_byte[info_size-2]<<8)| - (ts_data.obj.table_info_byte[info_size-1]<<16); - crc = get_crc24(ts_data.obj.table_info_byte, info_size-CRC_SIZE); - - if(ts_data.obj.info_crc != crc) - { - //1 TODO: Need set config table - - local_debug(KERN_INFO "%s:CRC failed, read CRC:[0x%x], get CRC:[0x%x]\n", __func__, ts_data.obj.info_crc, crc); - - mXT224_load_cfg(); - } - - - /* Build cfg CRC */ - cfg_crc = mXT224_cfg_crc(); -#endif - - - - /* Build report id table */ - mXT224_build_report_id_table(ts_data.obj.table_info, ts_data.obj.table_size); - - - - /* Dump mXT224 config setting */ -#ifdef FEATURE_CFG_DUMP - - local_debug(KERN_INFO "%s: Config size: %d\n", __func__, total_size); - - cfg_dmup = (u8*)kzalloc(info_size+total_size, GFP_KERNEL); - - if(!cfg_dmup) - { - local_debug(KERN_INFO "%s: Cannot get memory!\n", __func__); - goto failed; - } - - mxt224_i2c_read(client, 0, cfg_dmup, info_size+total_size); - mxt224_mem_dbg(cfg_dmup, info_size+total_size); -#endif - - - /* Try get mXT224 ID info */ - rc = mxt224_i2c_read(client, 0, &ts_data.obj.id_info, ID_INFORMATION_SIZE); - - local_debug(KERN_INFO "%s: ID version is 0x%x.\n", __func__, ts_data.obj.id_info.version); - - - /* Try get message T5 info */ - if(gpio_get_value(ts_data.int_gpio)) - { - //1 TODO: Need check touch interrput pin - - local_debug(KERN_INFO "%s: GPIO status error!\n", __func__); - - rc = -1; - goto failed; - } - - ts_data.obj.msg_t5_addr = mXT224_get_obj_addr(0x5, ts_data.obj.table_info, ts_data.obj.table_size); - - rc = mxt224_i2c_read(client, ts_data.obj.msg_t5_addr, (u8*)&msg_t5, sizeof(struct message_t5)); - - if(rc <= 0) - { - local_debug(KERN_INFO "%s:Can't get message T5!\n", __func__); - goto failed; - } - - mxt224_mem_dbg((u8*)&msg_t5, sizeof(struct message_t5)); - mXT224_process_msg(mXT224_get_obj_type(msg_t5.report_id, id_table, ts_data.obj.table_size), (u8*)&msg_t5.body); - - object_addr = mXT224_get_obj_addr(0x9, ts_data.obj.table_info, ts_data.obj.table_size); - - rc = mxt224_i2c_read(client, object_addr, (u8*)&T9_cfg[0], 31); - - if(rc <= 0) - { - local_debug(KERN_INFO "%s:Can't get message T9!\n", __func__); - goto failed; - } - - mxt224_mem_dbg((u8*)&T9_cfg[0], 31); - - local_debug(KERN_INFO "%s:Change T9 orient to [0]!\n", __func__); - - T9_cfg[9] = 0; - rc = mxt224_i2c_write(client, object_addr, (u8*)&T9_cfg[0], 31); - if(rc <= 0) - { - local_debug(KERN_INFO "%s:Can't write message T9!\n", __func__); - goto failed; - } - - rc = mxt224_i2c_read(client, object_addr, (u8*)&T9_cfg[0], 31); - - if(rc <= 0) - { - local_debug(KERN_INFO "%s:Can't get message T9!\n", __func__); - goto failed; - } - mxt224_mem_dbg((u8*)&T9_cfg[0], 31); - - //local_debug(KERN_INFO "%s:Find obj report: 0x%x\n", __func__, - // mXT224_get_obj_type(msg_t5.report_id, id_table, obj_table_size)); - msleep(15); - - if(gpio_get_value(ts_data.int_gpio)) - { - local_debug(KERN_INFO "%s: GPIO value is high\n", __func__); - } - - - ts_data.input_dev = input_allocate_device(); - if (!ts_data.input_dev) - { - rc = -ENOMEM; - goto failed; - } - - input_set_drvdata(ts_data.input_dev, &ts_data); - - snprintf(ts_data.phys, sizeof(ts_data.phys), - "%s/input0", dev_name(&client->dev)); - - ts_data.input_dev->name = "mXT224_touch"; - ts_data.input_dev->id.bustype = BUS_I2C; - ts_data.input_dev->phys = ts_data.phys; - -#if 0 - set_bit(EV_SYN, ts_data.input_dev->evbit); - set_bit(EV_KEY, ts_data.input_dev->evbit); - set_bit(BTN_TOUCH, ts_data.input_dev->keybit); - set_bit(BTN_2, ts_data.input_dev->keybit); - set_bit(EV_ABS, ts_data.input_dev->evbit); - - input_set_abs_params(ts_data.input_dev, ABS_X, 0, 240, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_Y, 0, 320, 0, 0); - - for(index=0; index<(sizeof(key_info)/sizeof(key_info[0])); index++) - { - input_set_capability(ts_data.input_dev, EV_KEY, key_info[index].code); - } -#else - ts_data.input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN); - ts_data.input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - //ts_data.input_dev->keybit[BIT_WORD(BTN_2)] = BIT_MASK(BTN_2); - - for(index=0; index<(sizeof(key_info)/sizeof(key_info[0])); index++) - { - input_set_capability(ts_data.input_dev, EV_KEY, key_info[index].code); - } - input_set_abs_params(ts_data.input_dev, ABS_X, 0, CONFIG_MXT224_MAX_X, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_Y, 0, CONFIG_MXT224_MAX_Y, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_PRESSURE, 0, 255, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_HAT0X, 0, CONFIG_MXT224_MAX_X, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_HAT0Y, 0, CONFIG_MXT224_MAX_Y, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_MT_POSITION_X,0, CONFIG_MXT224_MAX_X, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_MT_POSITION_Y, 0, CONFIG_MXT224_MAX_Y, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts_data.input_dev, ABS_MT_TRACKING_ID, 0, 10, 0, 0); - -#endif - rc = input_register_device(ts_data.input_dev); - - if (rc) - { - dev_err(&client->dev, "mXT224: input_register_device rc=%d\n", rc); - goto failed; - } - - ts_data.int_gpio = gpio_to_irq(ts_data.int_gpio); - - rc = request_irq(ts_data.int_gpio, mXT224_ts_interrupt, - IRQF_TRIGGER_FALLING, "mXT224_touch", &ts_data); - if(rc) - { - local_debug(KERN_INFO "mXT224 request interrput failed!\n"); - }else{ - local_debug(KERN_INFO "mXT224 request interrput successed!\n"); - } - - - return 0; - -get_info_failed: - /* Free mXT224 info */ -failed: - - if(ts_data.input_dev != NULL) - input_free_device(ts_data.input_dev); - -#ifdef FEATURE_CFG_DUMP - kfree(cfg_dmup); -#endif - kfree(ts_data.obj.table_info_byte); - - if(id_table != NULL) - { - kfree(id_table); - id_table = NULL; - } - - return rc; -} - - -static int __devexit mXT224_remove(struct i2c_client *client) -{ - struct mXT224_info *ts = i2c_get_clientdata(client); - - free_irq(ts->int_gpio, ts); - if (cancel_delayed_work_sync(&ts->work)) { - /* - * Work was pending, therefore we need to enable - * IRQ here to balance the disable_irq() done in the - * interrupt handler. - */ - enable_irq(ts->int_gpio); - } - - input_unregister_device(ts->input_dev); - - if(id_table != NULL) - { - kfree(id_table); - id_table = NULL; - } - return 0; -} - -static const struct i2c_device_id mXT224_ts_id[] = { - { "mXT224_touch", 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, mXT224_ts_id); - -static struct i2c_driver mXT224_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "mXT224_touch" - }, - .id_table = mXT224_ts_id, - .probe = mXT224_probe, - .remove = __devexit_p(mXT224_remove), -}; - -static void __init mXT_init_async(void *unused, async_cookie_t cookie) -{ - local_debug("--------> %s <-------------\n",__func__); - i2c_add_driver(&mXT224_driver); -} - - -static int __init mXT_init(void) -{ - async_schedule(mXT_init_async, NULL); - return 0; - -} - -static void __exit mXT_exit(void) -{ - i2c_del_driver(&mXT224_driver); -} - - -module_init(mXT_init); -module_exit(mXT_exit); - -MODULE_LICENSE("GPL"); diff --git a/include/linux/atmel_maxtouch.h b/include/linux/atmel_maxtouch.h deleted file mode 100644 index 7a806ee41d69..000000000000 --- a/include/linux/atmel_maxtouch.h +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Atmel maXTouch header file - * - * Copyright (c) 2010 Atmel Corporation - * Copyright (C) 2010 Ulf Samuelsson (ulf@atmel.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * See the file "COPYING" in the main directory of this archive - * for more details. - * - */ - -#define MXT224_I2C_ADDR1 0x4A -#define MXT224_I2C_ADDR2 0x4B -#define MXT1386_I2C_ADDR1 0x4C -#define MXT1386_I2C_ADDR2 0x4D -#define MXT1386_I2C_ADDR3 0x5A -#define MXT1386_I2C_ADDR4 0x5B - -/* - * Select this address from above depending on what maXTouch - * chip you have and how it's address pins are configured; - * see datasheet. - */ - -#define MXT_I2C_ADDRESS MXT224_I2C_ADDR2 - -#define MXT_BL_ADDRESS 0x25 - -#define MXT224_FAMILYID 0x80 -#define MXT1386_FAMILYID 0xA0 - -#define MXT224_CAL_VARIANTID 0x01 -#define MXT224_UNCAL_VARIANTID 0x00 -#define MXT1386_CAL_VARIANTID 0x00 - -#define MXT_MAX_REPORTED_WIDTH 255 -#define MXT_MAX_REPORTED_PRESSURE 255 -#define MXT_MAX_TOUCH_SIZE 255 -#define MXT_MAX_NUM_TOUCHES 10 - -/* Fixed addresses inside maXTouch device */ -#define MXT_ADDR_INFO_BLOCK 0 -#define MXT_ADDR_OBJECT_TABLE 7 -#define MXT_ID_BLOCK_SIZE 7 -#define MXT_OBJECT_TABLE_ELEMENT_SIZE 6 - -/* Object types */ -#define MXT_DEBUG_DELTAS_T2 2 -#define MXT_DEBUG_REFERENCES_T3 3 -#define MXT_GEN_MESSAGEPROCESSOR_T5 5 -#define MXT_GEN_COMMANDPROCESSOR_T6 6 -#define MXT_GEN_POWERCONFIG_T7 7 -#define MXT_GEN_ACQUIRECONFIG_T8 8 -#define MXT_TOUCH_MULTITOUCHSCREEN_T9 9 -#define MXT_TOUCH_SINGLETOUCHSCREEN_T10 10 -#define MXT_TOUCH_XSLIDER_T11 11 -#define MXT_TOUCH_YSLIDER_T12 12 -#define MXT_TOUCH_XWHEEL_T13 13 -#define MXT_TOUCH_YWHEEL_T14 14 -#define MXT_TOUCH_KEYARRAY_T15 15 -#define MXT_SPT_GPIOPWM_T19 19 -#define MXT_PROCI_GRIPFACESUPPRESSION_T20 20 -#define MXT_PROCG_NOISESUPPRESSION_T22 22 -#define MXT_TOUCH_PROXIMITY_T23 23 -#define MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24 24 -#define MXT_SPT_SELFTEST_T25 25 -#define MXT_DEBUG_CTERANGE_T26 26 -#define MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27 27 -#define MXT_SPT_CTECONFIG_T28 28 -#define MXT_TOUCH_KEYSET_T31 31 -#define MXT_TOUCH_XSLIDERSET_T32 32 -#define MXT_DEBUG_DIAGNOSTIC_T37 37 -#define MXT_USER_INFO_T38 38 - - -/* - * If a message is read from mXT when there's no new messages available, - * the report ID of the message will be 0xFF. - */ -#define MXT_END_OF_MESSAGES 0xFF - - -/* GEN_COMMANDPROCESSOR_T6 Register offsets from T6 base address */ -#define MXT_ADR_T6_RESET 0x00 -#define MXT_ADR_T6_BACKUPNV 0x01 -#define MXT_ADR_T6_CALIBRATE 0x02 -#define MXT_ADR_T6_REPORTALL 0x03 -#define MXT_ADR_T6_RESERVED 0x04 -#define MXT_ADR_T6_DIAGNOSTIC 0x05 - -/* T6 Debug Diagnostics Commands */ -#define MXT_CMD_T6_PAGE_UP 0x01 -#define MXT_CMD_T6_PAGE_DOWN 0x02 -#define MXT_CMD_T6_DELTAS_MODE 0x10 -#define MXT_CMD_T6_REFERENCES_MODE 0x11 -#define MXT_CMD_T6_CTE_MODE 0x31 - -/* T6 Backup Command */ -#define MXT_CMD_T6_BACKUP 0x55 - -/* SPT_DEBUG_DIAGNOSTIC_T37 Register offsets from T37 base address */ -#define MXT_ADR_T37_PAGE 0x01 -#define MXT_ADR_T37_DATA 0x02 - - - -/************************************************************************ - * MESSAGE OBJECTS ADDRESS FIELDS - * - ************************************************************************/ -#define MXT_MSG_REPORTID 0x00 - - -/* MXT_GEN_MESSAGEPROCESSOR_T5 Message address definitions */ -#define MXT_MSG_T5_REPORTID 0x00 -#define MXT_MSG_T5_MESSAGE 0x01 -#define MXT_MSG_T5_CHECKSUM 0x08 - -/* MXT_GEN_COMMANDPROCESSOR_T6 Message address definitions */ -#define MXT_MSG_T6_STATUS 0x01 -#define MXT_MSGB_T6_COMSERR 0x04 -#define MXT_MSGB_T6_CFGERR 0x08 -#define MXT_MSGB_T6_CAL 0x10 -#define MXT_MSGB_T6_SIGERR 0x20 -#define MXT_MSGB_T6_OFL 0x40 -#define MXT_MSGB_T6_RESET 0x80 -/* Three bytes */ -#define MXT_MSG_T6_CHECKSUM 0x02 - -/* MXT_GEN_POWERCONFIG_T7 NO Message address definitions */ -/* MXT_GEN_ACQUIRECONFIG_T8 Message address definitions */ -/* MXT_TOUCH_MULTITOUCHSCREEN_T9 Message address definitions */ - -#define MXT_MSG_T9_STATUS 0x01 -/* Status bit field */ -#define MXT_MSGB_T9_SUPPRESS 0x02 -#define MXT_MSGB_T9_AMP 0x04 -#define MXT_MSGB_T9_VECTOR 0x08 -#define MXT_MSGB_T9_MOVE 0x10 -#define MXT_MSGB_T9_RELEASE 0x20 -#define MXT_MSGB_T9_PRESS 0x40 -#define MXT_MSGB_T9_DETECT 0x80 - -#define MXT_MSG_T9_XPOSMSB 0x02 -#define MXT_MSG_T9_YPOSMSB 0x03 -#define MXT_MSG_T9_XYPOSLSB 0x04 -#define MXT_MSG_T9_TCHAREA 0x05 -#define MXT_MSG_T9_TCHAMPLITUDE 0x06 -#define MXT_MSG_T9_TCHVECTOR 0x07 - - -/* MXT_SPT_GPIOPWM_T19 Message address definitions */ -#define MXT_MSG_T19_STATUS 0x01 - -/* MXT_PROCI_GRIPFACESUPPRESSION_T20 Message address definitions */ -#define MXT_MSG_T20_STATUS 0x01 -#define MXT_MSGB_T20_FACE_SUPPRESS 0x01 -/* MXT_PROCG_NOISESUPPRESSION_T22 Message address definitions */ -#define MXT_MSG_T22_STATUS 0x01 -#define MXT_MSGB_T22_FHCHG 0x01 -#define MXT_MSGB_T22_GCAFERR 0x04 -#define MXT_MSGB_T22_FHERR 0x08 -#define MXT_MSG_T22_GCAFDEPTH 0x02 - -/* MXT_TOUCH_PROXIMITY_T23 Message address definitions */ -#define MXT_MSG_T23_STATUS 0x01 -#define MXT_MSGB_T23_FALL 0x20 -#define MXT_MSGB_T23_RISE 0x40 -#define MXT_MSGB_T23_DETECT 0x80 -/* 16 bit */ -#define MXT_MSG_T23_PROXDELTA 0x02 - -/* MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24 Message address definitions */ -#define MXT_MSG_T24_STATUS 0x01 -#define MXT_MSG_T24_XPOSMSB 0x02 -#define MXT_MSG_T24_YPOSMSB 0x03 -#define MXT_MSG_T24_XYPOSLSB 0x04 -#define MXT_MSG_T24_DIR 0x05 -/* 16 bit */ -#define MXT_MSG_T24_DIST 0x06 - -/* MXT_SPT_SELFTEST_T25 Message address definitions */ -#define MXT_MSG_T25_STATUS 0x01 -/* 5 Bytes */ -#define MXT_MSGR_T25_OK 0xFE -#define MXT_MSGR_T25_INVALID_TEST 0xFD -#define MXT_MSGR_T25_PIN_FAULT 0x11 -#define MXT_MSGR_T25_SIGNAL_LIMIT_FAULT 0x17 -#define MXT_MSGR_T25_GAIN_ERROR 0x20 -#define MXT_MSG_T25_INFO 0x02 - -/* MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27 Message address definitions */ -#define MXT_MSG_T27_STATUS 0x01 -#define MXT_MSGB_T27_ROTATEDIR 0x10 -#define MXT_MSGB_T27_PINCH 0x20 -#define MXT_MSGB_T27_ROTATE 0x40 -#define MXT_MSGB_T27_STRETCH 0x80 -#define MXT_MSG_T27_XPOSMSB 0x02 -#define MXT_MSG_T27_YPOSMSB 0x03 -#define MXT_MSG_T27_XYPOSLSB 0x04 -#define MXT_MSG_T27_ANGLE 0x05 - -/* 16 bit */ -#define MXT_MSG_T27_SEPARATION 0x06 - -/* MXT_SPT_CTECONFIG_T28 Message address definitions */ -#define MXT_MSG_T28_STATUS 0x01 -#define MXT_MSGB_T28_CHKERR 0x01 - - -/* One Touch Events */ -#define MXT_GESTURE_RESERVED 0x00 -#define MXT_GESTURE_PRESS 0x01 -#define MXT_GESTURE_RELEASE 0x02 -#define MXT_GESTURE_TAP 0x03 -#define MXT_GESTURE_DOUBLE_TAP 0x04 -#define MXT_GESTURE_FLICK 0x05 -#define MXT_GESTURE_DRAG 0x06 -#define MXT_GESTURE_SHORT_PRESS 0x07 -#define MXT_GESTURE_LONG_PRESS 0x08 -#define MXT_GESTURE_REPEAT_PRESS 0x09 -#define MXT_GESTURE_TAP_AND_PRESS 0x0a -#define MXT_GESTURE_THROW 0x0b - -/* Two-touch events */ -#define MXT_GESTURE_STRETCH (1 << 7) -#define MXT_GESTURE_ROTATE (1 << 6) -#define MXT_GESTURE_PINCH (1 << 5) -#define MXT_GESTURE_ROTATEDIR (1 << 4) - - - -/* Bootloader states */ -#define WAITING_BOOTLOAD_COMMAND 0xC0 -#define WAITING_FRAME_DATA 0x80 -#define APP_CRC_FAIL 0x40 -#define FRAME_CRC_CHECK 0x02 -#define FRAME_CRC_PASS 0x04 -#define FRAME_CRC_FAIL 0x03 - -#define MXT_MAX_FRAME_SIZE 276 - -/* Debug levels */ -#define DEBUG_INFO 1 -#define DEBUG_VERBOSE 2 -#define DEBUG_MESSAGES 5 -#define DEBUG_RAW 8 -#define DEBUG_TRACE 10 - -/* IOCTL commands */ -/* TODO: get correct numbers! */ -#define MXT_SET_ADDRESS_IOCTL ('x' + 1) /* Sets the internal address pointer */ -#define MXT_RESET_IOCTL ('x' + 2) /* Resets the device */ -#define MXT_CALIBRATE_IOCTL ('x' + 3) /* Calibrates the device */ -/* Backups the current state of registers to NVM */ -#define MXT_BACKUP_IOCTL ('x' + 4) -/* - * Only non-touch messages can be read from the message buffer - * (/dev/maXTouch_messages) - */ -#define MXT_NONTOUCH_MSG_IOCTL ('x' + 5) -/* All messages can be read from the message buffer */ -#define MXT_ALL_MSG_IOCTL ('x' + 6) - - -/* Message buffer size. This is a ring buffer, and when full, the oldest entry - will be overwritten. */ -#define MXT_MESSAGE_BUFFER_SIZE 256 - -#define MXT_MAKE_HIGH_CHG_SIZE_MIN 10 -#define MXT_ACK_BUFFER_SIZE 16 - -/* Routines for memory access within a 16 bit address space */ - -/* TODO: - won't compile if functions aren't defined*/ -/* Bootloader specific function prototypes. */ - -#if 0 -static int mxt_read_byte_bl(struct i2c_client *client, u8 *value); -static int mxt_read_block_bl(struct i2c_client *client, u16 length, u8 *value); -static int mxt_write_byte_bl(struct i2c_client *client, u8 value); -static int mxt_write_block_bl(struct i2c_client *client, u16 length, u8 *value); -#endif - -/** - * struct mxt_platform_data - includes platform specific informatio - * related to Atmel maXTouch touchscreen controller. - * - * @numtouch: Number of simultaneous touches supported - * @init_platform_hw(): Initialization function, which can for example - * trigger a hardware reset by toggling a GPIO pin - * @exit_platform_hw(): Function to run when the driver is unloaded. - * @valid_interrupt(): Function that checks the validity of the interrupt - - * function that check the validity of a interrupt (by - * reading the changeline interrupt pin and checking that - * it really is low for example). - * @max_x: Reported X range - * @max_y: Reported Y range - */ - -struct mxt_platform_data { - u8 numtouch; /* Number of touches to report */ - int (*init_platform_hw)(struct i2c_client *client); - int (*exit_platform_hw)(struct i2c_client *client); - int max_x; /* The default reported X range */ - int max_y; /* The default reported Y range */ - u8 (*valid_interrupt) (void); - u8 (*read_chg) (void); -}; - -void mxt_hw_reset(void);