| /*
|
| *
|
| * Zinitix touch driver
|
| *
|
| * Copyright (C) 2009 Zinitix, Inc.
|
| *
|
| * This software is licensed under the terms of the GNU General Public
|
| * License version 2, as published by the Free Software Foundation, and
|
| * may be copied, distributed, and modified under those terms.
|
| *
|
| * 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.
|
| *
|
| */
|
| // Version 2.0.0 : using reg data file (2010/11/05)
|
| // Version 2.0.1 : syntxt bug fix (2010/11/09)
|
| // Version 2.0.2 : Save status cmd delay bug (2010/11/10)
|
| // Version 2.0.3 : modify delay 10ms -> 50ms for clear hw calibration bit
|
| // : modify ZINITIX_TOTAL_NUMBER_OF_Y register (read only -> read/write )
|
| // : modify SUPPORTED FINGER NUM register (read only -> read/write )
|
| // Version 2.0.4 : [20101116]
|
| // Modify Firmware Upgrade routine.
|
| // Version 2.0.5 : [20101118]
|
| // add esd timer function & some bug fix.
|
| // you can select request_threaded_irq or request_irq, setting USE_THREADED_IRQ.
|
| // Version 2.0.6 : [20101123]
|
| // add ABS_MT_WIDTH_MAJOR Report
|
| // Version 2.0.7 : [20101201]
|
| // Modify zinitix_early_suspend() / zinitix_late_resume() routine.
|
| // Version 2.0.8 : [20101216]
|
| // add using spin_lock option
|
| // Version 2.0.9 : [20101216]
|
| // Test Version
|
| // Version 2.0.10 : [20101217]
|
| // add USE_THREAD_METHOD option. if USE_THREAD_METHOD = 0, you use workqueue
|
| // Version 2.0.11 : [20101229]
|
| // add USE_UPDATE_SYSFS option for update firmware. && TOUCH_MODE == 1 mode.
|
| // Version 2.0.13 : [20110125]
|
| // modify esd timer routine
|
| // Version 2.0.14 : [20110217]
|
| // esd timer bug fix. (kernel panic)
|
| // sysfs bug fix.
|
| // Version 2.0.15 : [20110315]
|
| // add power off delay ,250ms
|
| // Version 2.0.16 : [20110316]
|
| // add upgrade method using isp
|
| // Version 2.0.17 : [20110406]
|
| // change naming rule : sain -> zinitix
|
| // (add) pending interrupt skip
|
| // add isp upgrade mode
|
| // remove warning message when complile
|
|
|
| // Version 3.0.2 : [20110711]
|
| // support bt4x3 series
|
| // Version 3.0.3 : [20110720]
|
| // add raw data monitoring func.
|
| // add the h/w calibration skip option.
|
| // Version 3.0.4 : [20110728]
|
| // use threaded irq
|
| // Version 3.0.5 : [20110801]
|
| // fix some bugs.
|
| // Version 3.0.6 : [20110802]
|
| // fix Bt4x3 isp upgrade bug.
|
| // add USE_TS_MISC_DEVICE option for showing info & upgrade
|
| // remove USE_UPDATE_SYSFS option
|
| // Version 3.0.7 : [201108016]
|
| // merge USE_TS_MISC_DEVICE option and USE_TEST_RAW_TH_DATA_MODE
|
| // fix work proceedure bug.
|
| // Version 3.0.8 / Version 3.0.9 : [201108017]
|
| // add ioctl func.
|
| // Version 3.0.10 : [201108030]
|
| // support REAL_SUPPORTED_FINGER_NUM
|
| // Version 3.0.11 : [201109014]
|
| // support zinitix apps.
|
| // Version 3.0.12 : [201109015]
|
| // add disable touch event func.
|
| // Version 3.0.13 : [201109015]
|
| // add USING_CHIP_SETTING option. : interrupt mask / button num / finger num
|
| // Version 3.0.14 : [201109020]
|
| // support apps. above kernel version 2.6.35
|
| // Version 3.0.15 : [201101004]
|
| // modify timing in firmware upgrade
|
| // retry when failt to upgrade firmware
|
|
|
|
|
| #include <linux/module.h>
|
| #include <linux/input.h>
|
| #include <linux/i2c.h> // I2C_M_NOSTART
|
| #include <linux/miscdevice.h>
|
| #include <linux/interrupt.h>
|
| #include <linux/platform_device.h>
|
| #include <linux/hrtimer.h>
|
| #include <linux/ioctl.h>
|
| #include <linux/earlysuspend.h>
|
| #include <linux/string.h>
|
| #include <linux/semaphore.h>
|
| #include <linux/kthread.h>
|
| #include <linux/timer.h>
|
| #include <linux/workqueue.h>
|
| #include <linux/firmware.h>
|
| #include <linux/slab.h>
|
| #include <linux/version.h>
|
|
|
|
|
| #include <asm/io.h>
|
| #include <linux/delay.h>
|
| #include <mach/gpio.h>
|
| #include <asm/uaccess.h>
|
| // PSJ #include <linux/i2c/tsp_gpio.h>
|
| // PSJ #include <linux/d1982/pmic.h>
|
| // platform dependent
|
| // -----------------------------
|
| //#include <mach/regs-mem.h>
|
| //#include <mach/regs-gpio.h>
|
| //#include <mach/gpio-bank.h>
|
| // -----------------------------
|
|
|
|
|
| #include "zinitix_tsp_bt403_amazing.h"
|
|
|
| #include <linux/time.h> //KEY_LED_CONTROL
|
| #include <linux/timer.h>
|
| //#include <linux/mfd/pmic8058.h>
|
|
|
| #if BT4x2_Series
|
| #include "zinitix_touch_firmware.h"
|
| #include "zinitix_touch_reg_data.h"
|
| #endif
|
|
|
| #if BT4x3_Above_Series
|
| //#include "zinitix_touch_bt4x3_firmware.h" //V75
|
| //#include "zinitix_touch_bt4x3_firmware_R01.h" //V76
|
| //#include "ZinitixFW/zinitix_touch_bt4x3_firmware.h" //V78_test
|
| #include "ZinitixFW/zinitix_touch_bt4x3_firmware_R001.h" //R21
|
| #include "ZinitixFW/zinitix_touch_bt4x3_reg_data.h"
|
| #endif
|
|
|
| //#define SEC_DRIVER
|
| //#define KEY_LED_CONTROL
|
|
|
| #define TSP_INT 121 //PSJ
|
| #define TOUCH_EN 22 //PSJ
|
|
|
| #define CONFIG_TREBON_HW01 1
|
| #if 0 |
| static struct regulator *touch_regulator = NULL;
|
| #ifdef CONFIG_TREBON_HW01
|
| static struct regulator *touch_io_regulator = NULL;
|
| #endif
|
| #endif |
|
|
| #define ZINITIX_DEBUG 1
|
|
|
| static int m_ts_debug_mode = ZINITIX_DEBUG;
|
|
|
| #define SYSTEM_MAX_X_RESOLUTION 319 //4000 //480
|
| #define SYSTEM_MAX_Y_RESOLUTION 479 //3900 //800
|
|
|
| #ifdef CONFIG_TREBON_HW01
|
| #define T_REGULATOR_TOUCH "D1980_LDO8"
|
| #define T_REGULATOR_IO_TOUCH "D1980_LDO19"
|
| #endif
|
|
|
| #if RESET_CONTROL
|
| #define SYSTEM_RESET_PIN S5PV210_GPG3(0)
|
| #endif
|
|
|
|
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| static struct workqueue_struct *zinitix_tmr_workqueue;
|
| #endif
|
|
|
| #define zinitix_debug_msg(fmt, args...) if(m_ts_debug_mode) printk(KERN_INFO "[TSP][%-18s:%5d]" fmt, __FUNCTION__, __LINE__, ## args)
|
|
|
| //-------------------------------------------------------
|
| typedef struct
|
| {
|
| u16 x;
|
| u16 y;
|
| u8 width;
|
| u8 sub_status;
|
| }_ts_zinitix_coord;
|
|
|
| typedef struct
|
| {
|
| u16 status;
|
| #if (TOUCH_MODE == 1)
|
| u16 event_flag;
|
| #else
|
| u8 finger_cnt;
|
| u8 time_stamp;
|
| #endif
|
| _ts_zinitix_coord coord[MAX_SUPPORTED_FINGER_NUM];
|
|
|
| }_ts_zinitix_point_info;
|
|
|
|
|
| #define TOUCH_V_FLIP 0x01
|
| #define TOUCH_H_FLIP 0x02
|
| #define TOUCH_XY_SWAP 0x04
|
|
|
| typedef struct
|
| {
|
| u16 chip_revision;
|
| u16 chip_firmware_version;
|
| u16 chip_reg_data_version;
|
| u16 x_resolution;
|
| u16 y_resolution;
|
| u32 chip_fw_size;
|
| u32 MaxX;
|
| u32 MaxY;
|
| u32 MinX;
|
| u32 MinY;
|
| u32 Orientation;
|
| u8 gesture_support;
|
| u16 multi_fingers;
|
| u16 button_num;
|
| u16 chip_int_mask;
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| u16 x_node_num;
|
| u16 y_node_num;
|
| u16 total_node_num;
|
| #if BT4x3_Above_Series
|
| u16 max_y_node;
|
| u16 total_cal_n;
|
| #endif
|
| #endif
|
| }_ts_capa_info;
|
|
|
| typedef enum
|
| {
|
| TS_NO_WORK = 0,
|
| TS_NORMAL_WORK,
|
| TS_ESD_TIMER_WORK,
|
| TS_IN_EALRY_SUSPEND,
|
| TS_IN_SUSPEND,
|
| TS_IN_RESUME,
|
| TS_IN_LATE_RESUME,
|
| TS_IN_UPGRADE,
|
| TS_REMOVE_WORK,
|
| TS_SET_MODE,
|
| TS_HW_CALIBRAION,
|
| }_ts_work_proceedure;
|
|
|
|
|
| typedef struct
|
| {
|
| struct input_dev *input_dev;
|
| struct task_struct *task;
|
| wait_queue_head_t wait;
|
| struct work_struct tmr_work;
|
| struct i2c_client *client;
|
| struct semaphore update_lock;
|
| u32 i2c_dev_addr;
|
| _ts_capa_info cap_info;
|
| char phys[32];
|
|
|
| bool is_valid_event;
|
| _ts_zinitix_point_info touch_info;
|
| _ts_zinitix_point_info reported_touch_info;
|
| u16 icon_event_reg;
|
| u16 event_type;
|
| u32 int_gpio_num;
|
| u32 irq;
|
| u8 button[MAX_SUPPORTED_BUTTON_NUM];
|
|
|
| u8 work_proceedure;
|
| struct semaphore work_proceedure_lock;
|
|
|
| #if RESET_CONTROL
|
| int reset_gpio_num;
|
| #endif
|
|
|
| u8 use_esd_timer;
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| bool in_esd_timer;
|
| struct timer_list esd_timeout_tmr; //for repeated card detecting work
|
| struct timer_list *p_esd_timeout_tmr; //for repeated card detecting work
|
| #endif
|
|
|
| #ifdef CONFIG_HAS_EARLYSUSPEND
|
| struct early_suspend early_suspend;
|
| #endif
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| struct semaphore raw_data_lock;
|
| u16 raw_mode_flag;
|
| s16 ref_data[MAX_TEST_RAW_DATA];
|
| s16 cur_data[MAX_RAW_DATA];
|
| u8 update;
|
| #endif
|
| } zinitix_touch_dev;
|
|
|
|
|
| #define ZINITIX_DRIVER_NAME "Zinitix_tsp"
|
|
|
| #if TOUCH_USING_ISP_METHOD
|
| #define ZINITIX_ISP_NAME "zinitix_isp"
|
| struct i2c_client *m_isp_client = NULL;
|
| #endif
|
| #define FWUP_OFF 0
|
| #define FWUP_ON 1
|
| #define FWUP_NOW -1
|
|
|
| static struct i2c_device_id zinitix_idtable[] = {
|
| #if TOUCH_USING_ISP_METHOD
|
| {ZINITIX_ISP_NAME, 0},
|
| #endif
|
| {ZINITIX_DRIVER_NAME, 0}, // i2c register.
|
| { }
|
| };
|
|
|
| int zinitixTsp_irq;
|
|
|
| u32 BUTTON_MAPPING_KEY[MAX_SUPPORTED_BUTTON_NUM]={KEY_MENU, KEY_BACK}; //SEC_DRIVER
|
|
|
| // FW version
|
| zinitix_touch_dev *global_touch_dev;
|
| int IsDuringCall = 0;
|
| static int IsdebugMatrix = 0;
|
| static u8 IsfwUpdate = 0;
|
| /* sys fs */
|
| struct class *touch_class;
|
| EXPORT_SYMBOL(touch_class);
|
| struct device *firmware_dev;
|
| EXPORT_SYMBOL(firmware_dev);
|
| static ssize_t firmware_show(struct device *dev, struct device_attribute *attr, char *buf);
|
| static ssize_t firmware_sw_show(struct device *dev, struct device_attribute *attr, char *buf);
|
| static ssize_t tsp_StartCall_show(struct device *dev, struct device_attribute *attr, char *buf);
|
| static ssize_t tsp_EndCall_show(struct device *dev, struct device_attribute *attr, char *buf);
|
| static ssize_t tsp_xy_show(struct device *dev, struct device_attribute *attr, char *buf);
|
| static ssize_t firmware_update(struct device *dev, struct device_attribute *attr, char *buf);
|
| static ssize_t firmware_update_status(struct device *dev, struct device_attribute *attr, char *buf);
|
| //static ssize_t firmware_store( struct device *dev, struct device_attribute *attr, const char *buf, size_t size);
|
| static DEVICE_ATTR(firmware_ver , S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, firmware_show, NULL);
|
| static DEVICE_ATTR(sw_ver , S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, firmware_sw_show, NULL);
|
| static DEVICE_ATTR(tsp_StartCall , S_IRUGO | S_IWUSR | S_IWGRP | S_IXOTH, tsp_StartCall_show, NULL);
|
| static DEVICE_ATTR(tsp_EndCall , S_IRUGO | S_IWUSR | S_IWGRP | S_IXOTH, tsp_EndCall_show, NULL);
|
| static DEVICE_ATTR(debug_xy, S_IRUGO | S_IWUSR | S_IWGRP | S_IXOTH, tsp_xy_show, NULL);
|
| static DEVICE_ATTR(fw_update, S_IRUGO | S_IWUSR | S_IWGRP | S_IXOTH, firmware_update, NULL);
|
| static DEVICE_ATTR(fw_upstatus, S_IRUGO | S_IWUSR | S_IWGRP | S_IXOTH, firmware_update_status, NULL);
|
| // define sub functions
|
| //==================================================================
|
| #if BT4x2_Series
|
| inline s32 ts_write_cmd(struct i2c_client *client, u8 reg)
|
| {
|
| s32 ret;
|
| ret = i2c_smbus_write_byte(client, reg);
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return ret;
|
| }
|
|
|
| inline s32 ts_write_reg(struct i2c_client *client, u8 reg, u16 value)
|
| {
|
| s32 ret;
|
| ret = i2c_smbus_write_word_data(client, reg, value);
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return ret;
|
| }
|
|
|
| inline s32 ts_read_data(struct i2c_client *client, u8 reg, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| if((ret = i2c_master_send(client , ® , 1)) < 0) return ret; // select register
|
| udelay(DELAY_FOR_TRANSCATION); // for setup tx transaction.
|
| if((ret = i2c_master_recv(client , values , length)) < 0) return ret;
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return length;
|
| }
|
|
|
| inline s32 ts_write_data(struct i2c_client *client, u8 reg, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| ret = i2c_smbus_write_i2c_block_data(client, reg, length, values);
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return ret;
|
| }
|
|
|
| inline s32 ts_read_raw_data(struct i2c_client *client, u8 reg, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| if((ret = i2c_master_send(client , ® , 1)) < 0) return ret; // select register
|
| mdelay(5); // for setup tx transaction
|
| if((ret = i2c_master_recv(client , values , length)) < 0) return ret;
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return length;
|
| }
|
| #endif
|
| #define TOUCH_ON 1
|
| #define TOUCH_OFF 0
|
|
|
|
|
| void touch_power_control(int on_off)
|
| {
|
| int rc;
|
|
|
| if (on_off == TOUCH_ON)
|
| {
|
| rc = gpio_request(TOUCH_EN,"Touch_en");
|
| if (rc < 0)
|
| {
|
| printk("[TSP] touch_power_control unable to request GPIO pin");
|
| //printk(KERN_ERR "unable to request GPIO pin %d\n", TSP_INT_GPIO_PIN);
|
| return;
|
| }
|
| gpio_direction_output(TOUCH_EN,1);
|
| gpio_set_value(TOUCH_EN,1);
|
| gpio_free(TOUCH_EN);
|
| }
|
| else if(on_off == TOUCH_OFF)
|
| {
|
| gpio_request(TOUCH_EN,"Touch_en");
|
| gpio_direction_output(TOUCH_EN,0);
|
| gpio_set_value(TOUCH_EN,0);
|
| gpio_free(TOUCH_EN);
|
| }
|
| }
|
|
|
|
|
| #if 0 //PSJ
|
| void touch_ctrl_regulator(int on_off)
|
| {
|
| int ret=0;
|
|
|
| printk("[TSP] %s, %d\n", __func__, on_off );
|
|
|
| if(touch_regulator == NULL)
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_regulator = regulator_get(NULL,T_REGULATOR_TOUCH);
|
| #else
|
| touch_regulator = regulator_get(NULL,REGULATOR_TOUCH);
|
| #endif
|
| if(on_off==TOUCH_ON)
|
| {
|
| regulator_set_voltage(touch_regulator,OUTPUT_3_3V,OUTPUT_3_3V);
|
| ret = regulator_enable(touch_regulator);
|
| if (ret) {
|
| printk(KERN_ERR "%s: regulator_touch enable failed (%d)\n",__func__, ret);
|
| }
|
| }
|
| else
|
| {
|
| ret = regulator_disable(touch_regulator);
|
| if (ret) {
|
| printk(KERN_ERR "%s: regulator_touch disable failed (%d)\n",__func__, ret);
|
| }
|
| }
|
| }
|
|
|
| #ifdef CONFIG_TREBON_HW01
|
| void touch_io_ctrl_regulator(int on_off)
|
| {
|
| int ret=0,ret2=0;
|
|
|
| printk("[TSP] %s, %d\n", __func__, on_off );
|
| if(touch_io_regulator == NULL)
|
| touch_io_regulator = regulator_get(NULL,T_REGULATOR_IO_TOUCH);
|
|
|
| if(on_off==TOUCH_ON)
|
| {
|
| regulator_set_voltage(touch_io_regulator,OUTPUT_1_8V,OUTPUT_1_8V);
|
| ret = regulator_enable(touch_io_regulator);
|
| if (ret) {
|
| printk(KERN_ERR "%s: regulator_touch_io enable failed (%d)\n",__func__, ret);
|
| }
|
| }
|
| else
|
| {
|
| ret = regulator_disable(touch_io_regulator);
|
| if (ret) {
|
| printk(KERN_ERR "%s: regulator_touch_io disable failed (%d)\n",__func__, ret);
|
| }
|
| }
|
| }
|
| #endif
|
|
|
| EXPORT_SYMBOL(touch_ctrl_regulator);
|
| #ifdef CONFIG_TREBON_HW01
|
| EXPORT_SYMBOL(touch_io_ctrl_regulator);
|
| #endif
|
|
|
| #endif
|
|
|
| #if BT4x3_Above_Series
|
|
|
| inline s32 ts_read_data(struct i2c_client *client, u16 reg, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| if((ret = i2c_master_send(client , (u8*)® , 2)) < 0)
|
| {
|
| printk("[TSP] ts_read_data 1 : %d\n", ret);
|
| return ret; // select register
|
| }
|
| udelay(DELAY_FOR_TRANSCATION); // for setup tx transaction.
|
| if((ret = i2c_master_recv(client , values , length)) < 0)
|
| {
|
| printk("[TSP] ts_read_data 2: %d\n", ret);
|
| return ret;
|
| }
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return length;
|
| }
|
|
|
|
|
| inline s32 ts_write_data(struct i2c_client *client, u16 reg, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| u8 pkt[4];
|
| pkt[0] = (reg)&0xff;
|
| pkt[1] = (reg >>8)&0xff;
|
| pkt[2] = values[0];
|
| pkt[3] = values[1];
|
|
|
| if((ret = i2c_master_send(client , pkt , length+2)) < 0)
|
| {
|
| printk("[TSP] ts_write_data : %d\n", ret);
|
|
|
| return ret;
|
| }
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return length;
|
| }
|
|
|
| inline s32 ts_write_reg(struct i2c_client *client, u16 reg, u16 value)
|
| {
|
| if(ts_write_data(client, reg, (u8*)&value, 2) < 0) return -1;
|
| return I2C_SUCCESS;
|
| }
|
|
|
| inline s32 ts_write_cmd(struct i2c_client *client, u16 reg)
|
| {
|
| s32 ret;
|
| if((ret = i2c_master_send(client , (u8*)® , 2)) < 0)
|
| {
|
| printk("[TSP] ts_write_cmd : %d\n", ret);
|
| return ret;
|
| }
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return I2C_SUCCESS;
|
| }
|
|
|
| inline s32 ts_read_raw_data(struct i2c_client *client, u16 reg, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| if((ret = i2c_master_send(client , (u8*)® , 2)) < 0)
|
| {
|
| printk("[TSP] ts_read_raw_data 1 : %d\n", ret);
|
| return ret; // select register
|
| }
|
| udelay(200); // for setup tx transaction.
|
| if((ret = i2c_master_recv(client , values , length)) < 0)
|
| {
|
| printk("[TSP] ts_read_raw_data 1 : %d\n", ret);
|
|
|
| return ret;
|
| }
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return length;
|
| }
|
|
|
| #endif
|
|
|
| #if TOUCH_USING_ISP_METHOD
|
| inline s32 ts_read_firmware_data(struct i2c_client *client, char *addr, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| if(addr != NULL)
|
| {
|
| if((ret = i2c_master_send(client , addr , 2)) < 0) return ret; // select register
|
| mdelay(1); // for setup tx transaction.
|
| }
|
| if((ret = i2c_master_recv(client , values , length)) < 0) return ret;
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return length;
|
| }
|
|
|
| inline s32 ts_write_firmware_data(struct i2c_client *client, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| if((ret = i2c_master_send(client , values , length)) < 0)
|
| {
|
|
|
| return ret;
|
| }
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return length;
|
| }
|
| #else
|
| inline s32 ts_read_firmware_data(struct i2c_client *client, u8 reg, u8 *values, u16 length)
|
| {
|
| s32 ret;
|
| if((ret = i2c_master_send(client , ® , 1)) < 0) return ret; // select register
|
| mdelay(1); // for setup tx transaction
|
| if((ret = i2c_master_recv(client , values , length)) < 0) return ret;
|
| udelay(DELAY_FOR_POST_TRANSCATION);
|
| return length;
|
| }
|
| #endif
|
|
|
| //==================================================================
|
|
|
|
|
| static int zinitix_touch_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id);
|
| static int zinitix_touch_remove(struct i2c_client *client);
|
| bool ts_init_touch(zinitix_touch_dev* touch_dev);
|
| static void zinitix_clear_report_data(zinitix_touch_dev *touch_dev);
|
|
|
|
|
|
|
| #if (TOUCH_MODE == 1)
|
| static void zinitix_report_data(zinitix_touch_dev *touch_dev, int id);
|
| #endif
|
|
|
| #ifdef CONFIG_HAS_EARLYSUSPEND
|
| static void zinitix_early_suspend(struct early_suspend *h);
|
| static void zinitix_late_resume(struct early_suspend *h);
|
| #endif
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| static void ts_esd_timer_start(u16 sec, zinitix_touch_dev* touch_dev);
|
| static void ts_esd_timer_stop(zinitix_touch_dev* touch_dev);
|
| static void ts_esd_timer_init(zinitix_touch_dev* touch_dev);
|
| static void ts_esd_timeout_handler(unsigned long data);
|
| #endif
|
|
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| #if 0 //LINUX_VERSION_CODE < KERNEL_VERSION(2.6.36)
|
| static int ts_misc_fops_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg);
|
| #else
|
| static long ts_misc_fops_ioctl(struct file *filp,unsigned int cmd, unsigned long arg);
|
| #endif
|
| static int ts_misc_fops_open(struct inode *inode, struct file *filp);
|
| static int ts_misc_fops_close(struct inode *inode, struct file *filp);
|
|
|
| static struct file_operations ts_misc_fops = {
|
| .owner = THIS_MODULE,
|
| .open = ts_misc_fops_open,
|
| .release = ts_misc_fops_close,
|
| #if 0//LINUX_VERSION_CODE < KERNEL_VERSION(2.6.36)
|
| .ioctl = ts_misc_fops_ioctl,
|
| #else
|
| .unlocked_ioctl = ts_misc_fops_ioctl,
|
| #endif
|
| };
|
|
|
| static struct miscdevice touch_misc_device = {
|
| .minor = MISC_DYNAMIC_MINOR,
|
| .name = "zinitix_touch_misc",
|
| .fops = &ts_misc_fops,
|
| };
|
|
|
| #define TOUCH_IOCTL_BASE 0xbc
|
| #define TOUCH_IOCTL_GET_DEBUGMSG_STATE _IOW(TOUCH_IOCTL_BASE,0,int)
|
| #define TOUCH_IOCTL_SET_DEBUGMSG_STATE _IOW(TOUCH_IOCTL_BASE,1,int)
|
| #define TOUCH_IOCTL_GET_CHIP_REVISION _IOW(TOUCH_IOCTL_BASE,2,int)
|
| #define TOUCH_IOCTL_GET_FW_VERSION _IOW(TOUCH_IOCTL_BASE,3,int)
|
| #define TOUCH_IOCTL_GET_REG_DATA_VERSION _IOW(TOUCH_IOCTL_BASE,4,int)
|
| #define TOUCH_IOCTL_VARIFY_UPGRADE_SIZE _IOW(TOUCH_IOCTL_BASE,5,int)
|
| #define TOUCH_IOCTL_VARIFY_UPGRADE_DATA _IOW(TOUCH_IOCTL_BASE,6,int)
|
| #define TOUCH_IOCTL_START_UPGRADE _IOW(TOUCH_IOCTL_BASE,7,int)
|
| #define TOUCH_IOCTL_GET_X_NODE_NUM _IOW(TOUCH_IOCTL_BASE,8,int)
|
| #define TOUCH_IOCTL_GET_Y_NODE_NUM _IOW(TOUCH_IOCTL_BASE,9,int)
|
| #define TOUCH_IOCTL_GET_TOTAL_NODE_NUM _IOW(TOUCH_IOCTL_BASE,10,int)
|
| #define TOUCH_IOCTL_SET_RAW_DATA_MODE _IOW(TOUCH_IOCTL_BASE,11,int)
|
| #define TOUCH_IOCTL_GET_RAW_DATA _IOW(TOUCH_IOCTL_BASE,12,int)
|
| #define TOUCH_IOCTL_GET_X_RESOLUTION _IOW(TOUCH_IOCTL_BASE,13,int)
|
| #define TOUCH_IOCTL_GET_Y_RESOLUTION _IOW(TOUCH_IOCTL_BASE,14,int)
|
| #define TOUCH_IOCTL_HW_CALIBRAION _IOW(TOUCH_IOCTL_BASE,15,int)
|
| #define TOUCH_IOCTL_GET_REG _IOW(TOUCH_IOCTL_BASE,16,int)
|
| #define TOUCH_IOCTL_SET_REG _IOW(TOUCH_IOCTL_BASE,17,int)
|
| #define TOUCH_IOCTL_SEND_SAVE_STATUS _IOW(TOUCH_IOCTL_BASE,18,int)
|
| #define TOUCH_IOCTL_DONOT_TOUCH_EVENT _IOW(TOUCH_IOCTL_BASE,19,int)
|
|
|
|
|
| zinitix_touch_dev* misc_touch_dev;
|
|
|
| #endif //USE_TEST_RAW_TH_DATA_MODE
|
|
|
| #ifdef SEC_DRIVER
|
| int touch_power_onoff( int onoff );
|
| void init_hw(void);
|
| #endif
|
|
|
| // id -> include/linux/i2c-id.h
|
| static struct i2c_driver zinitix_touch_driver = {
|
| .probe = zinitix_touch_probe,
|
| .remove = zinitix_touch_remove,
|
| .id_table = zinitix_idtable,
|
| .driver = {
|
| .name = ZINITIX_DRIVER_NAME,
|
| },
|
| };
|
|
|
| #ifdef KEY_LED_CONTROL
|
| static struct timer_list g_led_timer;
|
| static bool key_led_on = false;
|
|
|
| static void vled_power_onoff(int onoff)
|
| {
|
| if(onoff)
|
| {
|
| if(!key_led_on)
|
| {
|
| gpio_direction_output(TSP_KEY_LED, 1);
|
| key_led_on = true;
|
| }
|
| }
|
| else
|
| {
|
| gpio_direction_output(TSP_KEY_LED, 0);
|
| key_led_on = false;
|
| }
|
| }
|
|
|
| static void TouchKey_Led_TimerProc(void)
|
| {
|
| vled_power_onoff(0);
|
| key_led_on = false;
|
| }
|
|
|
|
|
| static ssize_t touch_led_control(struct device *dev,
|
| struct device_attribute *attr, const char *buf,
|
| size_t size)
|
| {
|
| unsigned char data;
|
| int int_data;
|
| int errnum;
|
| printk("[TSP] touch_led_control start\n");
|
|
|
| if (sscanf(buf, "%c\n", &data) == 1) {
|
| // int_data = atoi(&data);
|
| // data = data *0x10;
|
| printk(KERN_DEBUG "[TSP] touch_led_control data: %d\n", data);
|
| if(data==50){ vled_power_onoff(1);}
|
| else if(data==48){ vled_power_onoff(0);}
|
|
|
|
|
| } else
|
| printk("[TSP] touch_led_control Error\n");
|
|
|
| return size;
|
| }
|
|
|
|
|
| #endif
|
|
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| static bool ts_get_raw_data(zinitix_touch_dev* touch_dev)
|
| {
|
| down(&touch_dev->raw_data_lock);
|
| if(touch_dev->raw_mode_flag == TOUCH_TEST_RAW_MODE)
|
| {
|
| #if BT4x2_Series
|
| if(touch_dev->cap_info.total_node_num*2 + MAX_TEST_POINT_INFO*2 < 512)
|
| {
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_RAWDATA_REG,(char *)touch_dev->cur_data, (unsigned int)((unsigned int)touch_dev->cap_info.total_node_num*2 + MAX_TEST_POINT_INFO*2))<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| }
|
| else
|
| {
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_RAWDATA_REG,(char *)&touch_dev->cur_data[0], 512)<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| udelay(50);
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_EXTRA_RAWDATA_REG,(char *)&touch_dev->cur_data[256], (unsigned int)((unsigned int)touch_dev->cap_info.total_node_num*2 + MAX_TEST_POINT_INFO*2)-512)<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| }
|
| #endif
|
|
|
| #if BT4x3_Above_Series
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_RAWDATA_REG,(char *)touch_dev->cur_data, (unsigned int)((unsigned int)touch_dev->cap_info.total_node_num*2 + MAX_TEST_POINT_INFO*2))<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| #endif
|
| if(!zinitix_bit_test(touch_dev->cur_data[touch_dev->cap_info.total_node_num], BIT_ICON_EVENT) &&
|
| !zinitix_bit_test(touch_dev->cur_data[touch_dev->cap_info.total_node_num], BIT_PT_EXIST)) // no point, so update ref_data
|
| {
|
| memcpy((u8*)touch_dev->ref_data, (u8*)touch_dev->cur_data, touch_dev->cap_info.total_node_num*2);
|
| }
|
| touch_dev->update = 1;
|
| memcpy((u8*)(&touch_dev->touch_info), (u8*)&touch_dev->cur_data[touch_dev->cap_info.total_node_num], sizeof(_ts_zinitix_point_info));
|
| up(&touch_dev->raw_data_lock);
|
| return true;
|
| }
|
| else if(touch_dev->raw_mode_flag != TOUCH_NORMAL_MODE)
|
| {
|
| zinitix_debug_msg("read raw data\r\n");
|
|
|
| #if BT4x2_Series
|
| if(touch_dev->raw_mode_flag == TOUCH_ZINITIX_CAL_N_MODE)
|
| {
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_RAWDATA_REG,(char *)touch_dev->cur_data,
|
| (unsigned int)((unsigned int)161*2 + sizeof(_ts_zinitix_point_info)))<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| misc_touch_dev->update = 1;
|
| memcpy((u8*)(&touch_dev->touch_info), (u8*)&touch_dev->cur_data[161], sizeof(_ts_zinitix_point_info));
|
| up(&touch_dev->raw_data_lock);
|
| return true;
|
| }
|
| if((unsigned int)((unsigned int)touch_dev->cap_info.total_node_num*2 + sizeof(_ts_zinitix_point_info)) < 512)
|
| {
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_RAWDATA_REG,(char *)touch_dev->cur_data,
|
| (unsigned int)((unsigned int)touch_dev->cap_info.total_node_num*2 + sizeof(_ts_zinitix_point_info)))<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| }
|
| else
|
| {
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_RAWDATA_REG,(char *)&touch_dev->cur_data[0], 512)<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| udelay(50);
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_EXTRA_RAWDATA_REG,(char *)&touch_dev->cur_data[256],
|
| (unsigned int)((unsigned int)touch_dev->cap_info.total_node_num*2 + sizeof(_ts_zinitix_point_info))-512)<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| }
|
| #endif
|
| #if BT4x3_Above_Series
|
| if(touch_dev->raw_mode_flag == TOUCH_ZINITIX_CAL_N_MODE)
|
| {
|
| int total_cal_n = touch_dev->cap_info.total_cal_n;
|
| if(total_cal_n == 0) total_cal_n = MAX_TEST_RAW_DATA;
|
|
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_RAWDATA_REG,(char *)touch_dev->cur_data,
|
| (unsigned int)((unsigned int)total_cal_n*2 + sizeof(_ts_zinitix_point_info)))<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| misc_touch_dev->update = 1;
|
| memcpy((u8*)(&touch_dev->touch_info), (u8*)&touch_dev->cur_data[total_cal_n], sizeof(_ts_zinitix_point_info));
|
| up(&touch_dev->raw_data_lock);
|
| return true;
|
| }
|
|
|
| if(ts_read_raw_data(touch_dev->client,ZINITIX_RAWDATA_REG,(char *)touch_dev->cur_data,
|
| (unsigned int)((unsigned int)touch_dev->cap_info.total_node_num*2 + sizeof(_ts_zinitix_point_info)))<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc raw data\n");
|
| up(&touch_dev->raw_data_lock);
|
| return false;
|
| }
|
| #endif
|
| if(!zinitix_bit_test(touch_dev->cur_data[touch_dev->cap_info.total_node_num], BIT_ICON_EVENT) &&
|
| !zinitix_bit_test(touch_dev->cur_data[touch_dev->cap_info.total_node_num], BIT_PT_EXIST)) // no point, so update ref_data
|
| {
|
| memcpy((u8*)touch_dev->ref_data, (u8*)touch_dev->cur_data, touch_dev->cap_info.total_node_num*2);
|
| }
|
| touch_dev->update = 1;
|
| memcpy((u8*)(&touch_dev->touch_info), (u8*)&touch_dev->cur_data[touch_dev->cap_info.total_node_num], sizeof(_ts_zinitix_point_info));
|
| }
|
| up(&touch_dev->raw_data_lock);
|
| return true;
|
| }
|
| #endif
|
|
|
|
|
| static bool ts_get_samples (zinitix_touch_dev* touch_dev)
|
| {
|
| int i;
|
|
|
| zinitix_debug_msg("ts_get_samples+\r\n");
|
|
|
| if (gpio_get_value(touch_dev->int_gpio_num))
|
| {
|
| //interrupt pin is high, not valid data.
|
| zinitix_debug_msg("woops... inturrpt pin is high\r\n");
|
| return false;
|
| }
|
|
|
|
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| if(touch_dev->raw_mode_flag != TOUCH_NORMAL_MODE)
|
| {
|
| if(ts_get_raw_data(touch_dev) == false) return false;
|
|
|
| #if (TOUCH_MODE == 0)
|
| goto continue_check_point_data;
|
| #endif
|
| }
|
| #endif
|
|
|
| #if (TOUCH_MODE == 1)
|
|
|
| memset(&touch_dev->touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
|
|
| if (ts_read_data (touch_dev->client, ZINITIX_POINT_STATUS_REG, (u8*)(&touch_dev->touch_info), 4)< 0)
|
| {
|
| zinitix_debug_msg("error read point info using i2c.-\r\n");
|
| return false;
|
| }
|
| zinitix_debug_msg("status reg = 0x%x , event_flag = 0x%04x\r\n", touch_dev->touch_info.status, touch_dev->touch_info.event_flag);
|
|
|
| if(touch_dev->touch_info.status == 0x0)
|
| {
|
| zinitix_debug_msg("periodical esd repeated int occured\r\n");
|
| return true;
|
| }
|
|
|
| if(zinitix_bit_test(touch_dev->touch_info.status, BIT_ICON_EVENT))
|
| {
|
| udelay(20);
|
| if (ts_read_data (touch_dev->client, ZINITIX_ICON_STATUS_REG, (u8*)(&touch_dev->icon_event_reg), 2) < 0)
|
| {
|
| printk(KERN_INFO "[TSP] error read icon info using i2c.\n");
|
| return false;
|
| }
|
| return true;
|
| }
|
|
|
| if(!zinitix_bit_test(touch_dev->touch_info.status, BIT_PT_EXIST))
|
| {
|
| //ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| for(i=0; i < touch_dev->cap_info.multi_fingers; i++)
|
| {
|
| if(zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_EXIST))
|
| {
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->reported_touch_info.coord[i].x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->reported_touch_info.coord[i].y);
|
| input_mt_sync(touch_dev->input_dev);
|
| touch_dev->reported_touch_info.coord[i].sub_status = 0;
|
| }
|
| }
|
|
|
| printk(KERN_INFO "x = %d, y = %d\n",touch_dev->reported_touch_info.coord[i].x, touch_dev->reported_touch_info.coord[i].y);
|
| input_sync(touch_dev->input_dev);
|
| return true;
|
| }
|
|
|
|
|
| for(i=0; i < touch_dev->cap_info.multi_fingers; i++)
|
| {
|
| if(zinitix_bit_test(touch_dev->touch_info.event_flag, i))
|
| {
|
| udelay(20);
|
| if (ts_read_data (touch_dev->client, ZINITIX_POINT_STATUS_REG+2+i, (u8*)(&touch_dev->touch_info.coord[i]), sizeof(_ts_zinitix_coord))< 0)
|
| {
|
| zinitix_debug_msg("error read point info using i2c.-\r\n");
|
| return false;
|
| }
|
| zinitix_bit_clr(touch_dev->touch_info.event_flag, i);
|
| if(touch_dev->touch_info.event_flag == 0)
|
| {
|
| //ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| zinitix_report_data(touch_dev, i);
|
| return true;
|
| }
|
| else
|
| zinitix_report_data(touch_dev, i);
|
| }
|
| }
|
|
|
|
|
| #else
|
| if (ts_read_data (touch_dev->client, ZINITIX_POINT_STATUS_REG, (u8*)(&touch_dev->touch_info), sizeof(_ts_zinitix_point_info))< 0)
|
| {
|
| zinitix_debug_msg("error read point info using i2c.-\r\n");
|
| return false;
|
| }
|
|
|
| continue_check_point_data:
|
| zinitix_debug_msg("status reg = 0x%x , point cnt = %d, time stamp = %d\r\n", touch_dev->touch_info.status,
|
| touch_dev->touch_info.finger_cnt, touch_dev->touch_info.time_stamp);
|
|
|
| if(touch_dev->touch_info.status == 0x0 && touch_dev->touch_info.finger_cnt == 100)
|
| {
|
| zinitix_debug_msg("periodical esd repeated int occured\r\n");
|
| return true;
|
| }
|
|
|
| for(i=0; i< MAX_SUPPORTED_BUTTON_NUM; i++) touch_dev->button[i] = ICON_BUTTON_UNCHANGE;
|
|
|
| if(zinitix_bit_test(touch_dev->touch_info.status, BIT_ICON_EVENT))
|
| {
|
| udelay(20);
|
| if (ts_read_data (touch_dev->client, ZINITIX_ICON_STATUS_REG, (u8*)(&touch_dev->icon_event_reg), 2) < 0)
|
| {
|
| printk(KERN_INFO "[TSP] error read icon info using i2c.\n");
|
| return false;
|
| }
|
| }
|
| #endif
|
| zinitix_debug_msg("ts_get_samples-\r\n");
|
|
|
| return true;
|
| }
|
|
|
|
|
|
|
| static bool ts_read_coord (zinitix_touch_dev * hDevice)
|
| {
|
| zinitix_touch_dev* touch_dev = (zinitix_touch_dev*)hDevice;
|
| //zinitix_debug_msg("ts_read_coord+\r\n");
|
|
|
| if(ts_get_samples(touch_dev)==false)
|
| {
|
| return false;
|
| }
|
|
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| #if DELAY_FOR_SIGNAL_DELAY
|
| udelay(DELAY_FOR_SIGNAL_DELAY);
|
| #endif
|
| return true;
|
| }
|
|
|
| //
|
| #if 0 //Comment out this function for compile warning
|
| static void ts_power_control(zinitix_touch_dev *touch_dev, u8 ctl)
|
| {
|
| if(ctl == POWER_OFF) //power off
|
| {
|
| }
|
| else if(ctl == POWER_ON) //power on
|
| {
|
| }
|
| else if(ctl == RESET_LOW) //reset pin low
|
| {
|
| #if RESET_CONTROL
|
| if(gpio_is_valid(touch_dev->reset_gpio_num))
|
| {
|
| printk(KERN_INFO "[TSP] reset pin low\r\n");
|
| // gpio_direction_output(touch_dev->reset_gpio_num, 0);
|
| gpio_set_value(touch_dev->reset_gpio_num, 0);
|
| }
|
| else
|
| printk(KERN_INFO "[TSP] error : zinitix reset pin gpio is invalid\r\n");
|
| #endif
|
| }
|
| else if(ctl == RESET_HIGH) //reset pin high
|
| {
|
| #if RESET_CONTROL
|
| if(gpio_is_valid(touch_dev->reset_gpio_num))
|
| {
|
| printk(KERN_INFO "[TSP] reset pin high\r\n");
|
| // gpio_direction_output(touch_dev->reset_gpio_num, 1);
|
| gpio_set_value(touch_dev->reset_gpio_num, 1);
|
| }
|
| else
|
| printk(KERN_INFO "[TSP] error : zinitix reset pin gpio is invalid\r\n");
|
| #endif
|
| }
|
|
|
|
|
| }
|
| #endif
|
| static bool ts_mini_init_touch(zinitix_touch_dev * touch_dev)
|
| {
|
| if(touch_dev == NULL)
|
| {
|
| printk(KERN_INFO "[TSP] ts_mini_init_touch : error (touch_dev == NULL?)\r\n");
|
| return false;
|
| }
|
|
|
| ts_init_touch(touch_dev);
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(touch_dev->use_esd_timer)
|
| {
|
| ts_esd_timer_start(ZINITIX_CHECK_ESD_TIMER, touch_dev);
|
| zinitix_debug_msg("esd timer start\r\n");
|
| }
|
| #endif
|
|
|
| return true;
|
| }
|
|
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
|
|
| static void zinitix_touch_tmr_work(struct work_struct *work)
|
| {
|
| zinitix_touch_dev *touch_dev = container_of(work, zinitix_touch_dev, tmr_work);
|
|
|
| printk(KERN_INFO "[TSP] tmr queue work ++\r\n");
|
| if(touch_dev == NULL)
|
| {
|
| printk(KERN_INFO "[TSP] touch dev == NULL ?\r\n");
|
| goto fail_time_out_init;
|
| }
|
| down(&touch_dev->work_proceedure_lock);
|
| if(touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| printk(KERN_INFO "[TSP] other process occupied (%d)\r\n", touch_dev->work_proceedure);
|
| up(&touch_dev->work_proceedure_lock);
|
| return;
|
| }
|
| touch_dev->work_proceedure = TS_ESD_TIMER_WORK;
|
|
|
| disable_irq(touch_dev->irq);
|
| printk(KERN_INFO "[TSP] error. timeout occured. maybe ts device dead. so reset & reinit.\r\n");
|
| mdelay(CHIP_POWER_OFF_DELAY);
|
| // ts_power_control(touch_dev, RESET_LOW); //reset pin low
|
| // ts_power_control (touch_dev, POWER_OFF); //power off
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(1000);
|
| // ts_power_control (touch_dev, POWER_ON); //power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1); //PSJ
|
| //ts_power_control(touch_dev, RESET_HIGH); //reset pin high
|
| mdelay(CHIP_ON_DELAY);
|
| zinitix_debug_msg("clear all reported points\r\n");
|
| zinitix_clear_report_data(touch_dev);
|
| if(ts_mini_init_touch(touch_dev) == false)
|
| goto fail_time_out_init;
|
|
|
| touch_dev->work_proceedure = TS_NO_WORK;
|
| enable_irq(touch_dev->irq);
|
| up(&touch_dev->work_proceedure_lock);
|
| printk(KERN_INFO "[TSP] tmr queue work ----\r\n");
|
| return;
|
| fail_time_out_init:
|
| printk(KERN_INFO "[TSP] tmr work : restart error\r\n");
|
| ts_esd_timer_start(ZINITIX_CHECK_ESD_TIMER, touch_dev);
|
| touch_dev->work_proceedure = TS_NO_WORK;
|
| enable_irq(touch_dev->irq);
|
| up(&touch_dev->work_proceedure_lock);
|
| }
|
|
|
| static void ts_esd_timer_start(u16 sec, zinitix_touch_dev* touch_dev)
|
| {
|
| zinitix_debug_msg(KERN_INFO "ts_esd_timer_start\r\n");
|
|
|
| if(touch_dev->p_esd_timeout_tmr != NULL) del_timer(touch_dev->p_esd_timeout_tmr);
|
| touch_dev->p_esd_timeout_tmr = NULL;
|
|
|
| init_timer(&(touch_dev->esd_timeout_tmr));
|
| touch_dev->esd_timeout_tmr.data = (unsigned long)(touch_dev);
|
| touch_dev->esd_timeout_tmr.function = ts_esd_timeout_handler;
|
| touch_dev->esd_timeout_tmr.expires = jiffies + HZ*sec;
|
| touch_dev->p_esd_timeout_tmr = &touch_dev->esd_timeout_tmr;
|
| add_timer(&touch_dev->esd_timeout_tmr);
|
| }
|
|
|
| static void ts_esd_timer_stop(zinitix_touch_dev* touch_dev)
|
| {
|
| if(touch_dev->p_esd_timeout_tmr) del_timer(touch_dev->p_esd_timeout_tmr);
|
| touch_dev->p_esd_timeout_tmr = NULL;
|
| }
|
|
|
| //static void ts_esd_timer_modify(u16 sec, zinitix_touch_dev* touch_dev)
|
| //{
|
| // mod_timer(&touch_dev->esd_timeout_tmr, jiffies + (HZ*sec));
|
| //}
|
|
|
| static void ts_esd_timer_init(zinitix_touch_dev* touch_dev)
|
| {
|
| init_timer(&(touch_dev->esd_timeout_tmr));
|
| touch_dev->esd_timeout_tmr.data = (unsigned long)(touch_dev);
|
| touch_dev->esd_timeout_tmr.function = ts_esd_timeout_handler;
|
| touch_dev->p_esd_timeout_tmr=NULL;
|
| }
|
|
|
| static void ts_esd_timeout_handler(unsigned long data)
|
| {
|
| zinitix_touch_dev* touch_dev = (zinitix_touch_dev*)data;
|
| touch_dev->p_esd_timeout_tmr=NULL;
|
| queue_work(zinitix_tmr_workqueue, &touch_dev->tmr_work);
|
| }
|
| #endif
|
|
|
|
|
| bool ts_check_need_upgrade(u16 curVersion, u16 curRegVersion)
|
| {
|
| u16 newVersion, phoneVersion,swVersion;
|
|
|
| newVersion = (u16) (m_firmware_data[0] | (m_firmware_data[1]<<8));
|
| if (ts_read_data(global_touch_dev->client, ZINITIX_DATA_VERSION_REG, (u8*)&phoneVersion, 2)<0);
|
| swVersion = (u16) (m_firmware_data[FIRMWARE_VERSION_POS+2] | (m_firmware_data[FIRMWARE_VERSION_POS+3]<<8));
|
|
|
| // printk(KERN_INFO "[TSP] cur Version = 0x%x, new Version = 0x%x\n", curVersion, newVersion);
|
| printk(KERN_INFO "[TSP] phone Version = %d, sw Version = %d\n", phoneVersion, swVersion);
|
|
|
| // if(phoneVersion != swVersion) return true;
|
| // else return false;
|
| if(phoneVersion < swVersion) return true;
|
| else return false;
|
|
|
| // if(curVersion < newVersion) return true;
|
| // else if(curVersion > newVersion) return false;
|
|
|
| #if BT4x2_Series
|
| if(m_firmware_data[0x3FFE] == 0xff && m_firmware_data[0x3FFF] == 0xff) return false;
|
| newVersion = (u16) (m_firmware_data[0x3FFE] | (m_firmware_data[0x3FFF]<<8));
|
|
|
| #endif
|
|
|
| #if BT4x3_Above_Series
|
| if(m_firmware_data[FIRMWARE_VERSION_POS+2] == 0xff && m_firmware_data[FIRMWARE_VERSION_POS+3] == 0xff) return false;
|
| newVersion = (u16) (m_firmware_data[FIRMWARE_VERSION_POS+2] | (m_firmware_data[FIRMWARE_VERSION_POS+3]<<8)); // register data version
|
| #endif
|
|
|
|
|
| if(curRegVersion < newVersion) return true;
|
|
|
| return false;
|
| }
|
|
|
|
|
| #define TC_PAGE_SZ 64
|
| #define TC_SECTOR_SZ 8
|
|
|
| u8 ts_upgrade_firmware(zinitix_touch_dev* touch_dev, const u8 *firmware_data, u32 size)
|
| {
|
| u16 flash_addr;
|
| u8 * verify_data;
|
| int retry_cnt = 0;
|
| #if (TOUCH_USING_ISP_METHOD==0 && BT4x2_Series == 1)
|
| u32 i;
|
| #endif
|
| u8 i2c_buffer[TC_PAGE_SZ+2];
|
|
|
|
|
|
|
| verify_data = (u8*)kzalloc(size, GFP_KERNEL);
|
| if(verify_data == NULL)
|
| {
|
| printk(KERN_ERR "[TSP] cannot alloc verify buffer\n");
|
| return false;
|
| }
|
|
|
| #if (TOUCH_USING_ISP_METHOD==0 && BT4x2_Series == 1)
|
| do{
|
| printk(KERN_INFO "[TSP] reset command\n");
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SWRESET_CMD)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[TSP] failed to reset\n");
|
| goto fail_upgrade;
|
| }
|
|
|
| #if USE_HW_CALIBRATION
|
| printk(KERN_INFO "[TSP] Erase Flash\n");
|
| if (ts_write_reg(touch_dev->client, ZINITIX_ERASE_FLASH, 0xaaaa)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[TSP] failed to erase flash\n");
|
| goto fail_upgrade;
|
| }
|
|
|
| mdelay(500);
|
| #else
|
| if (ts_write_reg(touch_dev->client, ZINITIX_TOUCH_MODE, 0x06)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[TSP] failed to erase flash\n");
|
| goto fail_upgrade;
|
| }
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| mdelay(10);
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| mdelay(10);
|
| #endif
|
|
|
| printk(KERN_INFO "[TSP] writing firmware data\n");
|
|
|
| for(flash_addr= 0; flash_addr< size; )
|
| {
|
|
|
| for(i=0; i< TC_PAGE_SZ/TC_SECTOR_SZ; i++)
|
| {
|
| zinitix_debug_msg("firmware write : addr = %04x, len = %d\n", flash_addr, TC_SECTOR_SZ);
|
| if(ts_write_data(touch_dev->client,ZINITIX_WRITE_FLASH, &firmware_data[flash_addr],TC_SECTOR_SZ)<0)
|
| {
|
| printk(KERN_INFO"[TSP] error : write zinitix tc firmare\n");
|
| goto fail_upgrade;
|
| }
|
| flash_addr+= TC_SECTOR_SZ;
|
| udelay(100);
|
| }
|
| mdelay(20);
|
| #if !USE_HW_CALIBRATION
|
| if(flash_addr >= CALIBRATION_AREA) break;
|
| #endif
|
| }
|
|
|
| printk(KERN_INFO "[TSP] read firmware data\n");
|
| for(flash_addr= 0; flash_addr< size; )
|
| {
|
|
|
| for(i=0; i< TC_PAGE_SZ/TC_SECTOR_SZ; i++)
|
| {
|
| zinitix_debug_msg( "firmware read : addr = %04x, len = %d\n", flash_addr, TC_SECTOR_SZ);
|
| if(ts_read_firmware_data(touch_dev->client,ZINITIX_READ_FLASH,&verify_data[flash_addr],TC_SECTOR_SZ)<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc firmare\n");
|
| goto fail_upgrade;
|
| }
|
| flash_addr+= TC_SECTOR_SZ;
|
| }
|
| #if !USE_HW_CALIBRATION
|
| if(flash_addr >= CALIBRATION_AREA)
|
| {
|
| memcpy((u8*)&verify_data[CALIBRATION_AREA], (u8*)&firmware_data[CALIBRATION_AREA], size-CALIBRATION_AREA);
|
| break;
|
| }
|
| #endif
|
| }
|
| // verify
|
| printk(KERN_INFO "[TSP] verify firmware data\n");
|
| if(memcmp((u8*)&firmware_data[0], (u8*)&verify_data[0], size) == 0)
|
| {
|
| printk(KERN_INFO "[TSP] upgrade finished\n");
|
| kfree(verify_data);
|
| // ts_power_control(touch_dev, RESET_LOW); //reset pin low
|
| // ts_power_control(touch_dev, POWER_OFF); //power off
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(1000);
|
| // ts_power_control(touch_dev, POWER_ON); //power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1); //PSJ
|
| // ts_power_control(touch_dev, RESET_HIGH); //reset pin high
|
| mdelay(CHIP_ON_DELAY);
|
| return true;
|
| }
|
| printk(KERN_INFO "[TSP] upgrade fail : so retry... (%d)\n", ++retry_cnt);
|
|
|
| if(retry_cnt >= ZINITIX_INIT_RETRY_CNT)
|
| goto fail_upgrade;
|
|
|
| }while(1);
|
|
|
|
|
| #elif (TOUCH_USING_ISP_METHOD==1) // isp
|
|
|
|
|
| if(m_isp_client == NULL)
|
| {
|
| printk(KERN_ERR "[TSP] i2c client for isp is not register \r\n");
|
| return false;
|
| }
|
|
|
| retry_isp_firmware_upgrade:
|
|
|
| #if BT4x2_Series
|
| //must be reset pin low
|
| //+++++++++++++++++++++++++++++++++++++++++++++++++++++
|
| ts_power_control(touch_dev, RESET_LOW); //reset pin low
|
| //+++++++++++++++++++++++++++++++++++++++++++++++++++++
|
| mdelay(100);
|
| #endif
|
|
|
| #if BT4x3_Above_Series
|
| // ts_power_control(touch_dev, RESET_LOW); //reset pin low
|
| // ts_power_control(touch_dev, POWER_OFF); //power off
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(1000);
|
| // ts_power_control(touch_dev, POWER_ON); //power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1); //PSJ
|
| // ts_power_control(touch_dev, RESET_HIGH); //reset pin high
|
| udelay(1000); // under 1ms
|
| #endif
|
| printk(KERN_INFO "[TSP] write firmware data\n");
|
|
|
| for(flash_addr= 0; flash_addr< size; flash_addr+=TC_PAGE_SZ)
|
| {
|
|
|
| #if !USE_HW_CALIBRATION
|
| if(flash_addr >= CALIBRATION_AREA*2) break;
|
| #endif
|
| // printk(KERN_INFO "[TSP] .");
|
| // zinitix_debug_msg("firmware write : addr = %04x, len = %d\n", flash_addr, TC_PAGE_SZ);
|
|
|
| i2c_buffer[0] = (flash_addr>>8)&0xff; //addr_h
|
| i2c_buffer[1] = (flash_addr)&0xff; //addr_l
|
| memcpy(&i2c_buffer[2], &firmware_data[flash_addr], TC_PAGE_SZ);
|
| // printk( "[TSP] flash_addr = %x i2c_buffer = %x : %x\n",flash_addr, i2c_buffer[0],i2c_buffer[1]);
|
|
|
| if(ts_write_firmware_data(m_isp_client, i2c_buffer, TC_PAGE_SZ+2)<0)
|
| {
|
| printk(KERN_INFO"[TSP] error : write zinitix tc firmare\n");
|
| goto fail_upgrade;
|
| }
|
| mdelay(20);
|
| }
|
| mdelay(CHIP_POWER_OFF_AF_FZ_DELAY);
|
|
|
| printk(KERN_INFO "\r\n[TSP] read firmware data\n");
|
|
|
| #if BT4x3_Above_Series
|
| flash_addr = 0;
|
| i2c_buffer[0] = (flash_addr>>8)&0xff; //addr_h
|
| i2c_buffer[1] = (flash_addr)&0xff; //addr_l
|
|
|
| #if !USE_HW_CALIBRATION
|
| size = CALIBRATION_AREA*2;
|
| #endif
|
|
|
| if(ts_read_firmware_data(m_isp_client, i2c_buffer,&verify_data[flash_addr], size)<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc firmare: addr = %04x, len = %d\n", flash_addr, size);
|
| goto fail_upgrade;
|
| }
|
| if(memcmp((u8*)&firmware_data[flash_addr], (u8*)&verify_data[flash_addr], size) != 0)
|
| {
|
| printk(KERN_INFO "[TSP] error : verify error : addr = %04x, len = %d\n", flash_addr, size);
|
| goto fail_upgrade;
|
| }
|
|
|
| #else //bt4x2
|
|
|
| for(flash_addr= 0; flash_addr< size; flash_addr+=TC_PAGE_SZ)
|
| {
|
| #if !USE_HW_CALIBRATION
|
| if(flash_addr >= CALIBRATION_AREA*2) break;
|
| #endif
|
| i2c_buffer[0] = (flash_addr>>8)&0xff; //addr_h
|
| i2c_buffer[1] = (flash_addr)&0xff; //addr_l
|
| zinitix_debug_msg("firmware read : addr = %04x, len = %d\n", flash_addr, TC_PAGE_SZ);
|
| if(ts_read_firmware_data(m_isp_client, i2c_buffer,&verify_data[flash_addr],TC_PAGE_SZ)<0)
|
| {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc firmare: addr = %04x, len = %d\n", flash_addr, TC_PAGE_SZ);
|
| goto fail_upgrade;
|
| }
|
| if(memcmp((u8*)&firmware_data[flash_addr], (u8*)&verify_data[flash_addr], TC_PAGE_SZ) != 0)
|
| {
|
| printk(KERN_INFO "[TSP] error : verify error : addr = %04x, len = %d\n", flash_addr, TC_PAGE_SZ);
|
| goto fail_upgrade;
|
| }
|
| udelay(500);
|
|
|
| }
|
| #endif
|
| // verify
|
| mdelay(CHIP_POWER_OFF_AF_FZ_DELAY);
|
| //ts_power_control(touch_dev, RESET_LOW); //reset pin low
|
| // ts_power_control(touch_dev, POWER_OFF); //power off
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(1000);
|
| // ts_power_control(touch_dev, POWER_ON); //power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1); //PSJ
|
| //ts_power_control(touch_dev, RESET_HIGH); //reset pin high
|
| mdelay(CHIP_ON_AF_FZ_DELAY);
|
| printk(KERN_INFO "[TSP] upgrade finished\n");
|
| kfree(verify_data);
|
| return true;
|
|
|
| #endif
|
|
|
| fail_upgrade:
|
| mdelay(CHIP_POWER_OFF_AF_FZ_DELAY);
|
| //ts_power_control(touch_dev, RESET_LOW); //reset pin low
|
| // ts_power_control(touch_dev, POWER_OFF); //power off
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(1000);
|
| // ts_power_control(touch_dev, POWER_ON); //power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1); //PSJ
|
| //ts_power_control(touch_dev, RESET_HIGH); //reset pin high
|
| mdelay(CHIP_ON_AF_FZ_DELAY);
|
|
|
| printk(KERN_INFO "[TSP] upgrade fail : so retry... (%d)\n", ++retry_cnt);
|
| if(retry_cnt >= ZINITIX_INIT_RETRY_CNT) goto retry_isp_firmware_upgrade;
|
|
|
| if(verify_data != NULL) kfree(verify_data);
|
| printk(KERN_INFO "[TSP] upgrade fail..\n");
|
| return false;
|
|
|
| }
|
|
|
| int gv_initCheck = 0;
|
|
|
| bool ts_init_touch(zinitix_touch_dev* touch_dev)
|
| {
|
| u16 reg_val;
|
| int i;
|
| u16 SetMaxX = SYSTEM_MAX_X_RESOLUTION; //Max Position range from 0x0002 to 0x1fff
|
| u16 SetMaxY = SYSTEM_MAX_Y_RESOLUTION; //Max Position range from 0x0002 to 0x1fff
|
| u16 chip_revision;
|
| u16 chip_firmware_version;
|
| u16 chip_reg_data_version;
|
| u16 chip_eeprom_info;
|
|
|
| int retry_cnt = 0;
|
|
|
|
|
| if(touch_dev == NULL)
|
| {
|
| printk(KERN_ERR "[TSP] error touch_dev == null?\r\n");
|
| return false;
|
| }
|
|
|
|
|
| retry_init:
|
|
|
| zinitix_debug_msg("disable interrupt\r\n");
|
|
|
| for(i=0; i<ZINITIX_INIT_RETRY_CNT; i++)
|
| {
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SWRESET_CMD)==I2C_SUCCESS) break;
|
| mdelay(10);
|
| }
|
|
|
| if(i==ZINITIX_INIT_RETRY_CNT)
|
| {
|
| printk(KERN_INFO "[TSP] fail to write interrupt register\r\n");
|
| goto fail_init;
|
| }
|
|
|
| #if USING_CHIP_SETTING
|
| if(ts_read_data(touch_dev->client, ZINITIX_INT_ENABLE_FLAG, (u8*)&touch_dev->cap_info.chip_int_mask, 2) < 0) goto fail_init;
|
| printk(KERN_INFO "[TSP] zinitix touch interrupt mask = %04x\r\n", touch_dev->cap_info.chip_int_mask);
|
| if(touch_dev->cap_info.chip_int_mask == 0 || touch_dev->cap_info.chip_int_mask == 0xffff) goto fail_init;
|
|
|
| #else
|
| touch_dev->cap_info.button_num = SUPPORTED_BUTTON_NUM;
|
|
|
| reg_val = 0;
|
| zinitix_bit_set(reg_val, BIT_PT_CNT_CHANGE);
|
| zinitix_bit_set(reg_val, BIT_DOWN);
|
| zinitix_bit_set(reg_val, BIT_MOVE);
|
| zinitix_bit_set(reg_val, BIT_UP);
|
| if(touch_dev->cap_info.button_num > 0) zinitix_bit_set(reg_val, BIT_ICON_EVENT);
|
| printk("[TSP] reg_val = %x , button_num = %d",reg_val, touch_dev->cap_info.button_num);
|
| touch_dev->cap_info.chip_int_mask = reg_val;
|
| #endif
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_INT_ENABLE_FLAG, 0x0) !=I2C_SUCCESS) goto fail_init;
|
|
|
| zinitix_debug_msg("send reset command\r\n");
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SWRESET_CMD)!=I2C_SUCCESS) goto fail_init;
|
|
|
| /* get chip revision id */
|
| if (ts_read_data(touch_dev->client, ZINITIX_CHIP_REVISION, (u8*)&chip_revision, 2)<0)
|
| {
|
| printk(KERN_INFO "[TSP] fail to read chip revision\r\n");
|
| goto fail_init;
|
| }
|
| printk(KERN_INFO "[TSP] zinitix touch chip revision id = %x\r\n", chip_revision);
|
|
|
| touch_dev->cap_info.chip_fw_size = 16*1024;
|
|
|
| #if BT4x3_Above_Series
|
| touch_dev->cap_info.chip_fw_size = 32*1024;
|
| #endif
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| if (ts_read_data(touch_dev->client, ZINITIX_TOTAL_NUMBER_OF_X, (u8*)&touch_dev->cap_info.x_node_num, 2)<0) goto fail_init;
|
| printk(KERN_INFO "[TSP] zinitix touch chip x node num = %d\r\n", touch_dev->cap_info.x_node_num);
|
| if (ts_read_data(touch_dev->client, ZINITIX_TOTAL_NUMBER_OF_Y, (u8*)&touch_dev->cap_info.y_node_num, 2)<0) goto fail_init;
|
| printk(KERN_INFO "[TSP] zinitix touch chip y node num = %d\r\n", touch_dev->cap_info.y_node_num);
|
|
|
| touch_dev->cap_info.total_node_num = touch_dev->cap_info.x_node_num*touch_dev->cap_info.y_node_num;
|
| printk(KERN_INFO "[TSP] zinitix touch chip total node num = %d\r\n", touch_dev->cap_info.total_node_num);
|
| #if BT4x3_Above_Series
|
| if (ts_read_data(touch_dev->client, ZINITIX_MAX_Y_NUM, (u8*)&touch_dev->cap_info.max_y_node, 2)<0) goto fail_init;
|
| printk(KERN_INFO "[TSP] zinitix touch chip max y node num = %d\r\n", touch_dev->cap_info.max_y_node);
|
|
|
| if (ts_read_data(touch_dev->client, ZINITIX_CAL_N_TOTAL_NUM, (u8*)&touch_dev->cap_info.total_cal_n, 2)<0) goto fail_init;
|
| printk(KERN_INFO "[TSP] zinitix touch chip total cal n data num = %d\r\n", touch_dev->cap_info.total_cal_n);
|
|
|
|
|
| #endif
|
| #endif
|
|
|
|
|
| /* get chip firmware version */
|
| if (ts_read_data(touch_dev->client, ZINITIX_FIRMWARE_VERSION, (u8*)&chip_firmware_version, 2)<0) goto fail_init;
|
| printk(KERN_INFO "[TSP] zinitix touch chip firmware version = %x\r\n", chip_firmware_version);
|
|
|
| #if 0 //TOUCH_ONESHOT_UPGRADE PSJ
|
| chip_reg_data_version = 0xffff;
|
|
|
| if (ts_read_data(touch_dev->client, ZINITIX_DATA_VERSION_REG, (u8*)&chip_reg_data_version, 2)<0) goto fail_init;
|
| zinitix_debug_msg("touch reg data version = %d\r\n", chip_reg_data_version);
|
|
|
| force_upgrade:
|
| printk(KERN_INFO "work_proceedure = %d\n", touch_dev->work_proceedure);
|
|
|
| if((touch_dev->work_proceedure != TS_IN_RESUME) && (touch_dev->work_proceedure != TS_IN_EALRY_SUSPEND))
|
| {
|
| if(IsfwUpdate || (ts_check_need_upgrade(chip_firmware_version, chip_reg_data_version)==true) || (retry_cnt>=ZINITIX_INIT_RETRY_CNT))
|
| {
|
| printk(KERN_INFO "[TSP] start upgrade firmware\n");
|
| IsfwUpdate = FWUP_NOW;
|
| ts_upgrade_firmware(touch_dev, &m_firmware_data[2], touch_dev->cap_info.chip_fw_size);
|
|
|
|
|
| /* get chip revision id */
|
| if (ts_read_data(touch_dev->client, ZINITIX_CHIP_REVISION, (u8*)&chip_revision, 2)<0)
|
| {
|
| printk(KERN_INFO "[TSP] fail to read chip revision\r\n");
|
| goto fail_init;
|
| }
|
| printk(KERN_INFO "[TSP] zinitix touch chip revision id = %x\r\n", chip_revision);
|
|
|
| /* get chip firmware version */
|
| if (ts_read_data(touch_dev->client, ZINITIX_FIRMWARE_VERSION, (u8*)&chip_firmware_version, 2)<0) goto fail_init;
|
| printk(KERN_INFO "[TSP] zinitix touch chip renewed firmware version = %x\r\n", chip_firmware_version);
|
|
|
| }
|
| }
|
| #endif
|
|
|
| if (ts_read_data(touch_dev->client, ZINITIX_DATA_VERSION_REG, (u8*)&chip_reg_data_version, 2)<0) goto fail_init;
|
| zinitix_debug_msg("touch reg data version = %d\r\n", chip_reg_data_version);
|
|
|
| #if 0 //TOUCH_ONESHOT_UPGRADE
|
| if(chip_reg_data_version < m_reg_data[ZINITIX_DATA_VERSION_REG].reg_val)
|
| {
|
| zinitix_debug_msg("write new reg data( %d < %d)\r\n", chip_reg_data_version, m_reg_data[ZINITIX_DATA_VERSION_REG].reg_val);
|
| for(i=0; i < MAX_REG_COUNT; i++)
|
| {
|
| if(m_reg_data[i].valid == 1)
|
| {
|
| if(ts_write_reg(touch_dev->client, (u16)i, (u16)(m_reg_data[i].reg_val))!=I2C_SUCCESS) goto fail_init;
|
| if(i == ZINITIX_TOTAL_NUMBER_OF_X || i == ZINITIX_TOTAL_NUMBER_OF_Y) mdelay(50); //for clear hw calibration bit
|
| if(ts_read_data(touch_dev->client, (u16)i, (u8*)&stmp, 2)<0) goto fail_init;
|
| if(memcmp((char*)&m_reg_data[i].reg_val, (char*)&stmp, 2)!=0) //if(m_reg_data[i].reg_val != stmp)
|
| printk(KERN_WARNING "[TSP] register data is different. (addr = 0x%02X , %d != %d)\r\n", i, m_reg_data[i].reg_val, stmp);
|
| }
|
| }
|
| zinitix_debug_msg("done new reg data( %d < %d)\r\n", chip_reg_data_version, m_reg_data[ZINITIX_DATA_VERSION_REG].reg_val);
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SAVE_STATUS_CMD)!=I2C_SUCCESS) goto fail_init;
|
| mdelay(1000); // for fusing eeprom
|
| }
|
|
|
| #endif
|
|
|
| if (ts_read_data(touch_dev->client, ZINITIX_EEPROM_INFO_REG, (u8*)&chip_eeprom_info, 2)<0) goto fail_init;
|
| zinitix_debug_msg("touch eeprom info = 0x%04X\r\n", chip_eeprom_info);
|
|
|
| #if USE_HW_CALIBRATION
|
| if(zinitix_bit_test(chip_eeprom_info, 0)) // hw calibration bit
|
| {
|
| if(touch_dev->cap_info.chip_int_mask !=0)
|
| {
|
| if (ts_write_reg(touch_dev->client, ZINITIX_INT_ENABLE_FLAG, touch_dev->cap_info.chip_int_mask)!=I2C_SUCCESS) goto fail_init;
|
| }
|
| // h/w calibration
|
| if (ts_write_reg(touch_dev->client, ZINITIX_TOUCH_MODE, 0x07)!=I2C_SUCCESS) goto fail_init;
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_CALIBRATE_CMD)!=I2C_SUCCESS) goto fail_init;
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SWRESET_CMD)!=I2C_SUCCESS) goto fail_init;
|
| mdelay(1);
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| mdelay(100);
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| mdelay(100);
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| // wait for h/w calibration
|
| do{
|
| mdelay(1000);
|
| if (ts_read_data(touch_dev->client, ZINITIX_EEPROM_INFO_REG, (u8*)&chip_eeprom_info, 2)<0) goto fail_init;
|
| zinitix_debug_msg("touch eeprom info = 0x%04X\r\n", chip_eeprom_info);
|
| if(!zinitix_bit_test(chip_eeprom_info, 0)) break;
|
| }while(1);
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_TOUCH_MODE, TOUCH_MODE)!=I2C_SUCCESS) goto fail_init;
|
| printk("[TSP] touch_dev->cap_info.chip_int_mask = %x",touch_dev->cap_info.chip_int_mask);
|
| mdelay(10);
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SWRESET_CMD)!=I2C_SUCCESS) goto fail_init;
|
| #if BT4x3_Above_Series
|
| mdelay(10);
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SAVE_CALIBRATION_CMD)!=I2C_SUCCESS) goto fail_init;
|
| mdelay(500);
|
| #endif
|
|
|
| //<----------------------------------------------------------
|
| #if BT4x2_Series
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SAVE_STATUS_CMD)!=I2C_SUCCESS) goto fail_init;
|
| mdelay(1000); // for fusing eeprom
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SWRESET_CMD)!=I2C_SUCCESS) goto fail_init;
|
| #endif
|
| //disable chip interrupt
|
| if (ts_write_reg(touch_dev->client, ZINITIX_INT_ENABLE_FLAG, 0)!=I2C_SUCCESS) goto fail_init;
|
|
|
| }
|
| #endif
|
|
|
| touch_dev->cap_info.chip_revision = (u16)chip_revision;
|
| touch_dev->cap_info.chip_firmware_version = (u16)chip_firmware_version;
|
| touch_dev->cap_info.chip_reg_data_version = (u16)chip_reg_data_version;
|
|
|
|
|
| /* initialize */
|
| if (ts_write_reg(touch_dev->client, ZINITIX_X_RESOLUTION, (u16)(SetMaxX))!=I2C_SUCCESS) goto fail_init;
|
| if (ts_write_reg(touch_dev->client, ZINITIX_Y_RESOLUTION, (u16)(SetMaxY))!=I2C_SUCCESS) goto fail_init;
|
|
|
| if (ts_read_data(touch_dev->client, ZINITIX_X_RESOLUTION, (u8*)&touch_dev->cap_info.x_resolution, 2)<0) goto fail_init;
|
| zinitix_debug_msg("touch max x = %d\r\n", touch_dev->cap_info.x_resolution);
|
| if (ts_read_data(touch_dev->client, ZINITIX_Y_RESOLUTION, (u8*)&touch_dev->cap_info.y_resolution, 2)<0) goto fail_init;
|
| zinitix_debug_msg("touch max y = %d\r\n", touch_dev->cap_info.y_resolution);
|
|
|
| touch_dev->cap_info.MinX = (u32)0;
|
| touch_dev->cap_info.MinY = (u32)0;
|
| touch_dev->cap_info.MaxX = (u32)touch_dev->cap_info.x_resolution;
|
| touch_dev->cap_info.MaxY = (u32)touch_dev->cap_info.y_resolution;
|
|
|
| #if USING_CHIP_SETTING
|
| if (ts_read_data(touch_dev->client, ZINITIX_BUTTON_SUPPORTED_NUM, (u8*)&touch_dev->cap_info.button_num, 2)<0) goto fail_init;
|
| zinitix_debug_msg("supported button num = %d\r\n", touch_dev->cap_info.button_num);
|
| if (ts_read_data(touch_dev->client, ZINITIX_SUPPORTED_FINGER_NUM, (u8*)&touch_dev->cap_info.multi_fingers, 2)<0) goto fail_init;
|
| zinitix_debug_msg("supported finger num = %d\r\n", touch_dev->cap_info.multi_fingers);
|
| #else // driver setting
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_SUPPORTED_FINGER_NUM, (u16)MAX_SUPPORTED_FINGER_NUM)!=I2C_SUCCESS) goto fail_init;
|
| touch_dev->cap_info.multi_fingers = REAL_SUPPORTED_FINGER_NUM;
|
| #endif
|
|
|
| zinitix_debug_msg("max supported finger num = %d, real supported finger num = %d\r\n", touch_dev->cap_info.multi_fingers, REAL_SUPPORTED_FINGER_NUM);
|
|
|
| touch_dev->cap_info.gesture_support = 0;
|
|
|
| zinitix_debug_msg("set other configuration\r\n");
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| if(touch_dev->raw_mode_flag != TOUCH_NORMAL_MODE) // test mode
|
| {
|
| if (ts_write_reg(touch_dev->client, ZINITIX_TOUCH_MODE, touch_dev->raw_mode_flag)!=I2C_SUCCESS) goto fail_init;
|
| }
|
| else
|
| #endif
|
| {
|
| reg_val = TOUCH_MODE;
|
| if (ts_write_reg(touch_dev->client, ZINITIX_TOUCH_MODE, reg_val)!=I2C_SUCCESS) goto fail_init;
|
| }
|
| // soft calibration
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_CALIBRATE_CMD)!=I2C_SUCCESS) goto fail_init;
|
| if (ts_write_reg(touch_dev->client, ZINITIX_INT_ENABLE_FLAG, touch_dev->cap_info.chip_int_mask)!=I2C_SUCCESS) goto fail_init;
|
|
|
| //---------------------------------------------------------------------
|
| // read garbage data
|
| for(i=0; i<10; i++)
|
| {
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| udelay(10);
|
| }
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| if(touch_dev->raw_mode_flag != TOUCH_NORMAL_MODE) // test mode
|
| {
|
| if (ts_write_reg(touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL)!=I2C_SUCCESS)
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL.\r\n");
|
| }
|
| else
|
| #endif
|
| {
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if (ts_write_reg(touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_ESD_TIMER_INTERVAL)!=I2C_SUCCESS) goto fail_init;
|
| if (ts_read_data(touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, (u8*)®_val, 2)<0) goto fail_init;
|
| zinitix_debug_msg("esd timer register = %d\r\n", reg_val);
|
| #endif
|
| }
|
|
|
| zinitix_debug_msg("successfully initialized\r\n");
|
| return true;
|
|
|
| fail_init:
|
|
|
| if(retry_cnt++ <= ZINITIX_INIT_RETRY_CNT)
|
| {
|
| mdelay(CHIP_POWER_OFF_DELAY);
|
| // ts_power_control(touch_dev, RESET_LOW); //reset pin low
|
| // ts_power_control(touch_dev, POWER_OFF); //power off
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(1000);
|
| // ts_power_control(touch_dev, POWER_ON); //power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1); //PSJ
|
| // ts_power_control(touch_dev, RESET_HIGH); //reset pin high
|
| mdelay(CHIP_ON_DELAY);
|
| zinitix_debug_msg("retry to initiallize(retry cnt = %d)\r\n", retry_cnt);
|
| goto retry_init;
|
| }
|
| else
|
| {
|
| touch_dev->cap_info.chip_fw_size = 16*1024;
|
| #if BT4x3_Above_Series
|
| touch_dev->cap_info.chip_fw_size = 32*1024;
|
| #endif
|
| mdelay(CHIP_POWER_OFF_DELAY);
|
| // ts_power_control(touch_dev, RESET_LOW); //reset pin low
|
| // ts_power_control(touch_dev, POWER_OFF); //power off
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(1000);
|
| // ts_power_control(touch_dev, POWER_ON); //power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1); //PSJ
|
| // ts_power_control(touch_dev, RESET_HIGH); //reset pin high
|
| mdelay(CHIP_ON_DELAY);
|
| zinitix_debug_msg("retry to initiallize(retry cnt = %d)\r\n", retry_cnt);
|
| #if 0 //TOUCH_FORCE_UPGRADE PSJ
|
| if(retry_cnt > 15)
|
| {
|
| printk("[zinitix touch] failed to force upgrade\r\n");
|
| return false;
|
| }
|
| goto force_upgrade;
|
| #endif
|
| }
|
|
|
| printk("[zinitix touch] failed to initiallize\r\n");
|
| gv_initCheck = 1;
|
| return false;
|
|
|
| }
|
|
|
|
|
| #if (TOUCH_MODE == 1)
|
| static void zinitix_report_data(zinitix_touch_dev *touch_dev, int id)
|
| {
|
| int i;
|
| u32 x, y;
|
| u32 tmp;
|
|
|
| if(id >= touch_dev->cap_info.multi_fingers || id < 0)
|
| {
|
| return;
|
| }
|
|
|
| x = touch_dev->touch_info.coord[id].x;
|
| y = touch_dev->touch_info.coord[id].y;
|
|
|
| /* transformation from touch to screen orientation */
|
| if (touch_dev->cap_info.Orientation & TOUCH_V_FLIP)
|
| {
|
| y = touch_dev->cap_info.MaxY + touch_dev->cap_info.MinY - y;
|
| }
|
| if (touch_dev->cap_info.Orientation & TOUCH_H_FLIP)
|
| {
|
| x = touch_dev->cap_info.MaxX + touch_dev->cap_info.MinX - x;
|
| }
|
| if (touch_dev->cap_info.Orientation & TOUCH_XY_SWAP)
|
| {
|
| zinitix_swap_v(x, y, tmp);
|
| }
|
| zinitix_debug_msg("x = %d, y = %d, w = %d\r\n", x, y, touch_dev->touch_info.coord[id].width);
|
|
|
| touch_dev->reported_touch_info.coord[id].x = x;
|
| touch_dev->reported_touch_info.coord[id].y = y;
|
| touch_dev->reported_touch_info.coord[id].width = touch_dev->touch_info.coord[id].width;
|
| touch_dev->reported_touch_info.coord[id].sub_status = touch_dev->touch_info.coord[id].sub_status;
|
|
|
|
|
| for(i=0; i< touch_dev->cap_info.multi_fingers; i++)
|
| {
|
| if(zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_EXIST)
|
| ||zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_DOWN)
|
| ||zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_MOVE))
|
| {
|
|
|
| if(touch_dev->reported_touch_info.coord[i].width == 0) touch_dev->reported_touch_info.coord[i].width = 5;
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, (u32)touch_dev->reported_touch_info.coord[i].width);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, (u32)touch_dev->reported_touch_info.coord[i].width);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->reported_touch_info.coord[i].x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->reported_touch_info.coord[i].y);
|
| input_mt_sync(touch_dev->input_dev);
|
| }
|
| else if(zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_UP))
|
| {
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->reported_touch_info.coord[i].x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->reported_touch_info.coord[i].y);
|
| input_mt_sync(touch_dev->input_dev);
|
| touch_dev->reported_touch_info.coord[i].sub_status = 0;
|
| }
|
| else
|
| touch_dev->reported_touch_info.coord[i].sub_status = 0;
|
| }
|
|
|
| input_sync(touch_dev->input_dev);
|
| }
|
| #endif // TOUCH_MODE == 1
|
|
|
| static void zinitix_clear_report_data(zinitix_touch_dev *touch_dev)
|
| {
|
| int i;
|
| u8 reported = 0;
|
|
|
| for(i=0; i < touch_dev->cap_info.multi_fingers; i++)
|
| {
|
| if(zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_EXIST))
|
| {
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->reported_touch_info.coord[i].x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->reported_touch_info.coord[i].y);
|
| input_mt_sync(touch_dev->input_dev);
|
| reported = 1;
|
| }
|
| touch_dev->reported_touch_info.coord[i].sub_status = 0;
|
| }
|
| if(reported) input_sync(touch_dev->input_dev);
|
| }
|
|
|
| static irqreturn_t ts_irq_thread(int irq, void *data)
|
| {
|
| zinitix_touch_dev* touch_dev = (zinitix_touch_dev*)data;
|
| bool read_coord_continued;
|
| int i;
|
| u8 reported = false;
|
| #if (TOUCH_MODE == 0)
|
| u32 x, y;
|
| u32 tmp;
|
| #endif
|
|
|
| if(gpio_get_value(touch_dev->int_gpio_num)) // remove pending interrupt
|
| {
|
| zinitix_debug_msg("invalid interrupt occured +\r\n");
|
| return IRQ_HANDLED;
|
| }
|
|
|
| down(&touch_dev->work_proceedure_lock);
|
| if(touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| printk(KERN_INFO "[TSP] invalid interrupt??? (%d)\n", touch_dev->work_proceedure);
|
| up(&touch_dev->work_proceedure_lock);
|
| return IRQ_HANDLED;
|
| }
|
| touch_dev->work_proceedure = TS_NORMAL_WORK;
|
| zinitix_debug_msg("zinitix_touch_thread : semaphore signalled\r\n");
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(touch_dev->use_esd_timer)
|
| {
|
| ts_esd_timer_stop(touch_dev);
|
| zinitix_debug_msg("esd timer stop\r\n");
|
| }
|
| #endif
|
| read_coord_continued = true;
|
| do
|
| {
|
|
|
| if (ts_read_coord(touch_dev)==false)
|
| {
|
| zinitix_debug_msg("couldn't read touch_dev sample\r\n");
|
| goto continue_read_samples;
|
| }
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| if(touch_dev->raw_mode_flag == TOUCH_TEST_RAW_MODE) goto continue_read_samples;
|
| #endif
|
|
|
|
|
| // invalid : maybe periodical repeated int.
|
| if(touch_dev->touch_info.status == 0x0) goto continue_read_samples;
|
| reported = false;
|
|
|
| if(zinitix_bit_test(touch_dev->touch_info.status, BIT_ICON_EVENT))
|
| {
|
|
|
| for(i=0; i<touch_dev->cap_info.button_num; i++)
|
| {
|
| if(zinitix_bit_test(touch_dev->icon_event_reg, (BIT_O_ICON0_DOWN+i)))
|
| {
|
| touch_dev->button[i] = ICON_BUTTON_DOWN;
|
| input_report_key(touch_dev->input_dev, BUTTON_MAPPING_KEY[i], 1);
|
| reported = true;
|
| zinitix_debug_msg("button down = %d \r\n", i);
|
| }
|
| }
|
|
|
| for(i=0; i<touch_dev->cap_info.button_num; i++)
|
| {
|
| if(zinitix_bit_test(touch_dev->icon_event_reg, (BIT_O_ICON0_UP+i)))
|
| {
|
| touch_dev->button[i] = ICON_BUTTON_UP;
|
| input_report_key(touch_dev->input_dev, BUTTON_MAPPING_KEY[i], 0);
|
| reported = true;
|
| zinitix_debug_msg("button up = %d \r\n", i);
|
| }
|
| }
|
| }
|
|
|
| // if button press or up event occured...
|
| if(reported == true)
|
| {
|
| #ifdef KEY_LED_CONTROL
|
| // printk(TCH_KERN_DEBUG "[TSP] key_led_on:%d menu_button:%d back_button%d\n", key_led_on, BUTTON_MAPPING_KEY[0], BUTTON_MAPPING_KEY[1]);
|
| // if(!key_led_on) {
|
| // vled_power_onoff(1);
|
| // mod_timer(&g_led_timer, (jiffies + HZ*2));
|
| // key_led_on = true;
|
| // }
|
| #endif
|
|
|
| #if (TOUCH_MODE == 1)
|
| //input_sync(touch_dev->input_dev);
|
| for(i=0; i< touch_dev->cap_info.multi_fingers; i++)
|
| {
|
|
|
| if(zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_EXIST))
|
| {
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->reported_touch_info.coord[i].x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->reported_touch_info.coord[i].y);
|
| input_mt_sync(touch_dev->input_dev);
|
| }
|
| touch_dev->reported_touch_info.coord[i].sub_status = 0;
|
| }
|
| input_sync(touch_dev->input_dev);
|
| //goto continue_read_samples;
|
| }
|
| #else
|
| zinitix_debug_msg("%s : touch mode = 0\n", __func__);
|
|
|
| for(i=0; i< touch_dev->cap_info.multi_fingers; i++)
|
| {
|
|
|
| if(zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_EXIST))
|
| {
|
|
|
| //input_report_abs(touch_dev->input_dev,ABS_MT_TRACKING_ID,i);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->reported_touch_info.coord[i].x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->reported_touch_info.coord[i].y);
|
| input_mt_sync(touch_dev->input_dev);
|
| }
|
| }
|
| memset(&touch_dev->reported_touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
| input_sync(touch_dev->input_dev);
|
| udelay(100);
|
| goto continue_read_samples;
|
| }
|
|
|
|
|
| if (touch_dev->touch_info.finger_cnt > MAX_SUPPORTED_FINGER_NUM)
|
| touch_dev->touch_info.finger_cnt = MAX_SUPPORTED_FINGER_NUM;
|
|
|
| if(!zinitix_bit_test(touch_dev->touch_info.status, BIT_PT_EXIST))
|
| {
|
|
|
| for(i=0; i< touch_dev->cap_info.multi_fingers; i++)
|
| {
|
| if(zinitix_bit_test(touch_dev->reported_touch_info.coord[i].sub_status, SUB_BIT_EXIST))
|
| {
|
| zinitix_debug_msg("TSP UP UP UP UP \n");
|
| //input_report_abs(touch_dev->input_dev,ABS_MT_TRACKING_ID,i);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->reported_touch_info.coord[i].x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->reported_touch_info.coord[i].y);
|
| input_mt_sync(touch_dev->input_dev);
|
| }
|
| }
|
| memset(&touch_dev->reported_touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
|
|
| input_report_key(touch_dev->input_dev, BTN_TOUCH, 0); /* SKC */
|
| input_sync(touch_dev->input_dev);
|
| goto continue_read_samples;
|
| }
|
|
|
|
|
| for(i=0; i< touch_dev->cap_info.multi_fingers; i++)
|
| {
|
|
|
| if(zinitix_bit_test(touch_dev->touch_info.coord[i].sub_status, SUB_BIT_DOWN)
|
| || zinitix_bit_test(touch_dev->touch_info.coord[i].sub_status, SUB_BIT_MOVE)
|
| || zinitix_bit_test(touch_dev->touch_info.coord[i].sub_status, SUB_BIT_EXIST))
|
| {
|
| x = touch_dev->touch_info.coord[i].x;
|
| y = touch_dev->touch_info.coord[i].y;
|
|
|
| /* transformation from touch to screen orientation */
|
| if (touch_dev->cap_info.Orientation & TOUCH_V_FLIP)
|
| {
|
| y = touch_dev->cap_info.MaxY + touch_dev->cap_info.MinY - y;
|
| }
|
| if (touch_dev->cap_info.Orientation & TOUCH_H_FLIP)
|
| {
|
| x = touch_dev->cap_info.MaxX + touch_dev->cap_info.MinX - x;
|
| }
|
| if (touch_dev->cap_info.Orientation & TOUCH_XY_SWAP)
|
| {
|
| zinitix_swap_v(x, y, tmp);
|
| }
|
| if (x == 0) x = 1;
|
| if (y == 0) y = 1;
|
| touch_dev->touch_info.coord[i].x = x;
|
| touch_dev->touch_info.coord[i].y = y;
|
|
|
| zinitix_debug_msg("finger [%02d] x = %d, y = %d \r\n", i, x, y);
|
| if(IsdebugMatrix)
|
| zinitix_debug_msg("[TSP] finger [%02d] x = %d, y = %d \r\n", i, x, y);
|
|
|
| //input_report_abs(touch_dev->input_dev,ABS_MT_TRACKING_ID,i);
|
| if(touch_dev->touch_info.coord[i].width == 0) touch_dev->touch_info.coord[i].width = 5;
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, (u32)touch_dev->touch_info.coord[i].width);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, (u32)touch_dev->touch_info.coord[i].width);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, y);
|
| input_mt_sync(touch_dev->input_dev);
|
|
|
|
|
| }
|
| else if(zinitix_bit_test(touch_dev->touch_info.coord[i].sub_status, SUB_BIT_UP))
|
| {
|
| zinitix_debug_msg("finger [%02d] up \r\n", i);
|
| memset(&touch_dev->touch_info.coord[i], 0x0, sizeof(_ts_zinitix_coord));
|
| //input_report_abs(touch_dev->input_dev, ABS_MT_TRACKING_ID,i);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, 0);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->reported_touch_info.coord[i].x);
|
| input_report_abs(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->reported_touch_info.coord[i].y);
|
| input_mt_sync(touch_dev->input_dev);
|
|
|
| }
|
|
|
| else
|
| memset(&touch_dev->touch_info.coord[i], 0x0, sizeof(_ts_zinitix_coord));
|
|
|
|
|
| }
|
| memcpy((char*)&touch_dev->reported_touch_info, (char*)&touch_dev->touch_info, sizeof(_ts_zinitix_point_info));
|
| input_report_key(touch_dev->input_dev, BTN_TOUCH, 1); /* SKC */
|
| input_sync(touch_dev->input_dev);
|
|
|
| #endif // TOUCH_MODE == 1
|
| continue_read_samples:
|
|
|
| //check_interrupt_pin, if high, enable int & wait signal
|
| // if (gpio_get_value(touch_dev->int_gpio_num))
|
| if(1)
|
| {
|
| read_coord_continued = false;
|
| if(touch_dev->work_proceedure == TS_NORMAL_WORK)
|
| {
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(touch_dev->use_esd_timer)
|
| {
|
| ts_esd_timer_start(ZINITIX_CHECK_ESD_TIMER, touch_dev);
|
| zinitix_debug_msg("esd timer start\r\n");
|
| }
|
| #endif
|
|
|
| touch_dev->work_proceedure = TS_NO_WORK;
|
| }
|
| up(&touch_dev->work_proceedure_lock);
|
| }
|
| else
|
| {
|
| zinitix_debug_msg("interrupt pin is still low, so continue read \r\n");
|
| }
|
|
|
| }while(read_coord_continued);
|
|
|
| return IRQ_HANDLED;
|
|
|
| }
|
|
|
| #ifdef CONFIG_HAS_EARLYSUSPEND
|
| static void zinitix_late_resume(struct early_suspend *h)
|
| {
|
|
|
| zinitix_touch_dev * touch_dev;
|
| touch_dev = container_of(h, zinitix_touch_dev, early_suspend);
|
| printk(KERN_INFO "[TSP] resume++\r\n");
|
| if(touch_dev == NULL) return;
|
|
|
| down(&touch_dev->work_proceedure_lock);
|
| if(touch_dev->work_proceedure != TS_IN_RESUME && touch_dev->work_proceedure != TS_IN_EALRY_SUSPEND)
|
| {
|
| up(&touch_dev->work_proceedure_lock);
|
| return;
|
| }
|
|
|
| // touch_power_onoff(1);
|
| // mdelay(50);
|
| // for trebon tsp power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1);
|
| mdelay(CHIP_ON_DELAY);
|
|
|
| ts_write_cmd(touch_dev->client, ZINITIX_WAKEUP_CMD);
|
| mdelay(10);
|
| if(ts_mini_init_touch(touch_dev)==false) goto fail_resume;
|
| touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&touch_dev->work_proceedure_lock);
|
| printk(KERN_INFO "[TSP] resume--\n");
|
| return;
|
| fail_resume:
|
| printk(KERN_ERR "[TSP] failed to resume\n");
|
| touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&touch_dev->work_proceedure_lock);
|
| return;
|
| }
|
|
|
|
|
| static void zinitix_early_suspend(struct early_suspend *h)
|
| {
|
| zinitix_touch_dev * touch_dev;
|
| touch_dev = container_of(h, zinitix_touch_dev, early_suspend);
|
| if(touch_dev == NULL) return;
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| flush_work(&touch_dev->tmr_work);
|
| #endif
|
|
|
| down(&touch_dev->work_proceedure_lock);
|
| if(touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| up(&touch_dev->work_proceedure_lock);
|
| return;
|
| }
|
| touch_dev->work_proceedure = TS_IN_EALRY_SUSPEND;
|
|
|
| printk(KERN_INFO "[TSP] early suspend++\n");
|
| zinitix_debug_msg("clear all reported points\r\n");
|
| zinitix_clear_report_data(touch_dev);
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(touch_dev->use_esd_timer)
|
| {
|
| ts_write_reg(touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, 0);
|
| ts_esd_timer_stop(touch_dev);
|
| printk(KERN_INFO "[TSP] ts_esd_timer_stop\n");
|
| }
|
| #endif
|
|
|
| #if !(USING_CHIP_SETTING)
|
| ts_write_reg(touch_dev->client, ZINITIX_INT_ENABLE_FLAG, 0x0);
|
| #endif
|
| udelay(100);
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| if (ts_write_cmd(touch_dev->client, ZINITIX_SLEEP_CMD)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_ERR "[TSP] failed to enter into sleep mode\n");
|
| up(&touch_dev->work_proceedure_lock);
|
| // touch_power_onoff(0);
|
| // mdelay(50);
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(CHIP_POWER_OFF_DELAY);
|
| return;
|
| }
|
|
|
| // vled_power_onoff(0);
|
| // touch_power_onoff(0);
|
| // mdelay(50);
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(CHIP_POWER_OFF_DELAY);
|
|
|
| printk(KERN_INFO "[TSP] early suspend--\n");
|
| up(&touch_dev->work_proceedure_lock);
|
| return;
|
| }
|
|
|
| #endif // CONFIG_HAS_EARLYSUSPEND
|
|
|
|
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
|
|
| static ssize_t zinitix_get_test_raw_data(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| int i,j;
|
| int k = 0;
|
|
|
| int written_bytes = 0 ; /* & error check */
|
|
|
| int16_t raw_data[X_RAW_DATA][Y_RAW_DATA]={{0,},};
|
| int16_t diff_data[X_RAW_DATA][Y_RAW_DATA]={{0,},};
|
|
|
|
|
| down(&misc_touch_dev->raw_data_lock);
|
|
|
| for(j = 0 ; j < Y_RAW_DATA; j++)
|
| {
|
| k = j;
|
| for(i = 0 ; i < X_RAW_DATA ; i++)
|
| {
|
| raw_data[i][j] =(int)(misc_touch_dev->ref_data[k]&0xffff);
|
| diff_data[i][j] =(int)(((s16)(misc_touch_dev->cur_data[k]-misc_touch_dev->ref_data[k]))&0xffff);
|
| k+=Y_RAW_DATA;
|
| }
|
| }
|
|
|
| up(&misc_touch_dev->raw_data_lock);
|
|
|
|
|
| for(i = 0 ; i < X_RAW_DATA ; i++)
|
| {
|
| printk("[TSP]");
|
| for(j = 0 ; j < Y_RAW_DATA ; j++ )
|
| printk(" %5d", raw_data[i][j]);
|
| printk("\n");
|
| }
|
|
|
|
|
| for(i = 0 ; i < X_RAW_DATA ; i++)
|
| {
|
| printk("[TSP]");
|
| for(j = 0 ; j < Y_RAW_DATA ; j++ )
|
| printk(" %5d", diff_data[i][j]);
|
| printk("\n");
|
| }
|
|
|
| for(j = 0 ; j < Y_RAW_DATA ; j++)
|
| {
|
| for (i = 0; i < X_RAW_DATA ; i++)
|
| written_bytes += sprintf(buf+written_bytes, "%d %d\n", raw_data[i][j], diff_data[i][j]);
|
| }
|
|
|
| if (written_bytes > 0)
|
| return written_bytes;
|
|
|
| return sprintf(buf, "-1");
|
| }
|
|
|
|
|
| ssize_t zinitix_set_testmode(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
|
| {
|
| unsigned char value = 0;
|
|
|
| printk(KERN_INFO "[zinitix_touch] zinitix_set_testmode, buf = %d\r\n", *buf);
|
|
|
| if(misc_touch_dev == NULL)
|
| {
|
| zinitix_debug_msg("device NULL : NULL\n");
|
| return 0;
|
| }
|
|
|
| sscanf(buf, "%c", &value);
|
|
|
| if(value != TOUCH_TEST_RAW_MODE && value != TOUCH_NORMAL_MODE)
|
| {
|
| printk(KERN_WARNING "[zinitix ts] test mode setting value error. you must set %d[=normal] or %d[=raw mode]\r\n", TOUCH_NORMAL_MODE, TOUCH_TEST_RAW_MODE);
|
| return 1;
|
| }
|
|
|
| down(&misc_touch_dev->raw_data_lock);
|
| misc_touch_dev->raw_mode_flag = value;
|
|
|
| printk(KERN_INFO "[zinitix_touch] zinitix_set_testmode, touchkey_testmode = %d\r\n", misc_touch_dev->raw_mode_flag);
|
|
|
| if(misc_touch_dev->raw_mode_flag == TOUCH_NORMAL_MODE) // Å×½ºÆ® ¸ðµå ÇØÁ¦½Ã
|
| {
|
| printk(KERN_INFO "[zinitix_touch] TEST Mode Exit\r\n");
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_ESD_TIMER_INTERVAL)!=I2C_SUCCESS)
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITIX_PERIODICAL_INTERRUPT_INTERVAL.\r\n");
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_TOUCH_MODE, TOUCH_MODE)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITX_TOUCH_MODE %d.\r\n", TOUCH_MODE);
|
| }
|
| // clear garbage data
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| mdelay(100);
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| }
|
| else // Å×½ºÆ® ¸ðµå ÁøÀÔ½Ã
|
| {
|
| printk(KERN_INFO "[zinitix_touch] TEST Mode Enter\r\n");
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL)!=I2C_SUCCESS)
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL.\r\n");
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_TOUCH_MODE, TOUCH_TEST_RAW_MODE)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[zinitix_touch] TEST Mode : Fail to set ZINITX_TOUCH_MODE %d.\r\n", TOUCH_TEST_RAW_MODE);
|
| }
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| // clear garbage data
|
| mdelay(100);
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| memset(&misc_touch_dev->reported_touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
| memset(&misc_touch_dev->touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
| }
|
| up(&misc_touch_dev->raw_data_lock);
|
| return 1;
|
|
|
| }
|
| static ssize_t zinitix_tkey_reference(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| zinitix_touch_dev *touch_dev = global_touch_dev;
|
|
|
|
|
| printk(KERN_INFO "[zinitix_touch] %s\r\n", __FUNCTION__);
|
|
|
| if(touch_dev == NULL)
|
| zinitix_debug_msg("device NULL : NULL\n");
|
|
|
| printk(KERN_INFO "[zinitix_touch] %s : menu(%d), back(%d)\r\n", __FUNCTION__, touch_dev->cur_data[ZINITIX_MENU_KEY], touch_dev->cur_data[ZINITIX_BACK_KEY]);
|
|
|
| return sprintf(buf, "%d %d", touch_dev->cur_data[ZINITIX_MENU_KEY], touch_dev->cur_data[ZINITIX_BACK_KEY]);
|
| }
|
|
|
| static ssize_t zinitix_tkey_data(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| zinitix_touch_dev *touch_dev = global_touch_dev;
|
| // u16 menukey, backkey;
|
|
|
| printk(KERN_INFO "[zinitix_touch] %s\r\n", __FUNCTION__);
|
|
|
| if(touch_dev == NULL)
|
| zinitix_debug_msg("device NULL : NULL\n");
|
|
|
| printk(KERN_INFO "[zinitix_touch] %s : menu(%d)(%d), back(%d)(%d)\r\n", __FUNCTION__,
|
| touch_dev->ref_data[ZINITIX_MENU_KEY], touch_dev->cur_data[ZINITIX_MENU_KEY],
|
| touch_dev->ref_data[ZINITIX_BACK_KEY],touch_dev->cur_data[ZINITIX_BACK_KEY]);
|
|
|
| return sprintf(buf, "%d\n%d\n%d\n%d\n", touch_dev->ref_data[ZINITIX_MENU_KEY], touch_dev->cur_data[ZINITIX_MENU_KEY],
|
| touch_dev->ref_data[ZINITIX_BACK_KEY],touch_dev->cur_data[ZINITIX_BACK_KEY]);
|
| }
|
| static int16_t zinitix_raw_data[X_RAW_DATA][Y_RAW_DATA] = {{0,},};
|
| static ssize_t zinitix_touch_reference(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| int time_out = 0;
|
| int i, j;
|
| int interrup_detecting;
|
| int written_bytes = 0; /* error check */
|
|
|
| int16_t raw_data[X_RAW_DATA][Y_RAW_DATA] = {{0,},}; // 2 byte
|
|
|
| printk(KERN_INFO "[zinitix_touch] zinitix_read_raw_data( )\r\n");
|
| disable_irq(misc_touch_dev->client->irq);
|
|
|
| if (ts_write_reg(misc_touch_dev->client,
|
| ZINITIX_TOUCH_MODE, 7) != I2C_SUCCESS) {
|
| printk(KERN_INFO "[zinitix_touch] ZINITIX_TOUCH_MODE fail\r\n");
|
| goto fail_read_raw;
|
| }
|
| udelay(10);
|
|
|
| for (i = 0; i < INT_WAIT_TIME; i++) {
|
| ts_write_cmd(misc_touch_dev->client,
|
| ZINITIX_CLEAR_INT_STATUS_CMD);
|
| time_out = 0;
|
| interrup_detecting = 1;
|
|
|
| while (gpio_get_value(misc_touch_dev->int_gpio_num)) {
|
| msleep(1);
|
|
|
| if (time_out++ > 20) {
|
| printk(KERN_INFO "[zinitix_touch] interrupt disable timed out\r\n");
|
| interrup_detecting = 0;
|
| break;
|
| }
|
| }
|
| if (i == INT_WAIT_TIME) {
|
| printk(KERN_INFO "[zinitix_touch] interrupt disable timed out\r\n");
|
| goto fail_read_raw;
|
| }
|
|
|
| if ((interrup_detecting == 1) && (time_out < 20)) {
|
| if (ts_read_raw_data(misc_touch_dev->client,
|
| ZINITIX_RAWDATA_REG, (char *)raw_data,
|
| MAX_TEST_RAW_DATA*2) < 0) {
|
| printk(KERN_INFO "[zinitix_touch] ZINITIX_RAWDATA_REG fail\r\n");
|
| goto fail_read_raw;
|
| }
|
| memcpy(zinitix_raw_data, raw_data, MAX_TEST_RAW_DATA*2);
|
| #ifdef ZINITIX_N_TEST
|
| for (j = 0; j < (MAX_TEST_RAW_DATA*2); j++) {
|
| printk(KERN_INFO "[zinitix_touch] temp_buff[%d]"
|
| "= %5d\r\n", j, zinitix_raw_data[j]);
|
| }
|
| #endif
|
| break;
|
| }
|
| }
|
|
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| udelay(10);
|
|
|
| if (ts_write_reg(misc_touch_dev->client,
|
| ZINITIX_TOUCH_MODE, TOUCH_MODE) != I2C_SUCCESS) {
|
| printk(KERN_INFO "[zinitix_touch] ZINITIX_TOUCH_MODE fail\r\n");
|
| goto fail_read_raw;
|
| }
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| udelay(10);
|
|
|
| enable_irq(misc_touch_dev->client->irq);
|
|
|
| for (i = 0; i < misc_touch_dev->cap_info.x_node_num; i++) {
|
| printk(KERN_CONT "[TSP]");
|
| for (j = 0; j < misc_touch_dev->cap_info.y_node_num; j++)
|
| printk(KERN_CONT " %5d", raw_data[i][j]);
|
| printk(KERN_CONT "\n");
|
| }
|
|
|
| // TSP ndata
|
| for (i = 0; i < misc_touch_dev->cap_info.x_node_num-1; i++) {
|
| for (j = 0; j < misc_touch_dev->cap_info.y_node_num; j++) {
|
| if (raw_data[i][j] < CAL_MIN_NUM)
|
| return snprintf(buf, 2, "0");
|
|
|
| if (raw_data[i][j] > CAL_MAX_NUM)
|
| return snprintf(buf, 2, "0");
|
| }
|
| }
|
|
|
| // TOUCH KEY ndata
|
| for (j = 0; j < misc_touch_dev->cap_info.y_node_num; j++) {
|
| if ((j == 1) || (j == 8)) {
|
| if (raw_data[misc_touch_dev->cap_info.x_node_num-1][j]
|
| < CAL_MIN_NUM)
|
| return snprintf(buf, 2, "0");
|
|
|
| if (raw_data[misc_touch_dev->cap_info.x_node_num-1][j]
|
| > CAL_MAX_NUM)
|
| return snprintf(buf, 2, "0");
|
| }
|
| }
|
| //return snprintf(buf, 2, "1");
|
| for (i = 0; i < misc_touch_dev->cap_info.x_node_num; i++) {
|
| for (j = 0; j < misc_touch_dev->cap_info.y_node_num; j++) {
|
| written_bytes += sprintf(buf+written_bytes, "%d,",raw_data[i][j]);
|
| }
|
| }
|
| if(written_bytes > 0)
|
| return written_bytes;
|
| fail_read_raw:
|
| if (ts_write_reg(misc_touch_dev->client,
|
| ZINITIX_TOUCH_MODE, TOUCH_MODE) != I2C_SUCCESS) {
|
| printk(KERN_INFO "[zinitix_touch] ZINITIX_TOUCH_MODE fail\r\n");
|
| goto fail_read_raw;
|
| }
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| udelay(10);
|
|
|
| enable_irq(misc_touch_dev->client->irq);
|
| return snprintf(buf, 2, "-1");
|
| }
|
|
|
| static ssize_t zinitix_touch_ndata_show(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| int i,j,written_bytes=0;
|
| printk("[TSP] %s\n",__func__);
|
|
|
| for (i = 0; i < misc_touch_dev->cap_info.x_node_num-1; i++) {
|
| for (j = 0; j < misc_touch_dev->cap_info.y_node_num; j++) {
|
| written_bytes += sprintf(buf+written_bytes, "%d,",zinitix_raw_data[i][j]);
|
| }
|
| }
|
| if(written_bytes > 0)
|
| return written_bytes;
|
| return -1;
|
| }
|
| static ssize_t zinitix_delta(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| zinitix_touch_dev *touch_dev = global_touch_dev;
|
| int written_bytes = 0, i;
|
|
|
| printk(KERN_INFO "[zinitix_touch] %s\r\n", __FUNCTION__);
|
|
|
| if(touch_dev == NULL)
|
| zinitix_debug_msg("device NULL : NULL\n");
|
|
|
| for(i = 0 ; i < MAX_TEST_RAW_DATA; i++)
|
| {
|
| written_bytes += sprintf(buf+written_bytes, "%d,", touch_dev->cur_data[i] - touch_dev->ref_data[i]) ;
|
| }
|
|
|
| if(written_bytes > 0)
|
| return written_bytes;
|
| return -1;
|
| }
|
|
|
| static ssize_t zinitix_scantime(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| int i, j;
|
| int written_bytes = 0; /* error check */
|
|
|
| u8 raw_data[FULL_X_DATA][FULL_Y_DATA] = {{0,},}; // get the full_data, 1 byte
|
| u8 scantime_data[X_RAW_DATA][Y_RAW_DATA] = {{0,},};
|
|
|
| printk(KERN_INFO "[zinitix_touch] scantime_zinitix( )\r\n");
|
| disable_irq(misc_touch_dev->client->irq);
|
|
|
| if (ts_write_reg(misc_touch_dev->client,
|
| ZINITIX_TOUCH_MODE, 8) != I2C_SUCCESS) {
|
| printk(KERN_INFO "[zinitix_touch] ZINITIX_TOUCH_MODE fail\r\n");
|
| goto fail_read_raw;
|
| }
|
| msleep(100);
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
|
|
| // ts_read_data(misc_touch_dev->client, ZINITIX_CAL_N_TOTAL_NUM, (u8*)&misc_touch_dev->cap_info.total_cal_n, 2);
|
| if (ts_read_raw_data(misc_touch_dev->client,
|
| ZINITIX_RAWDATA_REG, (char *)raw_data, SCANTIME_RAWDATA) < 0) {
|
| printk(KERN_INFO "[TSP] error : read zinitix tc Cal N raw data\n");
|
| goto fail_read_raw;
|
| }
|
| msleep(10);
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| msleep(10);
|
|
|
| if (ts_write_reg(misc_touch_dev->client,
|
| ZINITIX_TOUCH_MODE, TOUCH_MODE) != I2C_SUCCESS) {
|
| printk(KERN_INFO "[zinitix_touch] ZINITIX_TOUCH_MODE fail\r\n");
|
| goto fail_read_raw;
|
| }
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| msleep(10);
|
| enable_irq(misc_touch_dev->client->irq);
|
|
|
| #if 0
|
| for (i = 0; i < 20/* misc_touch_dev->cap_info.x_node_num*/; i++) {
|
| printk(KERN_CONT "[TSP]");
|
| for (j = 0; j < 16/*misc_touch_dev->cap_info.y_node_num*/; j++) {
|
| //scantime_data[i][j] = raw_data[i][j];
|
| printk(KERN_CONT " %d", raw_data[i][j]);
|
| }
|
| printk(KERN_CONT "\n");
|
| }
|
| #endif // #if 0. This is only for test to check raw_data
|
|
|
| for (i = 0; i < misc_touch_dev->cap_info.x_node_num; i++) {
|
| printk(KERN_CONT "[TSP]");
|
| for (j = 0; j < misc_touch_dev->cap_info.y_node_num; j++) {
|
| scantime_data[i][j] = raw_data[i][j];
|
| printk(KERN_CONT " %d", scantime_data[i][j]);
|
| }
|
| printk(KERN_CONT "\n");
|
| }
|
|
|
| for (i = 0; i < misc_touch_dev->cap_info.x_node_num; i++) {
|
| for (j = 0; j < misc_touch_dev->cap_info.y_node_num; j++) {
|
| // snprintf(buf+written_bytes, 8, "%d,",
|
| // scantime_data[i][j]);
|
| // written_bytes += 4;
|
| written_bytes +=sprintf(buf+written_bytes, "%d,",scantime_data[i][j]);
|
|
|
| }
|
| }
|
|
|
| if(written_bytes > 0)
|
| return written_bytes;
|
|
|
| return snprintf(buf, 2, "-1");
|
|
|
| fail_read_raw:
|
| if (ts_write_reg(misc_touch_dev->client,
|
| ZINITIX_TOUCH_MODE, TOUCH_MODE) != I2C_SUCCESS) {
|
| printk(KERN_INFO "[zinitix_touch] ZINITIX_TOUCH_MODE fail\r\n");
|
| goto fail_read_raw;
|
| }
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| udelay(10);
|
|
|
| enable_irq(misc_touch_dev->client->irq);
|
| return snprintf(buf, 2, "-1");
|
| }
|
|
|
| static ssize_t zinitix_enter_testmode(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| zinitix_touch_dev *touch_dev = global_touch_dev;
|
|
|
| printk(KERN_INFO "[zinitix_touch] %s 111 name : %s\r\n", __FUNCTION__, touch_dev->client->name);
|
|
|
| if(touch_dev == NULL)
|
| zinitix_debug_msg("device NULL : NULL\n");
|
|
|
| down(&touch_dev->raw_data_lock);
|
| touch_dev->raw_mode_flag = TOUCH_TEST_RAW_MODE;
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL)!=I2C_SUCCESS)
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL.\r\n");
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_TOUCH_MODE, TOUCH_TEST_RAW_MODE)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[zinitix_touch] TEST Mode : Fail to set ZINITX_TOUCH_MODE %d.\r\n", TOUCH_TEST_RAW_MODE);
|
| }
|
|
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| // clear garbage data
|
| mdelay(100);
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| memset(&touch_dev->reported_touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
| memset(&touch_dev->touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
|
|
| up(&touch_dev->raw_data_lock);
|
| return 1;
|
| }
|
|
|
| static ssize_t zinitix_enter_scanmode(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| zinitix_touch_dev *touch_dev = global_touch_dev;
|
|
|
| printk(KERN_INFO "[zinitix_touch] %s 111 name : %s\r\n", __FUNCTION__, touch_dev->client->name);
|
|
|
| if(touch_dev == NULL)
|
| zinitix_debug_msg("device NULL : NULL\n");
|
|
|
| down(&touch_dev->raw_data_lock);
|
| touch_dev->raw_mode_flag = TOUCH_ZINITIX_CAL_N_MODE;
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL)!=I2C_SUCCESS)
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL.\r\n");
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_TOUCH_MODE, TOUCH_ZINITIX_CAL_N_MODE)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[zinitix_touch] TEST Mode : Fail to set ZINITX_TOUCH_MODE %d.\r\n", TOUCH_ZINITIX_CAL_N_MODE);
|
| }
|
|
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| // clear garbage data
|
| mdelay(100);
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| memset(&touch_dev->reported_touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
| memset(&touch_dev->touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
|
|
| up(&touch_dev->raw_data_lock);
|
| return 1;
|
| }
|
|
|
| static ssize_t zinitix_enter_normalmode(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| zinitix_touch_dev *touch_dev = global_touch_dev;
|
|
|
| printk(KERN_INFO "[zinitix_touch] %s\r\n", __FUNCTION__);
|
|
|
| if(touch_dev == NULL)
|
| zinitix_debug_msg("device NULL : NULL\n");
|
|
|
| down(&touch_dev->raw_data_lock);
|
| touch_dev->raw_mode_flag = TOUCH_NORMAL_MODE;
|
|
|
| printk(KERN_INFO "[zinitix_touch] TEST Mode Exit\r\n");
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_ESD_TIMER_INTERVAL)!=I2C_SUCCESS)
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITIX_PERIODICAL_INTERRUPT_INTERVAL.\r\n");
|
|
|
| if (ts_write_reg(touch_dev->client, ZINITIX_TOUCH_MODE, TOUCH_MODE)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITX_TOUCH_MODE %d.\r\n", TOUCH_MODE);
|
| }
|
| // clear garbage data
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| mdelay(100);
|
| ts_write_cmd(touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
|
|
| up(&touch_dev->raw_data_lock);
|
| return 1;
|
| }
|
| static ssize_t zinitix_count_node(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| printk("[TSP] %s\n",__func__);
|
| return sprintf(buf, "%d,%d\n", X_RAW_DATA,Y_RAW_DATA);
|
| }
|
| static ssize_t zinitix_chip_info(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| printk("[TSP] %s\n",__func__);
|
| return sprintf(buf, "%s,%s\n", CHIP_INFO,CHIP_NAME);
|
| }
|
| static ssize_t zinitix_menu_sensitivity_show(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| int ret = 0;
|
| u16 menu_sensitivity;
|
|
|
| ret = ts_read_data(misc_touch_dev->client, 0x00A8, (u8*)&menu_sensitivity, 2);
|
|
|
| if (ret<0)
|
| return sprintf(buf, "%s\n", "fail to read menu_sensitivity.");
|
| else
|
| return sprintf(buf, "%d\n", menu_sensitivity);
|
| }
|
|
|
| static ssize_t zinitix_back_sensitivity_show(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| int ret = 0;
|
| u16 back_sensitivity;
|
|
|
| ret = ts_read_data(misc_touch_dev->client, 0x00A9, (u8*)&back_sensitivity, 2);
|
|
|
| if (ret<0)
|
| return sprintf(buf, "%s\n", "fail to read back_sensitivity.");
|
| else
|
| return sprintf(buf, "%d\n", back_sensitivity);
|
| }
|
| static DEVICE_ATTR(get_touch_test_raw_data, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_get_test_raw_data, zinitix_set_testmode);
|
| static DEVICE_ATTR(tkey_reference, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_tkey_reference, NULL);
|
| static DEVICE_ATTR(touch_reference, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_touch_reference, NULL);
|
| static DEVICE_ATTR(delta, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_delta, NULL);
|
| static DEVICE_ATTR(scantime, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_scantime, NULL);
|
| static DEVICE_ATTR(enter_testmode, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_enter_testmode, NULL);
|
| static DEVICE_ATTR(enter_scanmode, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_enter_scanmode, NULL);
|
| static DEVICE_ATTR(enter_normalmode, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_enter_normalmode, NULL);
|
| static DEVICE_ATTR(count_node, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_count_node, NULL);
|
| static DEVICE_ATTR(chip_info, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_chip_info, NULL);
|
| static DEVICE_ATTR(menu_sensitivity, S_IRUGO | S_IWUSR | S_IWGRP, zinitix_menu_sensitivity_show, NULL);
|
| static DEVICE_ATTR(back_sensitivity, S_IRUGO | S_IWUSR | S_IWGRP, zinitix_back_sensitivity_show, NULL);
|
| static DEVICE_ATTR(touch_ndata, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_touch_ndata_show, NULL);
|
| static DEVICE_ATTR(tkey_data, S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH, zinitix_tkey_data, NULL);
|
| #ifdef KEY_LED_CONTROL
|
| static DEVICE_ATTR(brightness, S_IRUGO | S_IWUSR | S_IWGRP, NULL, touch_led_control);
|
| #endif
|
|
|
| static int ts_misc_fops_open(struct inode *inode, struct file *filp)
|
| {
|
| return 0;
|
| }
|
|
|
| static int ts_misc_fops_close(struct inode *inode, struct file *filp)
|
| {
|
| return 0;
|
| }
|
|
|
| #if 0//LINUX_VERSION_CODE < KERNEL_VERSION(2.6.36)
|
| static int ts_misc_fops_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
|
| #else
|
| static long ts_misc_fops_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
| #endif
|
| {
|
| void __user *argp = (void __user *)arg;
|
|
|
|
|
| if(misc_touch_dev==NULL)
|
| {
|
| return -1;
|
| }
|
|
|
| //zinitix_debug_msg("cmd = %d, argp = 0x%x\n", cmd, (int)argp);
|
|
|
| switch(cmd)
|
| {
|
|
|
| case TOUCH_IOCTL_GET_DEBUGMSG_STATE:
|
| {
|
| int ret = 0;
|
| ret = m_ts_debug_mode;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
| case TOUCH_IOCTL_SET_DEBUGMSG_STATE:
|
| {
|
| int value = 0;
|
| if(copy_from_user(&value, argp, 4))
|
| {
|
| printk(KERN_INFO "[zinitix_touch] error : copy_from_user\r\n");
|
| return -1;
|
| }
|
| if(value)
|
| printk(KERN_INFO "[zinitix_touch] turn on debug mode (%d)\r\n", value);
|
| else
|
| printk(KERN_INFO "[zinitix_touch] turn off debug mode (%d)\r\n", value);
|
| m_ts_debug_mode = value;
|
| }
|
| break;
|
| case TOUCH_IOCTL_GET_CHIP_REVISION:
|
| {
|
| int ret = 0;
|
| ret = misc_touch_dev->cap_info.chip_revision;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_GET_FW_VERSION:
|
| {
|
| int ret = 0;
|
| ret = misc_touch_dev->cap_info.chip_firmware_version;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
| case TOUCH_IOCTL_GET_REG_DATA_VERSION:
|
| {
|
| int ret = 0;
|
| ret = misc_touch_dev->cap_info.chip_reg_data_version;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
| case TOUCH_IOCTL_VARIFY_UPGRADE_SIZE:
|
| {
|
| size_t sz = 0;
|
| if(copy_from_user(&sz, argp, sizeof(size_t))) return -1;
|
|
|
| printk(KERN_INFO "[TSP] firmware size = %d\r\n", sz);
|
| if(misc_touch_dev->cap_info.chip_fw_size != sz)
|
| {
|
| printk(KERN_INFO "[TSP] firmware size error\r\n");
|
| return -1;
|
| }
|
|
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_VARIFY_UPGRADE_DATA:
|
| {
|
| // int ret = 0;
|
| u16 version;
|
| // unsigned int version_pos;
|
| if(copy_from_user(&m_firmware_data[2], argp, misc_touch_dev->cap_info.chip_fw_size)) return -1;
|
| #if BT4x2_Series
|
| // version_pos = (unsigned int)((((unsigned int)m_firmware_data[4]<<8)&0xff00)|(m_firmware_data[5]&0xff));
|
| // version = (u16)(((u16)m_firmware_data[version_pos+2+2]<<8)|(u16)m_firmware_data[version_pos+2+1]);
|
| #endif
|
| #if BT4x3_Above_Series
|
| version = (u16)(((u16)m_firmware_data[FIRMWARE_VERSION_POS+1]<<8)|(u16)m_firmware_data[FIRMWARE_VERSION_POS]);
|
| #endif
|
| printk(KERN_INFO "[TSP] firmware version = %x\r\n", version);
|
|
|
| if (copy_to_user(argp, &version, sizeof(version))) return -1;
|
| }
|
| break;
|
| case TOUCH_IOCTL_START_UPGRADE:
|
| {
|
| // int ret = 0;
|
|
|
| disable_irq(misc_touch_dev->irq);
|
| down(&misc_touch_dev->work_proceedure_lock);
|
| misc_touch_dev->work_proceedure = TS_IN_UPGRADE;
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(misc_touch_dev->use_esd_timer)
|
| {
|
| ts_esd_timer_stop(misc_touch_dev);
|
| }
|
| #endif
|
|
|
| zinitix_debug_msg("clear all reported points\r\n");
|
| zinitix_clear_report_data(misc_touch_dev);
|
|
|
| //------------------------------------------------------------
|
| printk(KERN_INFO "[TSP] start upgrade firmware\n");
|
| if(ts_upgrade_firmware(misc_touch_dev, &m_firmware_data[2], misc_touch_dev->cap_info.chip_fw_size)==false)
|
| {
|
| enable_irq(misc_touch_dev->irq);
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
|
|
| //------------------------------------------------------------
|
|
|
| if(ts_init_touch(misc_touch_dev)==false)
|
| {
|
| enable_irq(misc_touch_dev->irq);
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(misc_touch_dev->use_esd_timer)
|
| {
|
| ts_esd_timer_start(ZINITIX_CHECK_ESD_TIMER, misc_touch_dev);
|
| zinitix_debug_msg("esd timer start\r\n");
|
| }
|
| #endif
|
| enable_irq(misc_touch_dev->irq);
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
|
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_GET_X_RESOLUTION:
|
| {
|
| int ret = 0;
|
| ret = misc_touch_dev->cap_info.x_resolution;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_GET_Y_RESOLUTION:
|
| {
|
| int ret = 0;
|
| ret = misc_touch_dev->cap_info.y_resolution;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_GET_X_NODE_NUM:
|
| {
|
| int ret = 0;
|
| ret = misc_touch_dev->cap_info.x_node_num;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_GET_Y_NODE_NUM:
|
| {
|
| int ret = 0;
|
| ret = misc_touch_dev->cap_info.y_node_num;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_GET_TOTAL_NODE_NUM:
|
| {
|
| int ret = 0;
|
| ret = misc_touch_dev->cap_info.total_node_num;
|
|
|
| if (copy_to_user(argp, &ret, sizeof(ret)))
|
| return -1;
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_HW_CALIBRAION:
|
| {
|
| // int value = 0;
|
| u16 mode;
|
| u16 chip_eeprom_info;
|
| int ret = -1;
|
|
|
| if(misc_touch_dev == NULL) zinitix_debug_msg("misc device NULL?\n");
|
| disable_irq(misc_touch_dev->irq);
|
| down(&misc_touch_dev->work_proceedure_lock);
|
| if(misc_touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| printk(KERN_INFO"[TSP] other process occupied.. (%d)\r\n", misc_touch_dev->work_proceedure);
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
| misc_touch_dev->work_proceedure = TS_HW_CALIBRAION;
|
|
|
|
|
| // h/w calibration
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_TOUCH_MODE, 0x07)!=I2C_SUCCESS) goto fail_hw_cal;
|
| if (ts_write_cmd(misc_touch_dev->client, ZINITIX_CALIBRATE_CMD)!=I2C_SUCCESS) goto fail_hw_cal;
|
| if (ts_write_cmd(misc_touch_dev->client, ZINITIX_SWRESET_CMD)!=I2C_SUCCESS) goto fail_hw_cal;
|
| mdelay(1);
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| // wait for h/w calibration
|
| do{
|
| mdelay(1000);
|
| if (ts_read_data(misc_touch_dev->client, ZINITIX_EEPROM_INFO_REG, (u8*)&chip_eeprom_info, 2)<0) goto fail_hw_cal;
|
| zinitix_debug_msg("touch eeprom info = 0x%04X\r\n", chip_eeprom_info);
|
| if(!zinitix_bit_test(chip_eeprom_info, 0)) break;
|
| }while(1);
|
|
|
| #if BT4x3_Above_Series
|
| mdelay(10);
|
| if (ts_write_cmd(misc_touch_dev->client, ZINITIX_SAVE_CALIBRATION_CMD)!=I2C_SUCCESS) goto fail_hw_cal;
|
| mdelay(500);
|
| #endif
|
| ret = 0;
|
| fail_hw_cal:
|
| if(misc_touch_dev->raw_mode_flag == TOUCH_NORMAL_MODE)
|
| mode = TOUCH_MODE;
|
| else
|
| mode = misc_touch_dev->raw_mode_flag;
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_TOUCH_MODE, mode)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITX_TOUCH_MODE %d.\r\n", mode);
|
| goto fail_hw_cal2;
|
| }
|
|
|
| if (ts_write_cmd(misc_touch_dev->client, ZINITIX_SWRESET_CMD)!=I2C_SUCCESS) goto fail_hw_cal2;
|
|
|
| #if BT4x2_Series
|
| if (ts_write_cmd(misc_touch_dev->client, ZINITIX_SAVE_STATUS_CMD)!=I2C_SUCCESS) goto fail_hw_cal2;
|
| mdelay(1000); // for fusing eeprom
|
| if (ts_write_cmd(misc_touch_dev->client, ZINITIX_SWRESET_CMD)!=I2C_SUCCESS) goto fail_hw_cal2;
|
| #endif
|
| enable_irq(misc_touch_dev->irq);
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return ret;
|
| fail_hw_cal2:
|
| enable_irq(misc_touch_dev->irq);
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
| break;
|
|
|
| case TOUCH_IOCTL_SET_RAW_DATA_MODE:
|
| {
|
|
|
| int value = 0;
|
| if(misc_touch_dev == NULL)
|
| {
|
| zinitix_debug_msg("misc device NULL?\n");
|
| return -1;
|
| }
|
|
|
| down(&misc_touch_dev->work_proceedure_lock);
|
| if(misc_touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| printk(KERN_INFO"[TSP] other process occupied.. (%d)\r\n", misc_touch_dev->work_proceedure);
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
| misc_touch_dev->work_proceedure = TS_SET_MODE;
|
|
|
| if(copy_from_user(&value, argp, 4))
|
| {
|
| printk(KERN_INFO "[zinitix_touch] error : copy_from_user\r\n");
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| return -1;
|
| }
|
| /*
|
| if(value != TOUCH_ZINITIX_BASELINED_RAW_MODE && value != TOUCH_ZINITIX_PROCESSED_RAW_MODE
|
| && value != TOUCH_ZINITIX_CAL_N_MODE && value != TOUCH_NORMAL_MODE)
|
| {
|
| printk(KERN_WARNING "[zinitix ts] test mode setting value error. you must set %d[=normal] or %d[=raw mode]\r\n", TOUCH_NORMAL_MODE, TOUCH_ZINITIX_BASELINED_RAW_MODE);
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return 0;
|
| }
|
| */
|
|
|
|
|
|
|
| zinitix_debug_msg("[zinitix_touch] zinitix_set_testmode, touchkey_testmode = %d\r\n", misc_touch_dev->raw_mode_flag);
|
|
|
| if(value == TOUCH_NORMAL_MODE && misc_touch_dev->raw_mode_flag != TOUCH_NORMAL_MODE) // Å×½ºÆ® ¸ðµå ÇØÁ¦½Ã
|
| {
|
| misc_touch_dev->raw_mode_flag = value;
|
| printk(KERN_INFO "[zinitix_touch] raw data mode exit\r\n");
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_ESD_TIMER_INTERVAL)!=I2C_SUCCESS)
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITIX_PERIODICAL_INTERRUPT_INTERVAL.\r\n");
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_TOUCH_MODE, TOUCH_MODE)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITX_TOUCH_MODE %d.\r\n", TOUCH_MODE);
|
| }
|
| // clear garbage data
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| mdelay(100);
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| }
|
| else if(value != TOUCH_NORMAL_MODE)// Å×½ºÆ® ¸ðµå ÁøÀÔ½Ã
|
| {
|
| misc_touch_dev->raw_mode_flag = value;
|
| printk(KERN_INFO "[zinitix_touch] raw data mode enter\r\n");
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, ZINITIX_SCAN_RATE_HZ*ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL)!=I2C_SUCCESS)
|
| printk(KERN_INFO "[zinitix_touch] Fail to set ZINITIX_RAW_DATA_ESD_TIMER_INTERVAL.\r\n");
|
|
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_TOUCH_MODE, misc_touch_dev->raw_mode_flag)!=I2C_SUCCESS)
|
| {
|
| printk(KERN_INFO "[zinitix_touch] raw data mode : Fail to set ZINITX_TOUCH_MODE %d.\r\n", misc_touch_dev->raw_mode_flag);
|
| }
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| // clear garbage data
|
| mdelay(100);
|
| ts_write_cmd(misc_touch_dev->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
| //memset(&misc_touch_dev->reported_touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
| //memset(&misc_touch_dev->touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
| }
|
|
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return 0;
|
|
|
| }
|
| break;
|
| case TOUCH_IOCTL_GET_REG:
|
| {
|
| _reg_ioctl reg_ioctl;
|
| u16 val;
|
| int ret =0;
|
| int nval;
|
|
|
| if(misc_touch_dev == NULL)
|
| {
|
| zinitix_debug_msg("misc device NULL?\n");
|
| return -1;
|
| }
|
| down(&misc_touch_dev->work_proceedure_lock);
|
| if(misc_touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| printk(KERN_INFO"[TSP] other process occupied.. (%d)\r\n", misc_touch_dev->work_proceedure);
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
|
|
| misc_touch_dev->work_proceedure = TS_SET_MODE;
|
|
|
| if(copy_from_user(®_ioctl, argp, sizeof(_reg_ioctl)))
|
| {
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| printk(KERN_INFO "[zinitix_touch] error : copy_from_user\r\n");
|
| return -1;
|
| }
|
|
|
| if (ts_read_data(misc_touch_dev->client, reg_ioctl.addr, (u8*)&val, 2)<0) ret = -1;
|
|
|
| nval = (int)val;
|
|
|
| if (copy_to_user(reg_ioctl.val, (u8*)&nval, 4))
|
| {
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| printk(KERN_INFO "[zinitix_touch] error : copy_to_user\r\n");
|
| return -1;
|
| }
|
|
|
| zinitix_debug_msg("read register : register address = 0x%x, value = 0x%x\r\n", reg_ioctl.addr, nval);
|
|
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return ret;
|
| }
|
| case TOUCH_IOCTL_SET_REG:
|
| {
|
| _reg_ioctl reg_ioctl;
|
| int ret =0;
|
| int val;
|
|
|
| if(misc_touch_dev == NULL)
|
| {
|
| zinitix_debug_msg("misc device NULL?\n");
|
| return -1;
|
| }
|
| down(&misc_touch_dev->work_proceedure_lock);
|
| if(misc_touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| printk(KERN_INFO"[TSP] other process occupied.. (%d)\r\n", misc_touch_dev->work_proceedure);
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
|
|
| misc_touch_dev->work_proceedure = TS_SET_MODE;
|
|
|
| if(copy_from_user(®_ioctl, argp, sizeof(_reg_ioctl)))
|
| {
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| printk(KERN_INFO "[zinitix_touch] error : copy_from_user\r\n");
|
| return -1;
|
| }
|
|
|
| if(copy_from_user(&val, reg_ioctl.val, 4))
|
| {
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| printk(KERN_INFO "[zinitix_touch] error : copy_from_user\r\n");
|
| return -1;
|
| }
|
|
|
| if (ts_write_reg(misc_touch_dev->client, reg_ioctl.addr, val)!=I2C_SUCCESS)
|
| ret = -1;
|
|
|
| zinitix_debug_msg("write register : register address = 0x%x, value = 0x%x\r\n", reg_ioctl.addr, val);
|
|
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return ret;
|
| }
|
| case TOUCH_IOCTL_DONOT_TOUCH_EVENT:
|
| {
|
| int ret =0;
|
|
|
| if(misc_touch_dev == NULL)
|
| {
|
| zinitix_debug_msg("misc device NULL?\n");
|
| return -1;
|
| }
|
| down(&misc_touch_dev->work_proceedure_lock);
|
| if(misc_touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| printk(KERN_INFO"[TSP] other process occupied.. (%d)\r\n", misc_touch_dev->work_proceedure);
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
|
|
| misc_touch_dev->work_proceedure = TS_SET_MODE;
|
| if (ts_write_reg(misc_touch_dev->client, ZINITIX_INT_ENABLE_FLAG, 0)!=I2C_SUCCESS) ret = -1;
|
|
|
| zinitix_debug_msg("write register : register address = 0x%x, value = 0x0\r\n", ZINITIX_INT_ENABLE_FLAG);
|
|
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return ret;
|
| }
|
| break;
|
| case TOUCH_IOCTL_SEND_SAVE_STATUS:
|
| {
|
| int ret =0;
|
|
|
| if(misc_touch_dev == NULL)
|
| {
|
| zinitix_debug_msg("misc device NULL?\n");
|
| return -1;
|
| }
|
| down(&misc_touch_dev->work_proceedure_lock);
|
| if(misc_touch_dev->work_proceedure != TS_NO_WORK)
|
| {
|
| printk(KERN_INFO"[TSP] other process occupied.. (%d)\r\n", misc_touch_dev->work_proceedure);
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
| misc_touch_dev->work_proceedure = TS_SET_MODE;
|
| ret = 0;
|
| if (ts_write_cmd(misc_touch_dev->client, ZINITIX_SAVE_STATUS_CMD)!=I2C_SUCCESS) ret =-1;
|
| mdelay(1000); // for fusing eeprom
|
|
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return ret;
|
| }
|
| case TOUCH_IOCTL_GET_RAW_DATA:
|
| {
|
| _raw_ioctl raw_ioctl;
|
| u8 *u8Data;
|
| int i, j, total_cal_n;
|
| u8 div_node;
|
|
|
| if(misc_touch_dev == NULL)
|
| {
|
| zinitix_debug_msg("misc device NULL?\n");
|
| return -1;
|
| }
|
|
|
| if(misc_touch_dev->raw_mode_flag == TOUCH_NORMAL_MODE) return -1;
|
|
|
| down(&misc_touch_dev->raw_data_lock);
|
| if(misc_touch_dev->update==0)
|
| {
|
| up(&misc_touch_dev->raw_data_lock);
|
| return -2;
|
| }
|
|
|
| if(copy_from_user(&raw_ioctl, argp, sizeof(raw_ioctl)))
|
| {
|
| up(&misc_touch_dev->raw_data_lock);
|
| printk(KERN_INFO "[zinitix_touch] error : copy_from_user\r\n");
|
| return -1;
|
| }
|
|
|
| misc_touch_dev->update = 0;
|
|
|
| u8Data = (u8*)&misc_touch_dev->cur_data[0];
|
| if(misc_touch_dev->raw_mode_flag == TOUCH_ZINITIX_CAL_N_MODE)
|
| {
|
| #if BT4x2_Series
|
| j = 0;
|
| u8Data = (u8*)&misc_touch_dev->cur_data[1];
|
| for(i=0; i<160; i++)
|
| {
|
| if((i*2)%16 < misc_touch_dev->cap_info.y_node_num)
|
| {
|
| misc_touch_dev->ref_data[j*2] = misc_touch_dev->cur_data[0] - (u16)u8Data[i*2];
|
| misc_touch_dev->ref_data[j*2+1] = misc_touch_dev->cur_data[0] - (u16)u8Data[i*2+1];
|
| j++;
|
| }
|
| }
|
| #endif
|
|
|
| #if BT4x3_Above_Series
|
| j = 0;
|
| total_cal_n = misc_touch_dev->cap_info.total_cal_n;
|
| if(total_cal_n == 0) total_cal_n = MAX_TEST_RAW_DATA;
|
|
|
| div_node = (u8)misc_touch_dev->cap_info.max_y_node;
|
| if(div_node == 0) div_node = X_RAW_DATA;
|
| u8Data = (u8*)&misc_touch_dev->cur_data[0];
|
| for(i=0; i<total_cal_n; i++)
|
| {
|
| if((i*2)%div_node < misc_touch_dev->cap_info.y_node_num)
|
| {
|
| misc_touch_dev->ref_data[j*2] = (u16)u8Data[i*2];
|
| misc_touch_dev->ref_data[j*2+1] = (u16)u8Data[i*2+1];
|
| j++;
|
| }
|
| }
|
| #endif
|
| u8Data = (u8*)&misc_touch_dev->ref_data[0];
|
| }
|
|
|
| if (copy_to_user(raw_ioctl.buf, (u8*)u8Data, raw_ioctl.sz))
|
| {
|
| up(&misc_touch_dev->raw_data_lock);
|
| return -1;
|
| }
|
|
|
| up(&misc_touch_dev->raw_data_lock);
|
|
|
| return 0;
|
| }
|
|
|
| default:
|
| break;
|
| }
|
| return 0;
|
|
|
| }
|
|
|
| #endif //USE_TEST_RAW_TH_DATA_MODE
|
|
|
|
|
| static int zinitix_touch_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id)
|
| {
|
| int ret;
|
| zinitix_touch_dev* touch_dev;
|
| int i;
|
|
|
| #if defined (CONFIG_TOUCHSCREEN_ATMEL_I2C)
|
| extern int mxt_probe_ok;
|
|
|
| if(mxt_probe_ok == 1)
|
| {
|
| zinitix_debug_msg("probe return+\r\n");
|
| return -ENODEV;
|
| }
|
| #endif
|
|
|
|
|
| #if BT4x2_Series
|
| zinitix_debug_msg("BT4x2 Driver\r\n");
|
| #endif
|
|
|
| #if BT4x3_Above_Series
|
| zinitix_debug_msg("Above BT4x3 Driver\r\n");
|
| #endif
|
| printk(KERN_INFO "[zinitix touch] driver version = %s\r\n", TS_DRVIER_VERSION);
|
|
|
| #if TOUCH_USING_ISP_METHOD
|
| if(strcmp(client->name, ZINITIX_ISP_NAME) == 0)
|
| {
|
| printk(KERN_INFO "[TSP] isp client probe \r\n");
|
| m_isp_client = client;
|
| return 0;
|
| }
|
| #endif
|
| #if 0
|
| init_hw();
|
| #endif
|
| zinitix_debug_msg("zinitix_touch_probe+\r\n");
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(1000);
|
| // ts_power_control(touch_dev, POWER_ON); //power on
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(1); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(1); //SEC_DRIVER
|
| touch_power_control(1); //PSJ
|
| // ts_power_control(touch_dev, RESET_HIGH); //reset pin high
|
| mdelay(CHIP_ON_DELAY);
|
| mdelay(500);
|
|
|
| zinitix_debug_msg("i2c check function \r\n");
|
| if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
| printk(KERN_ERR "[TSP] error : not compatible i2c function \r\n");
|
| ret = -ENODEV;
|
| goto err_check_functionality;
|
| }
|
|
|
| zinitix_debug_msg("touch data alloc \r\n");
|
| touch_dev = kzalloc(sizeof(zinitix_touch_dev), GFP_KERNEL);
|
| if (!touch_dev) {
|
| printk(KERN_ERR "[TSP] unabled to allocate touch data \r\n");
|
| ret = -ENOMEM;
|
| goto err_alloc_dev_data;
|
| }
|
| touch_dev->client = client;
|
| i2c_set_clientdata(client, touch_dev);
|
|
|
| global_touch_dev = touch_dev;
|
|
|
| #if RESET_CONTROL
|
| if(gpio_request(SYSTEM_RESET_PIN, "zinitix_reset_pin"))
|
| {
|
| printk(KERN_ERR "[TSP] error : could not obtain gpio for reset pin\r\n");
|
| touch_dev->reset_gpio_num = -ENODEV;
|
| }
|
| else
|
| {
|
| // output
|
| gpio_direction_output(SYSTEM_RESET_PIN, 1);
|
| touch_dev->reset_gpio_num = SYSTEM_RESET_PIN;
|
| // ts_power_control(touch_dev, RESET_HIGH);
|
| }
|
|
|
| mdelay(CHIP_ON_DELAY);
|
| #endif
|
|
|
| zinitix_debug_msg("allocate input device \r\n");
|
| touch_dev->input_dev = input_allocate_device();
|
| if (touch_dev->input_dev == 0) {
|
| printk(KERN_ERR "[TSP] unabled to allocate input device \r\n");
|
| ret = -ENOMEM;
|
| goto err_input_allocate_device;
|
| }
|
|
|
| //initialize zinitix touch ic
|
| touch_dev->int_gpio_num = client->irq; // for upgrade
|
| zinitixTsp_irq=client->irq;
|
|
|
| memset(&touch_dev->reported_touch_info, 0x0, sizeof(_ts_zinitix_point_info));
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| touch_dev->raw_mode_flag = TOUCH_NORMAL_MODE; // not test mode
|
| #endif
|
|
|
| ts_init_touch(touch_dev);
|
|
|
| touch_dev->use_esd_timer = 0;
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| INIT_WORK(&touch_dev->tmr_work, zinitix_touch_tmr_work);
|
|
|
| zinitix_tmr_workqueue = create_singlethread_workqueue("zinitix_tmr_workqueue");
|
| if (!zinitix_tmr_workqueue)
|
| {
|
| printk(KERN_ERR "unabled to create touch tmr work queue \r\n");
|
| ret = -1;
|
| goto err_kthread_create_failed;
|
| }
|
|
|
| touch_dev->use_esd_timer = 1;
|
| ts_esd_timer_init(touch_dev);
|
| ts_esd_timer_start(ZINITIX_CHECK_ESD_TIMER, touch_dev);
|
| printk(KERN_INFO "[TSP] ts_esd_timer_start\n");
|
| #endif
|
|
|
| touch_class = class_create(THIS_MODULE, "touch");
|
| if (IS_ERR(touch_class))
|
| pr_err("[TSP] Failed to create class(touch)!\n");
|
| firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware");
|
| if (IS_ERR(firmware_dev))
|
| pr_err("[TSP] Failed to create device(firmware)!\n");
|
| if (device_create_file(firmware_dev, &dev_attr_firmware_ver) < 0)
|
| pr_err("[TSP] Failed to create device file(%s)!\n", dev_attr_firmware_ver.attr.name);
|
| if (device_create_file(firmware_dev, &dev_attr_sw_ver) < 0)
|
| pr_err("[TSP] Failed to create device file(%s)!\n", dev_attr_sw_ver.attr.name);
|
| if (device_create_file(firmware_dev, &dev_attr_tsp_StartCall) < 0)
|
| pr_err("[TSP] Failed to create device file(%s)!\n", dev_attr_tsp_StartCall.attr.name);
|
| if (device_create_file(firmware_dev, &dev_attr_tsp_EndCall) < 0)
|
| pr_err("[TSP] Failed to create device file(%s)!\n", dev_attr_tsp_EndCall.attr.name);
|
| if (device_create_file(firmware_dev, &dev_attr_debug_xy) < 0)
|
| pr_err("[TSP] Failed to create device file(%s)!\n", dev_attr_debug_xy.attr.name);
|
| if (device_create_file(firmware_dev, &dev_attr_fw_update) < 0)
|
| pr_err("[TSP] Failed to create device file(%s)!\n", dev_attr_fw_update.attr.name);
|
| if (device_create_file(firmware_dev, &dev_attr_fw_upstatus) < 0)
|
| pr_err("[TSP] Failed to create device file(%s)!\n", dev_attr_fw_upstatus.attr.name);
|
| sprintf(touch_dev->phys, "input(ts)");
|
| touch_dev->input_dev->name = ZINITIX_DRIVER_NAME;
|
| //touch_dev->input_dev->phys = "zinitix_touch/input0"; // <- for compatability
|
| touch_dev->input_dev->id.bustype = BUS_I2C;
|
| touch_dev->input_dev->id.vendor = 0x0001;
|
| touch_dev->input_dev->phys = touch_dev->phys;
|
| touch_dev->input_dev->id.product = 0x0002;
|
| touch_dev->input_dev->id.version = 0x0100;
|
| //touch_dev->input_dev->dev.parent = &client->dev;
|
|
|
| set_bit(EV_SYN, touch_dev->input_dev->evbit);
|
| set_bit(EV_KEY, touch_dev->input_dev->evbit);
|
| set_bit(BTN_TOUCH, touch_dev->input_dev->keybit);
|
| set_bit(EV_ABS, touch_dev->input_dev->evbit);
|
| set_bit(INPUT_PROP_DIRECT, touch_dev->input_dev->propbit);
|
|
|
| for(i=0; i< MAX_SUPPORTED_BUTTON_NUM; i++)
|
| set_bit(BUTTON_MAPPING_KEY[i], touch_dev->input_dev->keybit);
|
|
|
|
|
| if (touch_dev->cap_info.Orientation & TOUCH_XY_SWAP)
|
| {
|
| input_set_abs_params(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->cap_info.MinX, touch_dev->cap_info.MaxX + ABS_PT_OFFSET, 0, 0);
|
| input_set_abs_params(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->cap_info.MinY, touch_dev->cap_info.MaxY + ABS_PT_OFFSET, 0, 0);
|
| }
|
| else
|
| {
|
| input_set_abs_params(touch_dev->input_dev, ABS_MT_POSITION_X, touch_dev->cap_info.MinX, touch_dev->cap_info.MaxX + ABS_PT_OFFSET, 0, 0);
|
| input_set_abs_params(touch_dev->input_dev, ABS_MT_POSITION_Y, touch_dev->cap_info.MinY, touch_dev->cap_info.MaxY + ABS_PT_OFFSET, 0, 0);
|
| }
|
|
|
| input_set_abs_params(touch_dev->input_dev, ABS_TOOL_WIDTH, 0, 255, 0, 0);
|
| input_set_abs_params(touch_dev->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
|
| input_set_abs_params(touch_dev->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
|
|
|
| zinitix_debug_msg("register %s input device \r\n", touch_dev->input_dev->name);
|
| ret = input_register_device(touch_dev->input_dev);
|
| if(ret) {
|
| printk(KERN_ERR "[TSP] unable to register %s input device\r\n", touch_dev->input_dev->name);
|
| goto err_input_register_device;
|
| }
|
|
|
| /* configure touchscreen interrupt gpio */
|
| ret = gpio_request(TSP_INT, "zinitix_irq_gpio");
|
| if (ret) {
|
| printk(KERN_ERR "[TSP] unable to request gpio.(%s)\r\n", touch_dev->input_dev->name);
|
| goto err_request_irq;
|
| }
|
|
|
| ret = gpio_direction_input(irq_to_gpio(zinitixTsp_irq));
|
|
|
| touch_dev->int_gpio_num = TSP_INT;
|
|
|
| #ifdef GPIO_TOUCH_IRQ
|
| touch_dev->irq = GPIO_TOUCH_IRQ;
|
| #else
|
| touch_dev->irq = gpio_to_irq(touch_dev->int_gpio_num);
|
| if(touch_dev->irq < 0)
|
| {
|
| printk(KERN_INFO "[TSP] error. gpio_to_irq(..) function is not supported? you should define GPIO_TOUCH_IRQ.\r\n");
|
| }
|
| #endif
|
| zinitix_debug_msg("request irq (irq = %d, pin = %d) \r\n", touch_dev->irq, touch_dev->int_gpio_num);
|
|
|
| touch_dev->work_proceedure = TS_NO_WORK;
|
| sema_init(&touch_dev->work_proceedure_lock, 1);
|
|
|
|
|
| ret = request_threaded_irq(touch_dev->irq, NULL, ts_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "zinitix_ts", touch_dev);
|
| if (ret) {
|
| dev_err(&client->dev, "failed to request irq %d\n", touch_dev->irq);
|
| goto err_request_irq;
|
| }
|
|
|
| dev_info(&client->dev, "zinitix touch probe.\r\n");
|
|
|
| #ifdef CONFIG_HAS_EARLYSUSPEND
|
| touch_dev->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
|
| touch_dev->early_suspend.suspend = zinitix_early_suspend;
|
| touch_dev->early_suspend.resume = zinitix_late_resume;
|
| register_early_suspend(&touch_dev->early_suspend);
|
| #endif
|
|
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| sema_init(&touch_dev->raw_data_lock, 1);
|
|
|
| misc_touch_dev = touch_dev;
|
|
|
| // Fops Device
|
| ret = misc_register(&touch_misc_device);
|
| if (ret) {
|
| zinitix_debug_msg("Fail to register touch misc device.\n");
|
| }
|
|
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_get_touch_test_raw_data)<0) //sys/class/misc/touch_misc_fops/....
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_get_touch_test_raw_data.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_tkey_reference)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_tkey_reference.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_touch_reference)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_touch_reference.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_delta)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_delta.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_scantime)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_scantime.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_enter_testmode)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_enter_testmode.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_enter_scanmode)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_enter_scanmode.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_enter_normalmode)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_enter_normalmode.attr.name);
|
| if (device_create_file(touch_misc_device.this_device, &dev_attr_count_node) < 0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_count_node.attr.name);
|
| if (device_create_file(touch_misc_device.this_device, &dev_attr_chip_info) < 0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_chip_info.attr.name);
|
| if (device_create_file(touch_misc_device.this_device, &dev_attr_menu_sensitivity) < 0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_menu_sensitivity.attr.name);
|
| if (device_create_file(touch_misc_device.this_device, &dev_attr_back_sensitivity) < 0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_back_sensitivity.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_touch_ndata)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_touch_ndata.attr.name);
|
| if(device_create_file(touch_misc_device.this_device, &dev_attr_tkey_data)<0)
|
| printk("[TSP] Failed to create device file(%s)!\n", dev_attr_tkey_data.attr.name);
|
| #endif
|
| #ifdef KEY_LED_CONTROL
|
| // init_timer(&g_led_timer);
|
| // g_led_timer.function = TouchKey_Led_TimerProc;
|
|
|
| if (device_create_file(touch_misc_device.this_device, &dev_attr_brightness) < 0) {
|
| printk("[TSP] %s device_create_file fail dev_attr_touch_update\n",__FUNCTION__);
|
| pr_err("[TSP] Failed to create device file(%s)!\n",dev_attr_brightness.attr.name);
|
| }
|
| #endif
|
| return 0;
|
|
|
| err_request_irq:
|
| input_unregister_device(touch_dev->input_dev);
|
| err_input_register_device:
|
| input_free_device(touch_dev->input_dev);
|
| //err_kthread_create_failed:
|
| err_input_allocate_device:
|
| kfree(touch_dev);
|
| err_alloc_dev_data:
|
| err_check_functionality:
|
| // touch_power_onoff(0); //SEC_DRIVER
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator(0); //SEC_DRIVER
|
| #endif
|
| //PSJ touch_ctrl_regulator(0); //SEC_DRIVER
|
| touch_power_control(0); //PSJ
|
| mdelay(CHIP_POWER_OFF_DELAY);
|
|
|
| return ret;
|
| }
|
|
|
|
|
| static int zinitix_touch_remove(struct i2c_client *client)
|
| {
|
| zinitix_touch_dev *touch_dev = i2c_get_clientdata(client);
|
|
|
| zinitix_debug_msg("zinitix_touch_remove+ \r\n");
|
| down(&touch_dev->work_proceedure_lock);
|
| touch_dev->work_proceedure = TS_REMOVE_WORK;
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(touch_dev->use_esd_timer)
|
| {
|
| flush_work(&touch_dev->tmr_work);
|
| ts_write_reg(touch_dev->client, ZINITIX_PERIODICAL_INTERRUPT_INTERVAL, 0);
|
| ts_esd_timer_stop(touch_dev);
|
| zinitix_debug_msg(KERN_INFO " ts_esd_timer_stop\n");
|
| destroy_workqueue(zinitix_tmr_workqueue);
|
| }
|
| #endif
|
| if (touch_dev->irq) {
|
| free_irq(touch_dev->irq, touch_dev);
|
| }
|
|
|
| #if USE_TEST_RAW_TH_DATA_MODE
|
| device_remove_file(touch_misc_device.this_device, &dev_attr_get_touch_test_raw_data);
|
| misc_deregister(&touch_misc_device);
|
| #endif
|
| #ifdef CONFIG_HAS_EARLYSUSPEND
|
| unregister_early_suspend(&touch_dev->early_suspend);
|
| #endif
|
|
|
| if(gpio_is_valid(touch_dev->int_gpio_num))
|
| gpio_free(touch_dev->int_gpio_num);
|
|
|
| #if RESET_CONTROL
|
| if(gpio_is_valid(touch_dev->reset_gpio_num))
|
| gpio_free(touch_dev->reset_gpio_num);
|
| #endif
|
| input_unregister_device(touch_dev->input_dev);
|
| input_free_device(touch_dev->input_dev);
|
| up(&touch_dev->work_proceedure_lock);
|
| kfree(touch_dev);
|
|
|
| return 0;
|
| }
|
|
|
| static int __devinit zinitix_touch_init(void)
|
| {
|
| printk("[TSP] zinitix_touch_init ! \n");
|
| return i2c_add_driver(&zinitix_touch_driver);
|
| }
|
|
|
| static void __exit zinitix_touch_exit(void)
|
| {
|
| i2c_del_driver(&zinitix_touch_driver);
|
| }
|
|
|
| static ssize_t firmware_sw_show(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| // int ret;
|
| u16 sw_version;
|
| // u16 chip_reg_data_version;
|
|
|
| printk("[TSP] %s\n",__func__);
|
|
|
| //sw_version = (u16)(((u16)m_firmware_data[FIRMWARE_VERSION_POS+1]<<8)|(u16)m_firmware_data[FIRMWARE_VERSION_POS]);
|
| sw_version = (u16) (m_firmware_data[FIRMWARE_VERSION_POS+2] | (m_firmware_data[FIRMWARE_VERSION_POS+3]<<8));
|
| printk("[TSP] phone ver firmware=%x\n", sw_version);
|
| return sprintf(buf, "%d\n", sw_version);
|
| }
|
|
|
| static ssize_t firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| u16 phone_version;
|
| printk("[TSP] %s\n",__func__);
|
|
|
| /* get chip firmware version */
|
| //phone_version = global_touch_dev->cap_info.chip_firmware_version;
|
| if (ts_read_data(global_touch_dev->client, ZINITIX_DATA_VERSION_REG, (u8*)&phone_version, 2)<0);
|
| printk(KERN_INFO "zinitix touch chip firmware version = %x\r\n", phone_version);
|
|
|
| return sprintf(buf, "%d\n", phone_version);
|
| }
|
|
|
| static ssize_t tsp_StartCall_show(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| printk("%s, %d\n", __func__, IsDuringCall);
|
|
|
| IsDuringCall = 1;
|
|
|
| return sprintf(buf, "%d", IsDuringCall);
|
| }
|
|
|
| static ssize_t tsp_EndCall_show(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| printk("%s, %d\n", __func__, IsDuringCall);
|
|
|
| IsDuringCall = 0;
|
|
|
| return sprintf(buf, "%d", IsDuringCall);
|
| }
|
|
|
| int Is_DuringCall(void)
|
| {
|
| return IsDuringCall;
|
| }
|
| static ssize_t tsp_xy_show(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| printk("%s, %d\n", __func__, IsdebugMatrix);
|
|
|
| if(IsdebugMatrix)
|
| IsdebugMatrix = 0;
|
| else
|
| IsdebugMatrix = 1;
|
|
|
| return sprintf(buf, "%d", IsdebugMatrix);
|
| }
|
| static ssize_t firmware_update(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| // int ret = 0;
|
| printk("[TSP] %s\n",__func__);
|
| IsfwUpdate = FWUP_ON;
|
|
|
| disable_irq(misc_touch_dev->irq);
|
| down(&misc_touch_dev->work_proceedure_lock);
|
| misc_touch_dev->work_proceedure = TS_IN_UPGRADE;
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(misc_touch_dev->use_esd_timer)
|
| {
|
| ts_esd_timer_stop(misc_touch_dev);
|
| }
|
| #endif
|
|
|
| zinitix_debug_msg("clear all reported points\r\n");
|
| zinitix_clear_report_data(misc_touch_dev);
|
| if(ts_init_touch(misc_touch_dev)==false)
|
| {
|
| enable_irq(misc_touch_dev->irq);
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| return -1;
|
| }
|
|
|
| #if ZINITIX_ESD_TIMER_INTERVAL
|
| if(misc_touch_dev->use_esd_timer)
|
| {
|
| ts_esd_timer_start(ZINITIX_CHECK_ESD_TIMER, misc_touch_dev);
|
| zinitix_debug_msg("esd timer start\r\n");
|
| }
|
| #endif
|
| enable_irq(misc_touch_dev->irq);
|
| misc_touch_dev->work_proceedure = TS_NO_WORK;
|
| up(&misc_touch_dev->work_proceedure_lock);
|
| IsfwUpdate = FWUP_OFF;
|
| printk("\n[TSP] success firmware_update\n");
|
| return 0;
|
|
|
| }
|
| static ssize_t firmware_update_status(struct device *dev, struct device_attribute *attr, char *buf)
|
| {
|
| // int ret;
|
| printk("[TSP] %s\n",__func__);
|
|
|
| return sprintf(buf, "%d\n", IsfwUpdate);
|
| }
|
| #ifdef SEC_DRIVER
|
|
|
| // configurate things related to hw such as gpio, regulator levels, ...
|
| void init_hw(void)
|
| {
|
| int err = gpio_request(TSP_EN, "TSP_EN");
|
| int err1 = gpio_request(TSP_KEY_LED, "TSP_KEY_LED");
|
| // gpio_tlmm_config(GPIO_CFG(TSP_SCL, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA),GPIO_CFG_ENABLE);
|
| // gpio_tlmm_config(GPIO_CFG(TSP_SDA, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA),GPIO_CFG_ENABLE);
|
| // gpio_tlmm_config(GPIO_CFG(TSP_INT, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_16MA),GPIO_CFG_ENABLE);
|
| // gpio_tlmm_config(GPIO_CFG(TSP_EN, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_16MA),GPIO_CFG_ENABLE);
|
|
|
| // gpio_set_value( TSP_SCL , 1 );
|
| // gpio_set_value( TSP_SDA , 1 );
|
| gpio_direction_output( TSP_EN , 1 );
|
| #ifdef CONFIG_TREBON_HW01
|
| //PSJ touch_io_ctrl_regulator( 1 );
|
| #endif
|
| //PSJ touch_ctrl_regulator( 1 );
|
| touch_power_control(1); //PSJ
|
|
|
| msleep(500);
|
| }
|
|
|
| int touch_power_onoff( int onoff )
|
| {
|
| gpio_direction_output( TSP_EN , onoff );
|
| return 0;
|
| }
|
|
|
| EXPORT_SYMBOL(touch_power_onoff);
|
| //EXPORT_SYMBOL(touchkey_avaliable);
|
| #endif
|
|
|
|
|
| module_init(zinitix_touch_init);
|
| module_exit(zinitix_touch_exit);
|
|
|
| MODULE_DESCRIPTION("touch-screen device driver using i2c interface");
|
| MODULE_AUTHOR("sohnet <swjang@zinitix.com>");
|
| MODULE_LICENSE("GPL");
|
|
|
|
|