Mstar虚拟按键触摸屏驱动(芯片msg2133,按键使用android虚拟按键实现,特定报点,识别为按键)

来源:互联网 发布:命令启动mysql 编辑:程序博客网 时间:2024/05/01 05:07

 

#ifndef __LINUX_MSTAR_MSG2133_TS_H__
#define __LINUX_MSTAR_MSG2133_TS_H__

//#define TS_DEBUG_MSG     1
#define VIRTUAL_KEYS    1   //是否有按键
#define MSG2133_UPDATE    1   //T卡升级功能

#define TS_WIDTH_MAX    480   //LCD分辨率
#define TS_HEIGHT_MAX    800   //LCD分辨率 //使用虚拟按键,也不需要把这个分辨率提高到按键区域。

#define TS_ENPIN_LEVEL    0   //ENPIN(ResetPin)电压,如果TP上有反相MOS管,则设为1

#define MSG2133_BUS_NUM   2
#define MSG2133_TS_NAME         "msg2133"
#define MSG2133_TS_ADDR   0x26
#define MSG2133_FW_ADDR   0x62
#define MSG2133_FW_UPDATE_ADDR    0x49 


#define TPD_OK      0
#define TPD_REG_BASE    0x00
#define TPD_SOFT_RESET_MODE  0x01
#define TPD_OP_MODE    0x00
#define TPD_LOW_PWR_MODE   0x04
#define TPD_SYSINFO_MODE   0x10

#define GET_HSTMODE(reg)  ((reg & 0x70) >> 4)  // in op mode or not
#define GET_BOOTLOADERMODE(reg) ((reg & 0x10) >> 4)  // in bl mode


struct ts_event {
 u16 x1;
 u16 y1;
 u16 x2;
 u16 y2;
    u8  touch_point;
};

struct msg2133_ts_data {
 struct input_dev *input_dev;
 struct ts_event  event;
 struct work_struct  pen_event_work;
 struct workqueue_struct *ts_workqueue;
 struct early_suspend early_suspend;
};

struct TouchScreenInfo_t{
    unsigned char nTouchKeyMode;
    unsigned char nTouchKeyCode;
    //unsigned char nFingerNum;
} ;

#endif  // end of __LINUX_MSTAR_MSG2133_TS_H__

 

 

================== 分割线 ======================================

 

 

/*
 * drivers/input/touchscreen/msg2133_ts.c
 *
 * MStar msg2133 TouchScreen driver.
 *
 * Copyright (c) 2012 MStar Semiconductor, 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       DATE   AUTHOR
 *    1.0    2010-01-05   WenFS
 *
 * note: only support mulititouch Wenfs 2010-10-01
 */

 

#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/earlysuspend.h>
#include <linux/interrupt.h>
#include <linux/delay.h>

#include <linux/firmware.h>
#include <linux/platform_device.h>

#include <linux/slab.h>

#include <mach/ldo.h>

#include "msg2133.h"


#define TS_DEBUG_MSG 1// use MSG2133_DBG

#if TS_DEBUG_MSG
#define MSG2133_DBG(format, ...) printk(KERN_INFO "MSG2133 " format "\n", ## __VA_ARGS__)
#else
#define MSG2133_DBG(format, ...)
#endif

extern int sprd_3rdparty_gpio_tp_rst;
extern int sprd_3rdparty_gpio_tp_irq;


static struct i2c_client *this_client;
static struct i2c_board_info msg2133_i2c_boardinfo = {
 I2C_BOARD_INFO(MSG2133_TS_NAME, MSG2133_TS_ADDR),
};

static void msg2133_device_power_on();


#ifdef MSG2133_UPDATE

struct class *firmware_class;
struct device *firmware_cmd_dev;
static int update_switch = 0;
static int FwDataCnt;
static  char *fw_version;
static unsigned char temp[94][1024];


static void msg2133_reset()
{
    gpio_set_value(sprd_3rdparty_gpio_tp_rst, TS_ENPIN_LEVEL);
 msg2133_device_power_on();
 msleep(20);
 gpio_set_value(sprd_3rdparty_gpio_tp_rst,!TS_ENPIN_LEVEL);
 msleep(500);
}


static bool msg2133_i2c_read(char *pbt_buf, int dw_lenth)
{
    int ret;
    //MSG2133_DBG("The msg_i2c_client->addr=0x%x\n",i2c_client->addr);
    ret = i2c_master_recv(this_client, pbt_buf, dw_lenth);

    if(ret <= 0){
        MSG2133_DBG("msg_i2c_read_interface error\n");
        return false;
    }

    return true;
}

static bool msg2133_i2c_write(char *pbt_buf, int dw_lenth)
{
    int ret;
    //MSG2133_DBG("The msg_i2c_client->addr=0x%x\n",i2c_client->addr);
    ret = i2c_master_send(this_client, pbt_buf, dw_lenth);

    if(ret <= 0){
        MSG2133_DBG("msg_i2c_read_interface error\n");
        return false;
    }

    return true;
}


static void i2c_read_msg2133(unsigned char *pbt_buf, int dw_lenth)
{
    this_client->addr = MSG2133_FW_ADDR;
 i2c_master_recv(this_client, pbt_buf, dw_lenth); //0xC5_8bit
 this_client->addr = MSG2133_TS_ADDR;
}

static void i2c_write_msg2133(unsigned char *pbt_buf, int dw_lenth)
{

 this_client->addr = MSG2133_FW_ADDR;
 i2c_master_send(this_client, pbt_buf, dw_lenth);  //0xC4_8bit
 this_client->addr = MSG2133_TS_ADDR;
}

static void i2c_read_update_msg2133(unsigned char *pbt_buf, int dw_lenth)

 this_client->addr = MSG2133_FW_UPDATE_ADDR;
 i2c_master_recv(this_client, pbt_buf, dw_lenth); //0x93_8bit
 this_client->addr = MSG2133_TS_ADDR;
}

static void i2c_write_update_msg2133(unsigned char *pbt_buf, int dw_lenth)

    this_client->addr = MSG2133_FW_UPDATE_ADDR;
 i2c_master_send(this_client, pbt_buf, dw_lenth); //0x92_8bit
 this_client->addr = MSG2133_TS_ADDR;
}

 

void dbbusDWIICEnterSerialDebugMode(void)
{
    unsigned char data[5];
    // Enter the Serial Debug Mode
    data[0] = 0x53;
    data[1] = 0x45;
    data[2] = 0x52;
    data[3] = 0x44;
    data[4] = 0x42;
    i2c_write_msg2133(data, 5);
}

void dbbusDWIICStopMCU(void)
{
    unsigned char data[1];
    // Stop the MCU
    data[0] = 0x37;
    i2c_write_msg2133(data, 1);
}

void dbbusDWIICIICUseBus(void)
{
    unsigned char data[1];
    // IIC Use Bus
    data[0] = 0x35;
    i2c_write_msg2133(data, 1);
}

void dbbusDWIICIICReshape(void)
{
    unsigned char data[1];
    // IIC Re-shape
    data[0] = 0x71;
    i2c_write_msg2133(data, 1);
}

void dbbusDWIICIICNotUseBus(void)
{
    unsigned char data[1];
    // IIC Not Use Bus
    data[0] = 0x34;
    i2c_write_msg2133(data, 1);
}

void dbbusDWIICNotStopMCU(void)
{
    unsigned char data[1];
    // Not Stop the MCU
    data[0] = 0x36;
    i2c_write_msg2133(data, 1);
}

void dbbusDWIICExitSerialDebugMode(void)
{
    unsigned char data[1];
    // Exit the Serial Debug Mode
    data[0] = 0x45;
    i2c_write_msg2133(data, 1);
    // Delay some interval to guard the next transaction
}

void drvISP_EntryIspMode(void)
{
    unsigned char bWriteData[5] =
    {
        0x4D, 0x53, 0x54, 0x41, 0x52
    };
    i2c_write_update_msg2133(bWriteData, 5);
    msleep(10);           // delay about 10ms
}

void drvISP_WriteEnable(void)
{
    unsigned char bWriteData[2] =
    {
        0x10, 0x06
    };
    unsigned char bWriteData1 = 0x12;
    i2c_write_update_msg2133(bWriteData, 2);
    i2c_write_update_msg2133(&bWriteData1, 1);
}

unsigned char drvISP_Read(unsigned char n, unsigned char *pDataToRead)    //First it needs send 0x11 to notify we want to get flash data back.
{
    unsigned char Read_cmd = 0x11;
    unsigned char i = 0;
    unsigned char dbbus_rx_data[16] = {0};
    i2c_write_update_msg2133(&Read_cmd, 1);
    //if (n == 1)
    {
        i2c_read_update_msg2133(&dbbus_rx_data[0], n + 1);

        for(i = 0; i < n; i++)
        {
            *(pDataToRead + i) = dbbus_rx_data[i + 1];
        }
    }
    //else
    {
        //     i2c_read_update_msg2133(pDataToRead, n);
    }
    return 0;
}

unsigned char drvISP_ReadStatus(void)
{
    unsigned char bReadData = 0;
    unsigned char bWriteData[2] =
    {
        0x10, 0x05
    };
    unsigned char bWriteData1 = 0x12;
//    msleep(1);           // delay about 100us
    i2c_write_update_msg2133(bWriteData, 2);
//    msleep(1);           // delay about 100us
    drvISP_Read(1, &bReadData);
//    msleep(10);           // delay about 10ms
    i2c_write_update_msg2133(&bWriteData1, 1);
    return bReadData;
}

 

void drvISP_BlockErase(unsigned int addr)
{
    unsigned char bWriteData[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
    unsigned char bWriteData1 = 0x12;
    unsigned int timeOutCount=0;
 
    drvISP_WriteEnable();
    //Enable write status register
    bWriteData[0] = 0x10;
    bWriteData[1] = 0x50;
    i2c_write_update_msg2133(bWriteData, 2);
    i2c_write_update_msg2133(&bWriteData1, 1);
    //Write Status
    bWriteData[0] = 0x10;
    bWriteData[1] = 0x01;
    bWriteData[2] = 0x00;
    i2c_write_update_msg2133(bWriteData, 3);
    i2c_write_update_msg2133(&bWriteData1, 1);
    //Write disable
    bWriteData[0] = 0x10;
    bWriteData[1] = 0x04;
    i2c_write_update_msg2133(bWriteData, 2);
    i2c_write_update_msg2133(&bWriteData1, 1);

    timeOutCount=0;
    msleep(1);           // delay about 100us
    while((drvISP_ReadStatus() & 0x01) == 0x01)
    {
        timeOutCount++;
  if ( timeOutCount > 10000 )
            break; /* around 1 sec timeout */
    }

    //pr_ch("The drvISP_ReadStatus3=%d\n", drvISP_ReadStatus());
    drvISP_WriteEnable();
    //pr_ch("The drvISP_ReadStatus4=%d\n", drvISP_ReadStatus());
    bWriteData[0] = 0x10;
    bWriteData[1] = 0xC7;        //Block Erase
    //bWriteData[2] = ((addr >> 16) & 0xFF) ;
    //bWriteData[3] = ((addr >> 8) & 0xFF) ;
    // bWriteData[4] = (addr & 0xFF) ;
    i2c_write_update_msg2133(bWriteData, 2);
    //i2c_write_update_msg2133( &bWriteData, 5);
    i2c_write_update_msg2133(&bWriteData1, 1);

    timeOutCount=0;
    msleep(1);           // delay about 100us
    while((drvISP_ReadStatus() & 0x01) == 0x01)
    {
        timeOutCount++;
  if ( timeOutCount > 10000 )
            break; /* around 1 sec timeout */
    }
}

void drvISP_Program(unsigned short k, unsigned char *pDataToWrite)
{
    unsigned short i = 0;
    unsigned short j = 0;
    //U16 n = 0;
    unsigned char TX_data[133];
    unsigned char bWriteData1 = 0x12;
    unsigned int addr = k * 1024;
#if 1

    for(j = 0; j < 8; j++)    //128*8 cycle
    {
        TX_data[0] = 0x10;
        TX_data[1] = 0x02;// Page Program CMD
        TX_data[2] = (addr + 128 * j) >> 16;
        TX_data[3] = (addr + 128 * j) >> 8;
        TX_data[4] = (addr + 128 * j);

        for(i = 0; i < 128; i++)
        {
            TX_data[5 + i] = pDataToWrite[j * 128 + i];
        }

        while((drvISP_ReadStatus() & 0x01) == 0x01)
        {
            ;    //wait until not in write operation
        }

        drvISP_WriteEnable();
        i2c_write_update_msg2133( TX_data, 133);   //write 133 byte per cycle
        i2c_write_update_msg2133(&bWriteData1, 1);
    }

#else

    for(j = 0; j < 512; j++)    //128*8 cycle
    {
        TX_data[0] = 0x10;
        TX_data[1] = 0x02;// Page Program CMD
        TX_data[2] = (addr + 2 * j) >> 16;
        TX_data[3] = (addr + 2 * j) >> 8;
        TX_data[4] = (addr + 2 * j);

        for(i = 0; i < 2; i++)
        {
            TX_data[5 + i] = pDataToWrite[j * 2 + i];
        }

        while((drvISP_ReadStatus() & 0x01) == 0x01)
        {
            ;    //wait until not in write operation
        }

        drvISP_WriteEnable();
        i2c_write_update_msg2133(TX_data, 7);    //write 7 byte per cycle
        i2c_write_update_msg2133(&bWriteData1, 1);
    }

#endif
}

void drvISP_ExitIspMode(void)
{
    unsigned char bWriteData = 0x24;
    i2c_write_update_msg2133(&bWriteData, 1);
}


static ssize_t firmware_version_show(struct device *dev,
                                     struct device_attribute *attr, char *buf)
{
 printk("tyd-tp: firmware_version_show\n");
    MSG2133_DBG("*** firmware_version_show fw_version = %s***\n", fw_version);
    return sprintf(buf, "%s\n", fw_version);
}

static ssize_t firmware_version_store(struct device *dev,
                                      struct device_attribute *attr, const char *buf, size_t size)
{
    unsigned char dbbus_tx_data[3];
    unsigned char dbbus_rx_data[4] ;
    unsigned short major = 0, minor = 0;
    dbbusDWIICEnterSerialDebugMode();
    dbbusDWIICStopMCU();
    dbbusDWIICIICUseBus();
    dbbusDWIICIICReshape();
    fw_version = kzalloc(sizeof(char), GFP_KERNEL);
    MSG2133_DBG("\n");
 printk("tyd-tp: firmware_version_store\n");
    //Get_Chip_Version();
    dbbus_tx_data[0] = 0x53;
    dbbus_tx_data[1] = 0x00;
    dbbus_tx_data[2] = 0x74;
    //i2c_write(TOUCH_ADDR_MSG20XX, &dbbus_tx_data[0], 3);
    //i2c_read(TOUCH_ADDR_MSG20XX, &dbbus_rx_data[0], 4);
    msg2133_i2c_write(&dbbus_tx_data[0], 3);
    msg2133_i2c_read(&dbbus_rx_data[0], 4);
    major = (dbbus_rx_data[1] << 8) + dbbus_rx_data[0];
    minor = (dbbus_rx_data[3] << 8) + dbbus_rx_data[2];
    MSG2133_DBG("***major = %d ***\n", major);
    MSG2133_DBG("***minor = %d ***\n", minor);
    sprintf(fw_version, "%03d%03d", major, minor);
    MSG2133_DBG("***fw_version = %s ***\n", fw_version);
    return size;
}

static ssize_t firmware_update_show(struct device *dev,
                                    struct device_attribute *attr, char *buf)
{
 printk("tyd-tp: firmware_update_show\n");
    return sprintf(buf, "%s\n", fw_version);
}

static ssize_t firmware_update_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t size)
{
    unsigned char i;
    unsigned char dbbus_tx_data[4];
    unsigned char dbbus_rx_data[2] = {0};
    update_switch = 1;
    //drvISP_EntryIspMode();
    //drvISP_BlockErase(0x00000);
    //M by cheehwa _HalTscrHWReset();

    //关闭中断
    disable_irq_nosync(this_client->irq);
 
 msg2133_reset();
    //msctpc_LoopDelay ( 100 );        // delay about 100ms*****
    // Enable slave's ISP ECO mode
    dbbusDWIICEnterSerialDebugMode();
    dbbusDWIICStopMCU();
    dbbusDWIICIICUseBus();
    dbbusDWIICIICReshape();
    //pr_ch("dbbusDWIICIICReshape\n");
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x08;
    dbbus_tx_data[2] = 0x0c;
    dbbus_tx_data[3] = 0x08;
    // Disable the Watchdog
    i2c_write_msg2133(dbbus_tx_data, 4);
    //Get_Chip_Version();
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x11;
    dbbus_tx_data[2] = 0xE2;
    dbbus_tx_data[3] = 0x00;
    i2c_write_msg2133(dbbus_tx_data, 4);
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x3C;
    dbbus_tx_data[2] = 0x60;
    dbbus_tx_data[3] = 0x55;
    i2c_write_msg2133(dbbus_tx_data, 4);
    //pr_ch("update\n");
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x3C;
    dbbus_tx_data[2] = 0x61;
    dbbus_tx_data[3] = 0xAA;
    i2c_write_msg2133(dbbus_tx_data, 4);
    //Stop MCU
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x0F;
    dbbus_tx_data[2] = 0xE6;
    dbbus_tx_data[3] = 0x01;
    i2c_write_msg2133(dbbus_tx_data, 4);
    //Enable SPI Pad
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x1E;
    dbbus_tx_data[2] = 0x02;
    i2c_write_msg2133(dbbus_tx_data, 3);
    i2c_read_msg2133(&dbbus_rx_data[0], 2);
    //pr_tp("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
    dbbus_tx_data[3] = (dbbus_rx_data[0] | 0x20);  //Set Bit 5
    i2c_write_msg2133(dbbus_tx_data, 4);
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x1E;
    dbbus_tx_data[2] = 0x25;
    i2c_write_msg2133(dbbus_tx_data, 3);
    dbbus_rx_data[0] = 0;
    dbbus_rx_data[1] = 0;
    i2c_read_msg2133(&dbbus_rx_data[0], 2);
    //pr_tp("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
    dbbus_tx_data[3] = dbbus_rx_data[0] & 0xFC;  //Clear Bit 1,0
    i2c_write_msg2133(dbbus_tx_data, 4);
    /*
    //------------
    // ISP Speed Change to 400K
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x11;
    dbbus_tx_data[2] = 0xE2;
    i2c_write_msg2133( dbbus_tx_data, 3);
    i2c_read_msg2133( &dbbus_rx_data[3], 1);
    //pr_tp("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
    dbbus_tx_data[3] = dbbus_tx_data[3]&0xf7;  //Clear Bit3
    i2c_write_msg2133( dbbus_tx_data, 4);
    */
    //WP overwrite
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x1E;
    dbbus_tx_data[2] = 0x0E;
    dbbus_tx_data[3] = 0x02;
    i2c_write_msg2133(dbbus_tx_data, 4);
    //set pin high
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x1E;
    dbbus_tx_data[2] = 0x10;
    dbbus_tx_data[3] = 0x08;
    i2c_write_msg2133(dbbus_tx_data, 4);
    dbbusDWIICIICNotUseBus();
    dbbusDWIICNotStopMCU();
    dbbusDWIICExitSerialDebugMode();
    ///////////////////////////////////////
    // Start to load firmware
    ///////////////////////////////////////
    drvISP_EntryIspMode();
    MSG2133_DBG("entryisp\n");
    drvISP_BlockErase(0x00000);
    //msleep(1000);
    MSG2133_DBG("FwVersion=2");

    for(i = 0; i < 94; i++)    // total  94 KB : 1 byte per R/W
    {
        //msleep(1);//delay_100us
        MSG2133_DBG("drvISP_Program\n");
        drvISP_Program(i, temp[i]);    // program to slave's flash
        //pr_ch("drvISP_Verify\n");
        //drvISP_Verify ( i, temp[i] ); //verify data
    }

    //MSG2133_DBG("update OK\n");
    drvISP_ExitIspMode();
    FwDataCnt = 0;
    msg2133_reset();
    MSG2133_DBG("update OK\n");
    update_switch = 0;
    //打开中断
    enable_irq(this_client->irq);
    return size;
}

static ssize_t firmware_data_show(struct device *dev,
                                  struct device_attribute *attr, char *buf)
{
 printk("tyd-tp: firmware_data_show\n");
    return FwDataCnt;
}

static ssize_t firmware_data_store(struct device *dev,
                                   struct device_attribute *attr, const char *buf, size_t size)
{
    int i;
    MSG2133_DBG("***FwDataCnt = %d ***\n", FwDataCnt);
 printk("tyd-tp: firmware_data_store\n");
    for(i = 0; i < 1024; i++)
    {
        memcpy(temp[FwDataCnt], buf, 1024);
    }

    FwDataCnt++;
    return size;
}

static ssize_t firmware_clear_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
{
    unsigned short k = 0, i = 0, j = 0;
    unsigned char bWriteData[5] =
    {
        0x10, 0x03, 0, 0, 0
    };
    unsigned char RX_data[256];
    unsigned char bWriteData1 = 0x12;
    unsigned int addr = 0;
    MSG2133_DBG("\n");
 printk("tyd-tp: firmware_clear_show\n");
    for(k = 0; k < 94; i++)    // total  94 KB : 1 byte per R/W
    {
        addr = k * 1024;

        for(j = 0; j < 8; j++)    //128*8 cycle
        {
            bWriteData[2] = (unsigned char)((addr + j * 128) >> 16);
            bWriteData[3] = (unsigned char)((addr + j * 128) >> 8);
            bWriteData[4] = (unsigned char)(addr + j * 128);

            while((drvISP_ReadStatus() & 0x01) == 0x01)
            {
                ;    //wait until not in write operation
            }

            i2c_write_update_msg2133(bWriteData, 5);     //write read flash addr
            drvISP_Read(128, RX_data);
            i2c_write_update_msg2133(&bWriteData1, 1);    //cmd end

            for(i = 0; i < 128; i++)    //log out if verify error{
                if(RX_data[i] != 0xFF){
                    MSG2133_DBG("k=%d,j=%d,i=%d===============erase not clean================", k, j, i);
                }
            }
     }
    MSG2133_DBG("read finish\n");
    return sprintf(buf, "%s\n", fw_version);
}

static ssize_t firmware_clear_store(struct device *dev,
                                    struct device_attribute *attr, const char *buf, size_t size)
{
    unsigned char dbbus_tx_data[4];
    unsigned char dbbus_rx_data[2] = {0};
    //msctpc_LoopDelay ( 100 );        // delay about 100ms*****
    // Enable slave's ISP ECO mode
    /*
    dbbusDWIICEnterSerialDebugMode();
    dbbusDWIICStopMCU();
    dbbusDWIICIICUseBus();
    dbbusDWIICIICReshape();*/
    MSG2133_DBG("\n");
 printk("tyd-tp: firmware_clear_store\n");
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x08;
    dbbus_tx_data[2] = 0x0c;
    dbbus_tx_data[3] = 0x08;
    // Disable the Watchdog
    i2c_write_msg2133(dbbus_tx_data, 4);
    //Get_Chip_Version();
    //FwVersion  = 2;
    //if (FwVersion  == 2)
    {
        dbbus_tx_data[0] = 0x10;
        dbbus_tx_data[1] = 0x11;
        dbbus_tx_data[2] = 0xE2;
        dbbus_tx_data[3] = 0x00;
        i2c_write_msg2133(dbbus_tx_data, 4);
    }
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x3C;
    dbbus_tx_data[2] = 0x60;
    dbbus_tx_data[3] = 0x55;
    i2c_write_msg2133(dbbus_tx_data, 4);
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x3C;
    dbbus_tx_data[2] = 0x61;
    dbbus_tx_data[3] = 0xAA;
    i2c_write_msg2133(dbbus_tx_data, 4);
    //Stop MCU
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x0F;
    dbbus_tx_data[2] = 0xE6;
    dbbus_tx_data[3] = 0x01;
    i2c_write_msg2133(dbbus_tx_data, 4);
    //Enable SPI Pad
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x1E;
    dbbus_tx_data[2] = 0x02;
    i2c_write_msg2133(dbbus_tx_data, 3);
    i2c_read_msg2133(&dbbus_rx_data[0], 2);
    MSG2133_DBG("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
    dbbus_tx_data[3] = (dbbus_rx_data[0] | 0x20);  //Set Bit 5
    i2c_write_msg2133(dbbus_tx_data, 4);
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x1E;
    dbbus_tx_data[2] = 0x25;
    i2c_write_msg2133(dbbus_tx_data, 3);
    dbbus_rx_data[0] = 0;
    dbbus_rx_data[1] = 0;
    i2c_read_msg2133(&dbbus_rx_data[0], 2);
    MSG2133_DBG("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
    dbbus_tx_data[3] = dbbus_rx_data[0] & 0xFC;  //Clear Bit 1,0
    i2c_write_msg2133(dbbus_tx_data, 4);
    //WP overwrite
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x1E;
    dbbus_tx_data[2] = 0x0E;
    dbbus_tx_data[3] = 0x02;
    i2c_write_msg2133(dbbus_tx_data, 4);
    //set pin high
    dbbus_tx_data[0] = 0x10;
    dbbus_tx_data[1] = 0x1E;
    dbbus_tx_data[2] = 0x10;
    dbbus_tx_data[3] = 0x08;
    i2c_write_msg2133(dbbus_tx_data, 4);
    dbbusDWIICIICNotUseBus();
    dbbusDWIICNotStopMCU();
    dbbusDWIICExitSerialDebugMode();
    ///////////////////////////////////////
    // Start to load firmware
    ///////////////////////////////////////
    drvISP_EntryIspMode();
    MSG2133_DBG("chip erase+\n");
    drvISP_BlockErase(0x00000);
    MSG2133_DBG("chip erase-\n");
    drvISP_ExitIspMode();
    return size;
}

static DEVICE_ATTR(version, 0777, firmware_version_show, firmware_version_store);
static DEVICE_ATTR(update, 0777, firmware_update_show, firmware_update_store);
static DEVICE_ATTR(data, 0777, firmware_data_show, firmware_data_store);
static DEVICE_ATTR(clear, 0777, firmware_clear_show, firmware_clear_store);

void msg2133_init_class()
{
 firmware_class = class_create(THIS_MODULE,"mtk-tpd" );//client->name

 if(IS_ERR(firmware_class))
  pr_err("Failed to create class(firmware)!\n");

 firmware_cmd_dev = device_create(firmware_class,
                                      NULL, 0, NULL, "device");//device

 if(IS_ERR(firmware_cmd_dev))
  pr_err("Failed to create device(firmware_cmd_dev)!\n");
  
 // version /sys/class/mtk-tpd/device/version
 if(device_create_file(firmware_cmd_dev, &dev_attr_version) < 0)
  pr_err("Failed to create device file(%s)!\n", dev_attr_version.attr.name);

 // update /sys/class/mtk-tpd/device/update
 if(device_create_file(firmware_cmd_dev, &dev_attr_update) < 0)
  pr_err("Failed to create device file(%s)!\n", dev_attr_update.attr.name);

 // data /sys/class/mtk-tpd/device/data
 if(device_create_file(firmware_cmd_dev, &dev_attr_data) < 0)
  pr_err("Failed to create device file(%s)!\n", dev_attr_data.attr.name);

 // clear /sys/class/mtk-tpd/device/clear
 if(device_create_file(firmware_cmd_dev, &dev_attr_clear) < 0)
  pr_err("Failed to create device file(%s)!\n", dev_attr_clear.attr.name);
}

#endif //endif MSG2133_UPDATE

static void msg2133_device_power_on()
{
 LDO_SetVoltLevel(LDO_LDO_SIM2, LDO_VOLT_LEVEL0);
 LDO_TurnOnLDO(LDO_LDO_SIM2);
 
 MSG2133_DBG("msg2133: power on\n");
}

static void msg2133_device_power_off()
{
// LDO_TurnOffLDO(LDO_LDO_SIM2);
 MSG2133_DBG("msg2133: power off\n");
}


#ifdef VIRTUAL_KEYS

/*
#define MSG2312_KEY_HOME 102
#define MSG2312_KEY_MENU 229
#define MSG2312_KEY_BACK 158
#define MSG2312_KEY_SEARCH  127

static ssize_t virtual_keys_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
 return sprintf(buf,
  __stringify(EV_KEY) ":" __stringify(MSG2312_KEY_HOME) ":180:900:64:60"
  ":" __stringify(EV_KEY) ":" __stringify(MSG2312_KEY_MENU) ":80:900:64:60"
  ":" __stringify(EV_KEY) ":" __stringify(MSG2312_KEY_BACK) ":280:900:64:60"
  ":" __stringify(EV_KEY) ":" __stringify(MSG2312_KEY_SEARCH) ":380:900:64:60"
  "\n");

}
*/

static ssize_t virtual_keys_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
 return sprintf(buf,
  __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":180:900:64:60"
  ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":80:900:64:60"
  ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":280:900:64:60"
  ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":380:900:64:60"
  "\n");
}


static struct kobj_attribute virtual_keys_attr = {
    .attr = {
        .name = "virtualkeys.msg2133",
        .mode = S_IRUGO,
    },
    .show = &virtual_keys_show,
};

static struct attribute *properties_attrs[] = {
    &virtual_keys_attr.attr,
    NULL
};

static struct attribute_group properties_attr_group = {
    .attrs = properties_attrs,
};

static void virtual_keys_init(void)
{
    int ret;
    struct kobject *properties_kobj;
 
    MSG2133_DBG("%s\n",__func__);
 
    properties_kobj = kobject_create_and_add("board_properties", NULL);
    if (properties_kobj)
        ret = sysfs_create_group(properties_kobj,
                     &properties_attr_group);
    if (!properties_kobj || ret)
        pr_err("failed to create board_properties\n");   
}
#endif

unsigned char msg2133_check_sum(unsigned char *pval)
{
    int i, sum = 0;

    for(i = 0; i < 7; i++)
    {
        sum += pval[i];
    }

    return (unsigned char)((-sum) & 0xFF);
}

static int msg2133_read_data(struct i2c_client *client)
{

 int ret, keycode;
 unsigned char reg_val[8] = {0};
 int dst_x=0,dst_y=0,xysawp_temp=0;
 unsigned int temp_checksum;
 struct TouchScreenInfo_t touchData;
 struct msg2133_ts_data *data = i2c_get_clientdata(this_client);
 struct ts_event *event = &data->event;
 
 event->touch_point = 0;
 ret = i2c_master_recv(client, reg_val, 8);
 MSG2133_DBG("dxf::%s: ret = %d\n", __func__, ret);
 if(ret <= 0)
  return ret;

 event->x1 =  ((reg_val[1] & 0xF0) << 4) | reg_val[2]; 
 event->y1  = ((reg_val[1] & 0x0F) << 8) | reg_val[3];
 dst_x = ((reg_val[4] & 0xF0) << 4) | reg_val[5];
 dst_y = ((reg_val[4] & 0x0F) << 8) | reg_val[6];


 temp_checksum = msg2133_check_sum(reg_val);
 // if check not ok , discard this point
 if((temp_checksum != reg_val[7]) || (reg_val[0] != 0x52) ){
  return 0;
 }
 else
 {
  if ((reg_val[1] == 0xFF) && (reg_val[2] == 0xFF) && (reg_val[3] == 0xFF) && (reg_val[4] == 0xFF) && (reg_val[6] == 0xFF))
  {
   event->x1 = 0; // final X coordinate
            event->y1 = 0; // final Y coordinate

   if((reg_val[5]==0x0)||(reg_val[5]==0xFF)){
    event->touch_point  = 0; //touch end
                touchData.nTouchKeyCode = 0; //TouchKeyMode
                touchData.nTouchKeyMode = 0; //TouchKeyMode
                keycode=0;
   }else// if have key down
   {
                touchData.nTouchKeyMode = 1; //TouchKeyMode
                touchData.nTouchKeyCode = reg_val[5]; //TouchKeyCode
                keycode= reg_val[5];
    MSG2133_DBG("dxf:: %s: keycode = %d -----------\n", __func__, keycode);
    #if 1
    // keyset, by duanxufang-----
    if(keycode==1){ // keycode==1 --> menu key
      event->x1 = 80; // final X coordinate
              event->y1 = 900; // final Y coordinate

    }else if(keycode==2){ // keycode==2 --> home key
      event->x1 = 180; // final X coordinate
              event->y1 = 900; // final Y coordinate

    }else if(keycode==4){ // keycode==4 --> back key
      event->x1 = 280; // final X coordinate
              event->y1 = 900; // final Y coordinate

    }else{// keycode == 8   --> search key
    
      event->x1 = 380; // final X coordinate
              event->y1 = 900; // final Y coordinate
    }
    #endif
                event->touch_point  = 1;
            }
  }else
  {// if touch on screen
   touchData.nTouchKeyMode = 0; //Touch on screen...

   if ((dst_x == 0) && (dst_y == 0)){
    event->touch_point  = 1; //one touch
    MSG2133_DBG("dxf:: %s: event->touch_point = %d\n", __func__, event->touch_point);
   #if 0
    xysawp_temp=cinfo->x1;
    cinfo->x1=2047-cinfo->y1;
    cinfo->y1=xysawp_temp;
   #endif
    event->x1 = (event->x1 * TS_WIDTH_MAX) / 2048;
    event->y1 = (event->y1 * TS_HEIGHT_MAX) / 2048;
   }else{
    event->touch_point  = 2; //two touch
    MSG2133_DBG("dxf:: %s: event->touch_point = %d\n", __func__, event->touch_point);
    if (dst_x > 2048) {    //transform the unsigh value to sign value
     dst_x -= 4096;
    }
    if (dst_y > 2048){
     dst_y -= 4096;
    }

    event->x2 = (event->x1 + dst_x);
    event->y2 = (event->y1 + dst_y);
    
   #if 0
    xysawp_temp=cinfo->x1;
    cinfo->x1=2047-cinfo->y1;
    cinfo->y1=xysawp_temp;

    xysawp_temp=cinfo->x2;
    cinfo->x2=2047-cinfo->y2;
    cinfo->y2=xysawp_temp;
   #endif
    //convert to screen resolution
    event->x1 = (event->x1 * TS_WIDTH_MAX) / 2048;
    event->y1 = (event->y1 * TS_HEIGHT_MAX) / 2048;

    event->x2 = (event->x2 * TS_WIDTH_MAX) / 2048;
    event->y2 = (event->y2 * TS_HEIGHT_MAX) / 2048;

   }
  }
        return 1;
    }//if((temp_checksum != reg_val[7]) || (reg_val[0] != 0x52) )
 
  return 1;

}

static void msg2133_report_value(struct i2c_client *client)
{
 struct msg2133_ts_data *data = i2c_get_clientdata(this_client);
 struct ts_event *event = &data->event;

 MSG2133_DBG("%s, point = %d\n", __func__, event->touch_point);
 if(event->touch_point){
  //input_report_key(data->input_dev, BTN_TOUCH, 1);// commented by dxf
  switch(event->touch_point) {
   case 2:
    MSG2133_DBG("%s, ::::x2=%d, y2=%d ::::\n", __func__, event->x2, event->y2);
    input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 15);
    input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x2);
    input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y2);
    input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
    input_mt_sync(data->input_dev);
    
   case 1:
    MSG2133_DBG("%s, ::::x1=%d, y1=%d::::\n", __func__, event->x1, event->y1);
    input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 15);
    input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x1);
    input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y1);
    input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
    input_mt_sync(data->input_dev);

   default:
 //   MSG2133_DBG("==touch_point default =\n");
    break;
  }
 }else{// if event->touch_point==0
  //input_report_key(data->input_dev, BTN_TOUCH, 0);  //commented by dxf
  input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0);
 }

 input_sync(data->input_dev); // active
} /*end msg2133_report_value*/

static void msg2133_ts_pen_irq_work(struct work_struct *work)
{
 int ret = -1;
 MSG2133_DBG("%s\n", __func__);
 ret = msg2133_read_data(this_client); 
 MSG2133_DBG("%s, ret = %d\n", __func__, ret);
 if (ret) { 
  msg2133_report_value(this_client);
 }
    enable_irq(this_client->irq);

}

static irqreturn_t msg2133_ts_interrupt(int irq, void *dev_id)
{
 struct msg2133_ts_data *msg2133_ts = (struct msg2133_ts_data *)dev_id;

 MSG2133_DBG("%s\n", __func__);

    disable_irq_nosync(this_client->irq);
 if (!work_pending(&msg2133_ts->pen_event_work)) {
  queue_work(msg2133_ts->ts_workqueue, &msg2133_ts->pen_event_work);
 }
 
 return IRQ_HANDLED;
}

static void msg2133_ts_suspend(struct early_suspend *handler)
{
 MSG2133_DBG("==%s==\n", __func__);
 disable_irq_nosync(this_client->irq);
    msleep(3);
 gpio_set_value(sprd_3rdparty_gpio_tp_rst, TS_ENPIN_LEVEL);
 msleep(10);
 
 msg2133_device_power_off();
}

static void msg2133_ts_resume(struct early_suspend *handler)

 MSG2133_DBG("==%s==start==\n", __func__);
 gpio_set_value(sprd_3rdparty_gpio_tp_rst, TS_ENPIN_LEVEL);
 msg2133_device_power_on();
 msleep(20);
 gpio_set_value(sprd_3rdparty_gpio_tp_rst,!TS_ENPIN_LEVEL);
 msleep(100);
 enable_irq(this_client->irq);
}

static int msg2133_ts_config_pins(void)
{
 int msg2133_irq;
 
 gpio_direction_output(sprd_3rdparty_gpio_tp_rst, 1); 
 gpio_direction_input(sprd_3rdparty_gpio_tp_irq);  
 gpio_set_value(sprd_3rdparty_gpio_tp_rst, !TS_ENPIN_LEVEL);
 
 msg2133_irq=sprd_alloc_gpio_irq(sprd_3rdparty_gpio_tp_irq);
 
 msleep(10); //wait for stable  
 return msg2133_irq;
}


static int msg2133_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
 struct msg2133_ts_data *msg2133_ts;
 struct input_dev *input_dev;
 int err = 0;
 
 MSG2133_DBG("%s\n", __func__);

 this_client = client;
 client->irq = msg2133_ts_config_pins();

 msg2133_device_power_on();
 
 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  err = -ENODEV;
  goto exit_check_functionality_failed;
 }

 msg2133_ts = kzalloc(sizeof(*msg2133_ts), GFP_KERNEL);
 if (!msg2133_ts) {
  err = -ENOMEM;
  goto exit_alloc_data_failed;
 }
 
 i2c_set_clientdata(client, msg2133_ts);

 MSG2133_DBG("I2C addr=%x", client->addr);

 INIT_WORK(&msg2133_ts->pen_event_work, msg2133_ts_pen_irq_work);

 msg2133_ts->ts_workqueue = create_singlethread_workqueue(dev_name(&client->dev));
 if (!msg2133_ts->ts_workqueue) {
  err = -ESRCH;
  goto exit_create_singlethread;
 }
 
// MSG2133_DBG("==request_irq=\n");
 MSG2133_DBG("%s: %s IRQ number is %d", __func__, client->name, client->irq);
 err = request_irq(client->irq, msg2133_ts_interrupt, IRQF_TRIGGER_FALLING, client->name, msg2133_ts);
 if (err < 0) {
  MSG2133_DBG("%s: msg2133_probe: request irq failed\n", __func__);
  goto exit_irq_request_failed;
 }

 disable_irq(client->irq);

// MSG2133_DBG("==input_allocate_device=\n");
 input_dev = input_allocate_device();
 if (!input_dev) {
  err = -ENOMEM;
  MSG2133_DBG("%s: failed to allocate input device\n", __func__);
  goto exit_input_dev_alloc_failed;
 }
 
 msg2133_ts->input_dev = input_dev; 

 __set_bit(EV_ABS, input_dev->evbit);
 __set_bit(EV_KEY, input_dev->evbit);
 __set_bit(EV_SYN, input_dev->evbit);


 __set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
 __set_bit(ABS_MT_POSITION_X, input_dev->absbit);
 __set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
 __set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);

#ifdef VIRTUAL_KEYS
 __set_bit(KEY_MENU,  input_dev->keybit);
 __set_bit(KEY_BACK,  input_dev->keybit);
 __set_bit(KEY_HOME,  input_dev->keybit);
 __set_bit(KEY_SEARCH,  input_dev->keybit);
#endif

 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, TS_WIDTH_MAX, 0, 0);
 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, TS_HEIGHT_MAX, 0, 0);
 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
 input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);

 

 input_dev->name  = MSG2133_TS_NAME;  //dev_name(&client->dev)
 err = input_register_device(input_dev);
 if (err) {
  dev_err(&client->dev,
  "msg2133_ts_probe: failed to register input device: %s\n",
  dev_name(&client->dev));
  goto exit_input_register_device_failed;
 }

 MSG2133_DBG("==register_early_suspend =");
 msg2133_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
 msg2133_ts->early_suspend.suspend = msg2133_ts_suspend;
 msg2133_ts->early_suspend.resume = msg2133_ts_resume;
 register_early_suspend(&msg2133_ts->early_suspend);

    msleep(50);
    //get some register information
   
#ifdef MSG2133_UPDATE
 msg2133_init_class();
#endif

#ifdef VIRTUAL_KEYS
 virtual_keys_init();
#endif

    enable_irq(client->irq);

    return 0;

exit_input_register_device_failed:
 input_free_device(input_dev);
exit_input_dev_alloc_failed:
 free_irq(client->irq, msg2133_ts);
exit_irq_request_failed:
 cancel_work_sync(&msg2133_ts->pen_event_work);
 destroy_workqueue(msg2133_ts->ts_workqueue);
exit_create_singlethread:
 MSG2133_DBG("==singlethread error =\n");
 i2c_set_clientdata(client, NULL);
 kfree(msg2133_ts);
exit_alloc_data_failed:
exit_check_functionality_failed:
 sprd_free_gpio_irq(client->irq);
 return err;
}

static int __devexit msg2133_ts_remove(struct i2c_client *client)
{

 struct msg2133_ts_data *msg2133_ts = i2c_get_clientdata(client);

 MSG2133_DBG("==msg2133_ts_remove=\n");
 
 unregister_early_suspend(&msg2133_ts->early_suspend);
 free_irq(client->irq, msg2133_ts);
 sprd_free_gpio_irq(this_client->irq);
 input_unregister_device(msg2133_ts->input_dev);
 kfree(msg2133_ts);
 cancel_work_sync(&msg2133_ts->pen_event_work);
 destroy_workqueue(msg2133_ts->ts_workqueue);
 i2c_set_clientdata(client, NULL);

 msg2133_device_power_off();
 return 0;
}

 

static const struct i2c_device_id msg2133_ts_id[] = {
 { MSG2133_TS_NAME, 0 },{ }
};

MODULE_DEVICE_TABLE(i2c, msg2133_ts_id);

static struct i2c_driver msg2133_ts_driver = {
 .probe  = msg2133_ts_probe,
 .remove  = __devexit_p(msg2133_ts_remove),
 .id_table = msg2133_ts_id,
 .driver = {
  .name = "MSG2133",
  //.name = MSG2133_TS_NAME, // msg2133_ts_driver.name 不一定要跟虚拟按键的 MSG2133_TS_NAME 一样。也就是说名字不一样,按键部分也可以正常工作。
  .owner = THIS_MODULE,
 },
};

int msg2133_add_i2c_device(struct i2c_board_info *info)
{
 int err;
 struct i2c_adapter *adapter;
 struct i2c_client *client;

 adapter = i2c_get_adapter(MSG2133_BUS_NUM);
 if (!adapter) {
  MSG2133_DBG("%s: can't get i2c adapter %d\n",
   __func__,  MSG2133_BUS_NUM);
  err = -ENODEV;
  goto err_driver;
 }

 client = i2c_new_device(adapter, info);
 if (!client) {
  MSG2133_DBG("%s:  can't add i2c device at 0x%x\n",
   __func__, (unsigned int)info->addr);
  err = -ENODEV;
  goto err_driver;
 }

 i2c_put_adapter(adapter);

 return 0;

err_driver:
 return err;
}

static int __init msg2133_init_module(void)
{
 MSG2133_DBG("%s\n", __func__);
 
 msg2133_add_i2c_device(&msg2133_i2c_boardinfo);
 return i2c_add_driver(&msg2133_ts_driver);
}

static void __exit msg2133_exit_module(void)
{
 MSG2133_DBG("%s\n", __func__);
 i2c_unregister_device(this_client);
 i2c_del_driver(&msg2133_ts_driver);
 
}

module_init(msg2133_init_module);
module_exit(msg2133_exit_module);

MODULE_LICENSE("GPL");

 

 

 

 

原创粉丝点击