--- /dev/null
+#include <linux/init.h>\r
+#include <linux/module.h>\r
+#include <linux/kernel.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/irq.h>\r
+#include <linux/i2c.h>\r
+//#include <asm/semaphore.h>\r
+#include <linux/gpio.h>\r
+#include <mach/gpio.h>\r
+#include <linux/suspend.h>\r
+#include <linux/input.h>\r
+#include <mach/hardware.h>\r
+\r
+#include <linux/semaphore.h>\r
+#include <linux/sched.h>\r
+#include <linux/delay.h>\r
+\r
+#include <mach/iomux.h>\r
+\r
+#include <mach/spi_fpga.h>\r
+\r
+extern void rk2818_mux_api_set(char *name, unsigned int mode);\r
+extern int lp8725_ldo_en(uint8_t ldo,uint8_t enble);\r
+extern int lp8725_set_ldo_vol(uint8_t ldon,uint16_t vol);\r
+extern int lp8725_set_lilo_vol(uint8_t lilon,uint16_t vol);\r
+extern int lp8725_lilo_en(uint8_t lilon,uint8_t enble);\r
+\r
+\r
+struct Ctp_it7250_data {\r
+ char status;
+ char curr_tate;
+ struct input_dev *input_dev;
+ struct i2c_client *client;
+ struct delayed_work delaywork;\r
+ int irq; /* Our chip IRQ */\r
+};\r
+static struct i2c_client *Ctp_it7250_client;\r
+\r
+#define Ctp_it7250_GPIO_INT RK2818_PIN_PE1\r
+\r
+#if 0\r
+#define rk28printk(x...) printk(x)\r
+#else\r
+#define rk28printk(x...) \r
+#endif\r
+\r
+ struct KeyInfo
+{
+ int value;\r
+ int key;\r
+};
+
+static struct KeyInfo panel_key_info[]={
+{0x01, KEY_HOME},\r
+{0x02, KEY_MENU},\r
+{0x03, KEY_BACK},\r
+{0x04, KEY_SEARCH},\r
+};\r
+\r
+#define MAX_FINGER_NUM 3\r
+//#define DEVICE_ADDRESS 0x8C\r
+#define COMMAND_BUFFER_INDEX 0x20\r
+#define QUERY_BUFFER_INDEX 0x80\r
+#define COMMAND_RESPONSE_BUFFER_INDEX 0xA0\r
+#define POINT_BUFFER_INDEX 0xE0\r
+#define QUERY_SUCCESS 0x00\r
+#define QUERY_BUSY 0x01\r
+#define QUERY_ERROR 0x02\r
+#define QUERY_POINT 0x80\r
+\r
+\r
+static u8 gpucPointBuffer[14];\r
+static u32 gpdwSampleX[3],gpdwSampleY[3],gpdwPressure[1];\r
+\r
+static int Ctp_it7250_rx_data( u8 reg,u8* rxData, int length)\r
+{\r
+#if 0\r
+ \r
+ int ret;\r
+ struct i2c_adapter *adap;int i;\r
+ struct i2c_msg msgs[2];
+ if(!Ctp_it7250_client)\r
+ return ret;
+ adap = Ctp_it7250_client->adapter;\r
+ \r
+ //·¢ËͼĴæÆ÷µØÖ·
+ msgs[0].addr = Ctp_it7250_client->addr;\r
+ msgs[0].buf = ®\r
+ msgs[0].flags = Ctp_it7250_client->flags;\r
+ msgs[0].len =1;\r
+ msgs[0].scl_rate = 400*1000;\r
+ //½ÓÊÕÊý¾Ý
+ \r
+// rk28printk("i2c addr=0x%x \r\n",msgs[0].addr);\r
+ // rk28printk("msgs[0].buf = 0x%x rxData=0x%x\n",*(msgs[0].buf),*rxData);\r
+ \r
+ msgs[1].buf = rxData;\r
+ msgs[1].addr = Ctp_it7250_client->addr;\r
+ msgs[1].flags = Ctp_it7250_client->flags | I2C_M_RD;\r
+ msgs[1].len = length;\r
+ msgs[1].scl_rate = 400*1000;\r
+
+ ret = i2c_transfer(adap, msgs, 2);
+ //DBG("**has run at %s %d ret=%d**\n",__FUNCTION__,__LINE__,ret);
+// rk28printk("\r\n msgs[1].buf = 0x%x ret=%d\n",*(msgs[1].buf),ret);\r
+\r
+\r
+ //for (i=0;i<length;i++)\r
+ // rk28printk("rxData[%d]=%d \r\n",i,rxData[i]);\r
+\r
+#else\r
+//int i;\r
+return i2c_master_reg8_recv(Ctp_it7250_client, reg, rxData, length, 400 * 1000);\r
+//for (i=0;i<length;i++)\r
+// rk28printk("rxData[%d]=%d \r\n",i,rxData[i]);\r
+#endif\r
+ \r
+}
+\r
+static int Ctp_it7250_tx_data(u8 reg,char *txData, int length)\r
+{
+#if 0\r
+ int ret,i;\r
+ struct i2c_adapter *adap = Ctp_it7250_client->adapter;\r
+ struct i2c_msg msg;\r
+ \r
+ u8 buf[128];//128\r
+// rk28printk("reg=0x%x txData=0x%x \r\n",reg,*txData);\r
+ buf[0]=reg;\r
+ for (i=0;i<length;i++)\r
+ {\r
+ buf[i+1]=*txData++;\r
+ rk28printk("buf[%d]=0x%x ",i+1,buf[i+1]);\r
+ }\r
+ rk28printk("\r\n");\r
+// rk28printk("buf[0]=0x%x buf[1]=0x%x",buf[0],buf[1]);\r
+ msg.addr = Ctp_it7250_client->addr;\r
+//rk28printk("i2c addr=0x%x",msg.addr);\r
+ msg.buf =&buf[0];\r
+ msg.len = length+1;//+1 means add the reg length;by roberts\r
+ msg.flags = Ctp_it7250_client->flags;\r
+ msg.scl_rate = 400*1000;\r
+
+ ret = i2c_transfer(adap, &msg, 1);
+return ret;\r
+#else\r
+ return i2c_master_reg8_send(Ctp_it7250_client, reg, txData, length, 400 * 1000);\r
+#endif\r
+\r
+\r
+\r
+\r
+}\r
+\r
+\r
+\r
+bool ReadQueryBuffer(u8* pucData)\r
+{\r
+ return Ctp_it7250_rx_data( QUERY_BUFFER_INDEX, pucData, 1);\r
+}\r
+\r
+bool ReadCommandResponseBuffer(u8* pucData, unsigned int unDataLength)\r
+{\r
+ return Ctp_it7250_rx_data( COMMAND_RESPONSE_BUFFER_INDEX, pucData, unDataLength);\r
+}\r
+\r
+bool ReadPointBuffer(u8* pucData)\r
+{\r
+ return Ctp_it7250_rx_data( POINT_BUFFER_INDEX, pucData, 14);\r
+}\r
+\r
+bool WriteCommandBuffer(u8* pucData, unsigned int unDataLength)\r
+{\r
+ return Ctp_it7250_tx_data(COMMAND_BUFFER_INDEX, pucData, unDataLength);\r
+}\r
+\r
+static int Ctp_it7250_touch_open(struct input_dev *idev)\r
+{\r
+ \r
+struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(Ctp_it7250_client);\r
+\r
+\r
+//BTN_TOUCH =0 means no touch ;by robert\r
+ input_report_key(Ctp_it7250->input_dev,BTN_TOUCH, 0);\r
+ input_sync(Ctp_it7250->input_dev);\r
+\r
+ return 0;\r
+}\r
+\r
+static void Ctp_it7250_touch_close(struct input_dev *idev)\r
+{\r
+return 0;\r
+}\r
+\r
+static irqreturn_t Ctp_it7250_touch_irq(int irq, void *dev_id)\r
+{ \r
+ struct Ctp_it7250_data *Ctp_it7250 = dev_id;\r
+\r
+ //rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__);\r
+ disable_irq_nosync(irq);\r
+ //rk28printk("%s++++ %d irq=%d\r\n",__FUNCTION__,__LINE__,irq);\r
+ schedule_delayed_work(&Ctp_it7250->delaywork,usecs_to_jiffies(5)); \r
+ \r
+ return IRQ_HANDLED; \r
+ \r
+}\r
+\r
+\r
+\r
+static int ts_input_init(struct i2c_client *client)\r
+{\r
+ int ret = -1,i;\r
+ struct Ctp_it7250_data *Ctp_it7250;\r
+ Ctp_it7250 = i2c_get_clientdata(client);\r
+ /* register input device */\r
+ Ctp_it7250->input_dev = input_allocate_device();\r
+ if (Ctp_it7250->input_dev == NULL) {\r
+ pr_emerg( "%s: failed to allocate input dev\n",\r
+ __FUNCTION__);\r
+ return -ENOMEM;\r
+ }\r
+rk28printk("+++++++ %s+++++++\n", __FUNCTION__);\r
+ Ctp_it7250->input_dev->name = "CTS_Ctp_it7250";\r
+ Ctp_it7250->input_dev->phys = "CTS_Ctp_it7250/input1";\r
+ \r
+ //no need to open & close it,it will do it automaticlly;noted by robert\r
+ Ctp_it7250->input_dev->open = Ctp_it7250_touch_open;\r
+ Ctp_it7250->input_dev->close = Ctp_it7250_touch_close;\r
+\r
+ __set_bit(EV_ABS, Ctp_it7250->input_dev->evbit);\r
+ __set_bit(ABS_X, Ctp_it7250->input_dev->absbit);\r
+ __set_bit(ABS_Y, Ctp_it7250->input_dev->absbit);\r
+\r
+ __set_bit(EV_SYN, Ctp_it7250->input_dev->evbit);\r
+ __set_bit(EV_KEY, Ctp_it7250->input_dev->evbit);\r
+ __set_bit(BTN_TOUCH, Ctp_it7250->input_dev->keybit);\r
+\r
+for (i = 0; i < ARRAY_SIZE(panel_key_info); i++)\r
+{rk28printk("ts_input_init i=%d\r\n",i);\r
+ __set_bit(panel_key_info[i].key,Ctp_it7250->input_dev->keybit);\r
+}\r
+ //__clear_bit(0, input_dev->keybit);\r
+\r
+ input_set_abs_params(Ctp_it7250->input_dev, ABS_X, 0, 1000, 0, 0);\r
+ input_set_abs_params(Ctp_it7250->input_dev, ABS_Y, 0, 1000, 0, 0);\r
+//pr_emerg("+++++++ %s\n", __FUNCTION__); \r
+ ret = input_register_device(Ctp_it7250->input_dev);\r
+ if (ret) {\r
+ pr_emerg(\r
+ "%s: unabled to register input device, ret = %d\n",\r
+ __FUNCTION__, ret);\r
+ return ret;\r
+ }\r
+ rk28printk("+++++++ %s+++++++END\n", __FUNCTION__);\r
+ return 0;\r
+\r
+}\r
+\r
+static void CTS_configure_pin(struct i2c_client *client)\r
+{\r
+ //add reset pin;but we not used it ;robert\r
+ //had already do it it spi_gpio.c\r
+ //end add \r
+ //RESET THE CTP;note by robert\r
+ spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_HIGH);\r
+ mdelay(5);\r
+ spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_LOW);\r
+ mdelay(5);\r
+ spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_HIGH);\r
+ mdelay(5);\r
+}\r
+\r
+static int Ctp_it7250_init_irq(struct i2c_client *client)\r
+{\r
+ struct Ctp_it7250_data *Ctp_it7250;\r
+ int ret;\r
+ \r
+ Ctp_it7250 = i2c_get_clientdata(client);\r
+ #if 1\r
+ if ( !gpio_is_valid(client->irq)) {\r
+ rk28printk("+++++++++++gpio_is_invalid\n");
+ return -EINVAL;
+ }
+ ret = gpio_request(client->irq, "Ctp_it7250_int");\r
+ if (ret) {
+ rk28printk( "failed to request Ctp_it7250_init_irq GPIO%d\n",gpio_to_irq(client->irq));\r
+ return ret;
+ }\r
+#if 1\r
+ret = gpio_direction_input(client->irq);\r
+ if (ret) {\r
+ rk28printk("failed to set CTS_configure_pin gpio input\n");\r
+ //goto err_free_gpio;\r
+ }\r
+ gpio_pull_updown(client->irq,GPIOPullUp);\r
+#endif\r
+\r
+ rk28printk("%s gpio_to_irq(%d) is %d\n",__FUNCTION__,client->irq,gpio_to_irq(client->irq));\r
+ \r
+ client->irq = gpio_to_irq(client->irq);\r
+ #endif\r
+ ret = request_irq(client->irq, Ctp_it7250_touch_irq, IRQF_TRIGGER_LOW, client->dev.driver->name, Ctp_it7250);\r
+ Ctp_it7250->irq=client->irq;\r
+ rk28printk("%s request irq is %d,irq1 is %d,ret is 0x%x\n",__FUNCTION__,client->irq,Ctp_it7250->irq,ret);\r
+ if (ret ) {
+ rk28printk(KERN_ERR "Ctp_it7250_init_irq: request irq failed,ret is %d\n",ret);\r
+ return ret;
+ }\r
+ \r
+}\r
+\r
+\r
+// ================================================================================\r
+// Function Name --- GetFirmwareInformation\r
+// Description --- Get firmware information\r
+// Input --- NULL\r
+//Output --- return true if the command execute successfully, otherwuse return false.\r
+// ================================================================================\r
+bool GetFirmwareInformation()\r
+{\r
+ u8 ucWriteLength, ucReadLength;\r
+ u8 pucData[128];\r
+ u8 ucQuery;\r
+int i;\r
+ ucWriteLength = 2;\r
+ ucReadLength = 0x09;\r
+ pucData[0] = 0x01;\r
+ pucData[1] = 0x00;\r
+\r
+ // Query\r
+ do\r
+ {\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ ucQuery = QUERY_BUSY;\r
+ }\r
+ }while(ucQuery & QUERY_BUSY);\r
+\r
+ // Write Command\r
+ if(!WriteCommandBuffer(pucData, ucWriteLength))\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // Query\r
+ do\r
+ {\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ ucQuery = QUERY_BUSY;\r
+ }\r
+ }while(ucQuery & QUERY_BUSY);\r
+ pucData[5]== 0 ;\r
+ pucData[6] == 0 ;\r
+ pucData[7] == 0 ;\r
+ pucData[8] == 0;\r
+ // Read Command Response\r
+ if(!ReadCommandResponseBuffer(pucData, ucReadLength))\r
+ {\r
+ return false;\r
+ }\r
+\r
+\r
+ \r
+for (i =0;i<ucReadLength;i++)\r
+ rk28printk("GetFirmwareInformation pucData[%d]=%d \r\n",i,pucData[i]);\r
+ if(pucData[5]== 0 \r
+ && pucData[6] == 0 \r
+ && pucData[7] == 0 \r
+ && pucData[8] == 0) \r
+ {\r
+ // There is no flash code\r
+ rk28printk("There is no flash code \r\n");\r
+ return false;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+// ================================================================================\r
+// Function Name --- SetInterruptNotification\r
+// Description --- Set It7260 interrupt mode\r
+// Input --- \r
+// ucStatus- the interrupt status\r
+// ucType- the interrupt type\r
+//Output --- return true if the command execute successfully, otherwuse return false.\r
+// ================================================================================\r
+bool SetInterruptNotification(u8 ucStatus, u8 ucType)\r
+{\r
+ u8 ucWriteLength, ucReadLength;\r
+ u8 pucData[128];\r
+ u8 ucQuery;\r
+int i;\r
+ ucWriteLength = 4;// 2\r
+ ucReadLength = 2;\r
+ pucData[0] = 0x02;\r
+ pucData[1] = 0x04;\r
+ pucData[2] = ucStatus;\r
+ pucData[3] = ucType;\r
+\r
+ // Query\r
+ do\r
+ {\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ ucQuery = QUERY_BUSY;\r
+ }\r
+ }while(ucQuery & QUERY_BUSY);\r
+\r
+ // Write Command\r
+ if(!WriteCommandBuffer(pucData, ucWriteLength))\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // Query\r
+ do\r
+ {\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ ucQuery = QUERY_BUSY;\r
+ }\r
+ }while(ucQuery & QUERY_BUSY);\r
+\r
+ // Read Command Response\r
+ if(!ReadCommandResponseBuffer(pucData, ucReadLength))\r
+ {\r
+ return false;\r
+ }\r
+\r
+for (i =0;i<ucReadLength;i++)\r
+ rk28printk("SetInterruptNotification pucData[%d]=0x%x \r\n",i,pucData[i]);\r
+ if(*(u16*) pucData != 0) \r
+ {\r
+ return false;\r
+ }\r
+ return true;\r
+}\r
+\r
+\r
+// ================================================================================\r
+// Function Name --- IdentifyCapSensor\r
+// Description --- Identify Capacitive Sensor information\r
+// Input --- NULL\r
+//Output --- return true if the command execute successfully, otherwuse return false.\r
+// ================================================================================\r
+bool IdentifyCapSensor()\r
+{\r
+ u8 ucWriteLength, ucReadLength;\r
+ u8 pucData[128];\r
+ u8 ucQuery=0;int i;\r
+\r
+ ucWriteLength = 1;\r
+ ucReadLength = 0x0A;\r
+ pucData[0] = 0x00;\r
+rk28printk("%s\r\n",__FUNCTION__);\r
+ // Query\r
+ do\r
+ {//printk("first wait 111\r\n");\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ rk28printk("first wait \r\n");\r
+ ucQuery = QUERY_BUSY;\r
+ }\r
+ rk28printk("%s ucQuery=0x%x \r\n",__FUNCTION__,ucQuery);\r
+ mdelay(500);\r
+ }while(ucQuery & QUERY_BUSY);\r
+\r
+ // Write Command\r
+ //rk28printk("%s11\r\n",__FUNCTION__);\r
+ pucData[0] = 0x00;ucWriteLength = 1;\r
+ if(!WriteCommandBuffer(pucData, ucWriteLength))\r
+ {\r
+ rk28printk("WriteCommandBuffer false \r\n");\r
+ // return false;\r
+ }\r
+//rk28printk("show1 %s\r\n",__FUNCTION__);\r
+ // Query\r
+ do\r
+ {\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ rk28printk("second wait \r\n");\r
+ ucQuery = QUERY_BUSY;\r
+ }rk28printk("%s ucQuery1=0x%x \r\n",__FUNCTION__,ucQuery);\r
+ }while(ucQuery & QUERY_BUSY);\r
+//rk28printk("show2 %s\r\n",__FUNCTION__);\r
+ // Read Command Response\r
+ for (i=0;i<ucReadLength;i++)\r
+ {pucData[i]=0x0;\r
+ rk28printk("pucData[%d]=%d \r\n",i,pucData[i]);\r
+ }\r
+ if(!ReadCommandResponseBuffer(pucData, ucReadLength))\r
+ {\r
+ rk28printk("ReadCommandResponseBuffer false \r\n");\r
+ // return false;\r
+ }\r
+//rk28printk("show %s\r\n",__FUNCTION__);\r
+for (i=0;i<ucReadLength;i++)\r
+ rk28printk("pucData[%d]=%d \r\n",i,pucData[i]);\r
+ rk28printk("pucData=%c %c %c %c %c %c %c \r\n",pucData[1],pucData[2],pucData[3],pucData[4],pucData[5],pucData[6],pucData[7]);\r
+\r
+ return true;\r
+}\r
+\r
+// ================================================================================\r
+// Function Name --- Get2DResolutions\r
+// Description --- Get the resolution of X and Y axes\r
+// Input --- \r
+// pwXResolution - the X resolution\r
+// pwYResolution - the Y resolution\r
+// pucStep - the step\r
+//Output --- return true if the command execute successfully, otherwuse return false.\r
+// ================================================================================\r
+bool Get2DResolutions(u32 *pwXResolution, u32*pwYResolution, u8 *pucStep)\r
+{\r
+ u8 ucWriteLength, ucReadLength;\r
+ u8 pucData[128];\r
+ u8 ucQuery;\r
+int i;\r
+\r
+ ucWriteLength = 3;\r
+ ucReadLength = 0x07;\r
+ pucData[0] = 0x01;\r
+ pucData[1] = 0x02;\r
+ pucData[2] = 0x00;\r
+\r
+ // Query\r
+ do\r
+ {\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ ucQuery = QUERY_BUSY;\r
+ }\r
+ }while(ucQuery & QUERY_BUSY);\r
+\r
+ // Write Command\r
+ rk28printk("%s WriteCommandBuffer\r\n",__FUNCTION__);\r
+ if(!WriteCommandBuffer(pucData, ucWriteLength))\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // Query\r
+ do\r
+ {\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ ucQuery = QUERY_BUSY;\r
+ }\r
+ }while(ucQuery & QUERY_BUSY);\r
+rk28printk("%s ReadCommandResponseBuffer\r\n",__FUNCTION__);\r
+ // Read Command Response\r
+ if(!ReadCommandResponseBuffer(pucData, ucReadLength))\r
+ {\r
+ return false;\r
+ }\r
+rk28printk("%s ReadCommandResponseBuffer EDN\r\n",__FUNCTION__);\r
+\r
+ for (i=0;i<ucReadLength;i++)\r
+ rk28printk("pucData[%d] = 0x%x \r\n",i,pucData[i]);\r
+ \r
+ if(pwXResolution != NULL) \r
+ {\r
+ *pwXResolution = (pucData[2] | (pucData[3] << 8));\r
+ }\r
+ if(pwYResolution!= NULL) \r
+ {\r
+ * pwYResolution = (pucData[4] | (pucData[5] << 8));\r
+ }\r
+ if(pucStep!= NULL) \r
+ {\r
+ * pucStep = pucData[6];\r
+ }\r
+ rk28printk("%s x res=%d y res=%d \r\n",__FUNCTION__,*pwXResolution,* pwYResolution);\r
+ return true;\r
+}\r
+\r
+// *******************************************************************************************\r
+// Function Name: CaptouchMode\r
+// Description: \r
+// This function is mainly used to initialize cap-touch controller to active state.\r
+// Parameters: \r
+// dwMode -- the power state to be entered\r
+// Return value: \r
+// return zero if success, otherwise return non zero value\r
+// *******************************************************************************************\r
+int CaptouchMode(u8 dwMode)\r
+{\r
+ u8 ucQueryResponse;\r
+ u8 pucCommandBuffer[128];\r
+\r
+ do\r
+ {\r
+ ReadQueryBuffer(&ucQueryResponse);\r
+ }\r
+ while(ucQueryResponse & QUERY_BUSY);\r
+\r
+ pucCommandBuffer[0] = 0x04;\r
+ pucCommandBuffer[1] = 0x00;\r
+ switch(dwMode)\r
+ {\r
+ case 0x00:\r
+ pucCommandBuffer[2] = 0x00;\r
+ break;\r
+ case 0x01:\r
+ pucCommandBuffer[2] = 0x01;\r
+ break;\r
+ case 0x02:\r
+ pucCommandBuffer[2] = 0x02;\r
+ break;\r
+ default:\r
+ return -1;\r
+ }\r
+\r
+ if(!WriteCommandBuffer( pucCommandBuffer,3))\r
+ {\r
+ return -1;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+// *******************************************************************************************\r
+// Function Name: CaptouchReset\r
+// Description: \r
+// This function is mainly used to reset cap-touch controller by sending reset command.\r
+// Parameters: NULL\r
+// Return value: \r
+// return TRUE if success, otherwise return FALSE\r
+// *******************************************************************************************\r
+int CaptouchReset()\r
+{\r
+ u8 ucQueryResponse;\r
+ u8 pucCommandBuffer[128];\r
+\r
+ do\r
+ {\r
+ ReadQueryBuffer(&ucQueryResponse);\r
+ }\r
+ while(ucQueryResponse & QUERY_BUSY);\r
+\r
+ pucCommandBuffer[0] = 0x6F;\r
+ if(!WriteCommandBuffer(pucCommandBuffer,1))\r
+ {\r
+ return -1;\r
+ }\r
+ mdelay(200);\r
+ \r
+\r
+ do\r
+ {\r
+ ReadQueryBuffer(&ucQueryResponse);\r
+ }\r
+ while(ucQueryResponse & QUERY_BUSY);\r
+\r
+\r
+ if(!ReadCommandResponseBuffer(pucCommandBuffer,2))\r
+ {\r
+ return -1;\r
+ }\r
+\r
+ if(pucCommandBuffer[0] == 0 && pucCommandBuffer[1] == 0)\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ return -1;\r
+}\r
+\r
+\r
+\r
+// *******************************************************************************************\r
+// Function Name: CaptouchHWInitial\r
+// Description: \r
+// This function is mainly used to initialize cap-touch controller to active state.\r
+// Parameters: NULL\r
+// Return value: \r
+// return zero if success, otherwise return non zero value\r
+// *******************************************************************************************\r
+int CaptouchHWInitial()\r
+{\r
+ u32 wXResolution=0,wYResolution=0;\r
+ u8 ucStep=0;\r
+ if (!IdentifyCapSensor())\r
+ {\r
+ rk28printk("%s IdentifyCapSensor error \r\n",__FUNCTION__);\r
+ // goto resetagin;\r
+}\r
+ #if 1\r
+if (!GetFirmwareInformation ())\r
+ {\r
+ rk28printk("%s GetFirmwareInformation error \r\n",__FUNCTION__);\r
+ // goto resetagin;\r
+}\r
+\r
+ if (!Get2DResolutions(&wXResolution, &wYResolution, &ucStep))\r
+ {\r
+ rk28printk("%s Get2DResolutions error \r\n",__FUNCTION__);\r
+ // goto resetagin;\r
+}\r
+\r
+//no need to set interrupt mode because firmware has done that;note by robert\r
+ #if 0\r
+ if (!SetInterruptNotification(0x01, 0x00))\r
+ {\r
+ rk28printk("%s SetInterruptNotification error \r\n",__FUNCTION__);\r
+ goto resetagin;\r
+}\r
+ #endif\r
+ //note end\r
+#endif\r
+ return 0;\r
+\r
+resetagin:\r
+ if (!CaptouchReset())\r
+ rk28printk("CaptouchReset success \r\n");\r
+ mdelay(100);\r
+// if (!CaptouchMode(0x00))\r
+ // rk28printk("CaptouchMode success \r\n");\r
+}\r
+\r
+\r
+// *******************************************************************************************\r
+// Function Name: CaptouchGetSampleValue\r
+// Description: \r
+// This function is mainly used to get sample values which shall contain x, y position and pressure. \r
+// Parameters:\r
+// pdwSampleX -- the pointer of returned X coordinates\r
+// pdwSampleY -- the pointer of returned Y coordinates\r
+// pdwPressure -- the pointer of returned pressures\r
+// Return value: \r
+// The return value is the number of sample points. Return 0 if failing to get sample. The maximum // return value is 10 in normal case. If the CTP controller does not support pressure measurement, // the return value is the sample values OR with PRESSURE_INVALID.\r
+// *******************************************************************************************\r
+int CaptouchGetSampleValue(u32* pdwSampleX, u32* pdwSampleY, u32* pdwPressure)\r
+{\r
+ int nRet;\r
+ int i;\r
+\r
+ if(gpucPointBuffer[1] & 0x01)\r
+ {\r
+ return MAX_FINGER_NUM + 1;\r
+ }\r
+\r
+ nRet = 0;\r
+ for(i = 0; i < MAX_FINGER_NUM; i++)\r
+ {\r
+ if(gpucPointBuffer[0] & (1 << i))\r
+ {\r
+ nRet++;\r
+ #if 0\r
+ pdwSampleX[i] = ((u32)(gpucPointBuffer[i * 4 + 3] & 0x0F) << 8) + \r
+(u32)gpucPointBuffer[i * 4 + 2];;\r
+ pdwSampleY[i] = ((u32)(gpucPointBuffer[i * 4 + 3] & 0xF0) << 4) + \r
+(u32)gpucPointBuffer[i * 4 + 4];\r
+ pdwPressure[i] = (u32)(gpucPointBuffer[i * 4 + 5] & 0x0F);\r
+ #else \r
+ pdwSampleX[i] = ((u32)(gpucPointBuffer[i * 4 + 3] & 0x0F) << 8) | \r
+gpucPointBuffer[i * 4 + 2];\r
+ pdwSampleY[i] = ((u32)(gpucPointBuffer[i * 4 + 3] & 0xF0) << 4) | \r
+gpucPointBuffer[i * 4 + 4];\r
+ pdwPressure[i] = (u32)(gpucPointBuffer[i * 4 + 5] & 0x0F);\r
+\r
+ // rk28printk("%s x[%d]=%d y[%d]=%d \r\n",__FUNCTION__,i,pdwSampleX[i],i,pdwSampleY[i]);\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ pdwSampleX[i] = 0;\r
+ pdwSampleY[i] = 0;\r
+ pdwPressure[i] = 0;\r
+ }\r
+ }\r
+ //add by robert for test\r
+ #if 0\r
+ for(i = 0; i < MAX_FINGER_NUM; i++)\r
+ {\r
+ rk28printk("%s x[%d]=%d y[%d]=%d \r\n",__FUNCTION__,0,pdwSampleX[0],0,pdwSampleY[0]);\r
+ }\r
+ #endif\r
+ return nRet;\r
+}\r
+\r
+// *******************************************************************************************\r
+// Function Name: CaptouchGetGesture\r
+// Description: \r
+// This function is mainly used to initialize cap-touch controller to active state.\r
+// Parameters: NULL\r
+// Return value: \r
+// return gesture ID\r
+// *******************************************************************************************\r
+int CaptouchGetGesture()\r
+{\r
+ return (int)gpucPointBuffer[1];\r
+}\r
+\r
+static void Ctp_it7250_delaywork_func(struct work_struct *work)\r
+{
+
+ u8 ucQueryResponse;\r
+ u32 dwTouchEvent;\r
+ struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(Ctp_it7250_client);\r
+ int PE1status = 0;\r
+\r
+// rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__);\r
+\r
+\r
+ PE1status = gpio_get_value(Ctp_it7250_GPIO_INT);\r
+ // PE1status ΪµÍ£¬±íʾµÍµçƽÖжÏÓÐЧ \r
+ if (!PE1status)\r
+ {\r
+ // rk28printk("%s PE1status low!! \r\n",__FUNCTION__);\r
+ if(!ReadQueryBuffer(&ucQueryResponse))\r
+ {rk28printk("%s++++ %d ucQueryResponse=0x%x \r\n",__FUNCTION__,__LINE__,ucQueryResponse);\r
+ return false;\r
+ }\r
+//rk28printk("%s++++ %d ucQueryResponse=0x%x \r\n",__FUNCTION__,__LINE__,ucQueryResponse);\r
+ // Touch Event\r
+ if(ucQueryResponse & QUERY_POINT)\r
+ {//rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__);\r
+ if(!ReadPointBuffer(gpucPointBuffer))\r
+ {rk28printk("%s++++ %d \r\n",__FUNCTION__,__LINE__);\r
+ return false;\r
+ }\r
+//rk28printk("%s++++ %d ucQueryResponse=0x%x gpucPointBuffer=0x%x\r\n",__FUNCTION__,__LINE__,ucQueryResponse,gpucPointBuffer[0] & 0xF0);\r
+ switch(gpucPointBuffer[0] & 0xF0)\r
+ {\r
+ case 0x00:\r
+ dwTouchEvent = CaptouchGetSampleValue(gpdwSampleX, gpdwSampleY, \r
+gpdwPressure);\r
+ if(dwTouchEvent == 0)\r
+ {\r
+ //SynchroSystemEvent(SYSTEM_TOUCH_EVENT_FINGER_RELEASE);\r
+ rk28printk("TOUCH Release !!\r\n");\r
+ input_report_key(Ctp_it7250->input_dev,BTN_TOUCH, 0);\r
+ input_sync(Ctp_it7250->input_dev);\r
+ }\r
+ else if(dwTouchEvent <=MAX_FINGER_NUM) //CTP_MAX_FINGER_NUMBER)\r
+ {\r
+ //SynchroSystemEvent(SYSTEM_TOUCH_EVENT_FINGER_ASSERT);\r
+ \r
+ input_report_abs(Ctp_it7250->input_dev, ABS_X, gpdwSampleX[0]);// & 0xfff\r
+ input_report_abs(Ctp_it7250->input_dev, ABS_Y, gpdwSampleY[0]); //& 0xfff\r
+ input_report_key(Ctp_it7250->input_dev,BTN_TOUCH, 1);\r
+ input_sync(Ctp_it7250->input_dev);rk28printk("x=%d y=%d \r\n",gpdwSampleX[0],gpdwSampleY[0]);\r
+ }\r
+ else\r
+ {\r
+ rk28printk("%s SYSTEM_TOUCH_EVENT_PALM_DETECT \r\n",__FUNCTION__);\r
+ //SynchroSystemEvent(SYSTEM_TOUCH_EVENT_PALM_DETECT);\r
+ }\r
+ break;\r
+ case 0x80:\r
+ dwTouchEvent = CaptouchGetGesture();\r
+ //SynchroSystemEvent(SYSTEM_GESTURE_EVENT);\r
+ rk28printk("gesture:0x%x \r\n",dwTouchEvent);\r
+ break;\r
+ //for keypad below\r
+ case 0x40:\r
+ rk28printk("ID of button is 0x%x status is 0x%x\r\n",gpucPointBuffer[1],gpucPointBuffer[2]);\r
+ switch (gpucPointBuffer[1]) \r
+ {case 0x01:\r
+ rk28printk("home \r\n");\r
+ if (gpucPointBuffer[2])\r
+ input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,1);\r
+ else\r
+ input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,0);\r
+ break;\r
+ case 0x02:\r
+ rk28printk("menu \r\n");\r
+ if (gpucPointBuffer[2])\r
+ input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,1);\r
+ else\r
+ input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,0);\r
+ break;\r
+ case 0x03:\r
+ rk28printk("back \r\n");\r
+ if (gpucPointBuffer[2])\r
+ {\r
+ rk28printk("back down key=%d\r\n",panel_key_info[(gpucPointBuffer[1]-1)].key);\r
+ input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,1);\r
+ }\r
+ else\r
+ {\r
+ rk28printk("back up key=%d\r\n",panel_key_info[(gpucPointBuffer[1]-1)].key);\r
+ input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,0);\r
+ }\r
+ break;\r
+ case 0x04:\r
+ rk28printk("find \r\n");\r
+ if (gpucPointBuffer[2])\r
+ {\r
+ rk28printk("find down key=%d\r\n",panel_key_info[(gpucPointBuffer[1]-1)].key);\r
+ input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,1);\r
+ }\r
+ else\r
+ {\r
+ rk28printk("find up key=%d\r\n",panel_key_info[(gpucPointBuffer[1]-1)].key);\r
+ input_report_key(Ctp_it7250->input_dev, panel_key_info[(gpucPointBuffer[1]-1)].key,0);\r
+ }\r
+ break; \r
+ default:\r
+ rk28printk("shit default \r\n");\r
+ break;\r
+ }\r
+ break;\r
+ default:\r
+ rk28printk("default \r\n");\r
+ break;\r
+ }\r
+ }\r
+ else if (ucQueryResponse & QUERY_ERROR)\r
+ {\r
+ if (!CaptouchReset())\r
+ rk28printk("!! CaptouchReset success \r\n");\r
+ mdelay(100);\r
+ //if (!CaptouchMode(0x00))\r
+ //rk28printk("!! CaptouchMode success \r\n");\r
+ }\r
+ }\r
+// rk28printk("enable ctp_irq=%d \r\n",Ctp_it7250->irq);\r
+ \r
+ enable_irq(Ctp_it7250->irq);\r
+ //²»ÊDzéѯģʽ£¬²»ÐèÒªÂÖѯ\r
+//schedule_delayed_work(&Ctp_it7250->delaywork,msecs_to_jiffies(1000));\r
+\r
+}\r
+\r
+ static int Ctp_it7250_probe(struct i2c_client *client, const struct i2c_device_id *id)\r
+{\r
+ struct Ctp_it7250_data *Ctp_it7250;\r
+ u16 TempReg=0x0;\r
+ u16 val=0x0;\r
+ \r
+ Ctp_it7250_client = client;\r
+ rk28printk("+++++++ %s+++++++\n", __FUNCTION__);\r
+ Ctp_it7250 = kzalloc(sizeof(struct Ctp_it7250_data), GFP_KERNEL);\r
+ if (!Ctp_it7250) \r
+ {\r
+ rk28printk("[Ctp_it7250_probe]:alloc data failed.\n");\r
+ return -ENOMEM;\r
+ }\r
+\r
+// INIT_WORK(&Ctp_it7250->irq_work, Ctp_it7250_irq_worker);\r
+ INIT_DELAYED_WORK(&Ctp_it7250->delaywork, Ctp_it7250_delaywork_func);\r
+\r
+\r
+ Ctp_it7250->client = client;\r
+ i2c_set_clientdata(client, Ctp_it7250);\r
+\r
+ \r
+ \r
+ ts_input_init(client);\r
+// CTS_configure_pin(client);\r
+\r
+{\r
+#if 0\r
+lp8725_lilo_en(2,0);\r
+mdelay(100);\r
+\r
+lp8725_lilo_en(2,1);\r
+mdelay(100);\r
+lp8725_set_lilo_vol(2,300);\r
+mdelay(5);\r
+#endif\r
+\r
+}\r
+CaptouchHWInitial();\r
+Ctp_it7250_init_irq(client);\r
+ \r
+ \r
+//²»ÊDzéѯģʽ£¬²»ÐèÒªÂÖѯ\r
+//schedule_delayed_work(&Ctp_it7250->delaywork,msecs_to_jiffies(50));\r
+\r
+\r
+ rk28printk("+++++++ %s+++++++\n", __FUNCTION__);\r
+ return 0;\r
+\r
+}\r
+\r
+\r
+\r
+static int Ctp_it7250_remove(struct i2c_client *client)\r
+{
+
+ return 0;
+}
+\r
+\r
+\r
+#ifdef CONFIG_PM\r
+static int Ctp_it7250_suspend(struct i2c_client *client, pm_message_t state)\r
+{//pr_emerg("\n irq1=%d \n",irq1);\r
+struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(client);\r
+\r
+//send command to make ctp into sleep mode\r
+#if 1\r
+ u8 ucWriteLength;\r
+ u8 pucData[128];\r
+ u8 ucQuery;\r
+\r
+ ucWriteLength = 3;\r
+ pucData[0] = 0x04;\r
+ pucData[1] = 0x00;\r
+ pucData[2] = 0x02;\r
+\r
+ // Query\r
+ do\r
+ {\r
+ if(!ReadQueryBuffer(&ucQuery))\r
+ {\r
+ ucQuery = QUERY_BUSY;\r
+ }\r
+ }while(ucQuery & QUERY_BUSY);\r
+\r
+ // Write Command\r
+ rk28printk("%s WriteCommandBuffer\r\n",__FUNCTION__);\r
+ if(!WriteCommandBuffer(pucData, ucWriteLength))\r
+ {\r
+ return false;\r
+ }\r
+ #endif\r
+//send sleep command end\r
+\r
+ disable_irq(Ctp_it7250->irq);\r
+\r
+ return 0;\r
+}\r
+\r
+static int Ctp_it7250_resume(struct i2c_client *client)\r
+{\r
+struct Ctp_it7250_data *Ctp_it7250 = (struct Ctp_it7250_data *)i2c_get_clientdata(client);\r
+//read command to wakeup ctp\r
+#if 1\r
+u8 ucQuery;\r
+ReadQueryBuffer(&ucQuery);\r
+#endif\r
+//wakeup end\r
+ enable_irq(Ctp_it7250->irq);\r
+ return 0;\r
+}\r
+#else\r
+#define Ctp_it7250_suspend NULL\r
+#define Ctp_it7250_resume NULL\r
+#endif\r
+\r
+static const struct i2c_device_id Ctp_it7250_id[] = {\r
+ {"Ctp_it7250", 0},\r
+ { }
+};\r
+\r
+static struct i2c_driver Ctp_it7250_driver = {\r
+ .driver = {\r
+ .name = "Ctp_it7250",\r
+ },\r
+ .id_table = Ctp_it7250_id,\r
+ .probe = Ctp_it7250_probe,\r
+ .remove = Ctp_it7250_remove,\r
+};\r
+\r
+static int __init Ctp_it7250_init(void)\r
+{\r
+ int ret; \r
+ rk28printk("+++++++ %s++\n", __FUNCTION__);\r
+ ret=i2c_add_driver(&Ctp_it7250_driver);\r
+ rk28printk("**Ctp_it7250_init_init return %d**\n",ret);\r
+ return ret;\r
+}\r
+\r
+static void __exit Ctp_it7250_exit(void)\r
+{\r
+ /* We move these codes here because we want to detect the\r
+ * pen down event even when touch driver is not opened.\r
+ */\r
+ i2c_del_driver(&Ctp_it7250_driver);\r
+}\r
+\r
+ late_initcall(Ctp_it7250_init);\r
+module_exit(Ctp_it7250_exit);\r
+\r
+MODULE_AUTHOR("Robert_mu<robert.mu@rahotech.com>");\r
+\r