*
* Copyright (C) 2012 Bruce Ding <bruce.ding@mstarsemi.com>
*
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/input.h>
+#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/timer.h>
#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include <linux/sysfs.h>
#include <linux/init.h>
#include <linux/string.h>
#include <asm/unistd.h>
#include <linux/cdev.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/regulator/consumer.h>
+
#if defined(CONFIG_HAS_EARLYSUSPEND)
#include <linux/earlysuspend.h>
#endif
#include <linux/notifier.h>
#include <linux/fb.h>
#endif
-#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
+#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
#include <linux/input/vir_ps.h>
#endif
-/*=============================================================*/
-// Macro Definition
-/*=============================================================*/
+/* Macro Definition */
#define TOUCH_DRIVER_DEBUG 0
#if (TOUCH_DRIVER_DEBUG == 1)
-#define DBG(fmt, arg...) pr_err(fmt, ##arg) //pr_info(fmt, ##arg)
+#define DBG(fmt, arg...) pr_info(fmt, ##arg)
#else
#define DBG(fmt, arg...)
#endif
-/*=============================================================*/
-// Constant Value & Variable Definition
-/*=============================================================*/
+/* Constant Value & Variable Definition */
+
+static struct regulator *vdd;
+static struct regulator *vcc_i2c;
+
+#define MSTAR_VTG_MIN_UV 2800000
+#define MSTAR_VTG_MAX_UV 3300000
+#define MSTAR_I2C_VTG_MIN_UV 1800000
+#define MSTAR_I2C_VTG_MAX_UV 1800000
-#define U8 unsigned char
-#define U16 unsigned short
-#define U32 unsigned int
-#define S8 signed char
-#define S16 signed short
-#define S32 signed int
#define TOUCH_SCREEN_X_MIN (0)
#define TOUCH_SCREEN_Y_MIN (0)
-/*
- * Note.
- * Please change the below touch screen resolution according to the touch panel that you are using.
- */
-#define TOUCH_SCREEN_X_MAX (480)
-#define TOUCH_SCREEN_Y_MAX (800)
+
+#define MAX_BUTTONS 4
+#define FT_COORDS_ARR_SIZE 4
+
+
/*
* Note.
* Please do not change the below setting.
#define TPD_WIDTH (2048)
#define TPD_HEIGHT (2048)
-/*
- * Note.
- * Please change the below GPIO pin setting to follow the platform that you are using
- */
-static int int_gpio = 1;
-static int reset_gpio = 0;
-#define MS_TS_MSG21XX_GPIO_RST reset_gpio
-#define MS_TS_MSG21XX_GPIO_INT int_gpio
-//---------------------------------------------------------------------//
-
-//#define SYSFS_AUTHORITY_CHANGE_FOR_CTS_TEST
-
-#ifdef SYSFS_AUTHORITY_CHANGE_FOR_CTS_TEST
-#define SYSFS_AUTHORITY (0644)
-#else
-#define SYSFS_AUTHORITY (0777)
-#endif
-
-#define FIRMWARE_AUTOUPDATE
#ifdef FIRMWARE_AUTOUPDATE
-typedef enum {
- SWID_START = 1,
- SWID_TRULY = SWID_START,
- SWID_NULL,
-} SWID_ENUM;
+enum {
+ SWID_START = 1,
+ SWID_TRULY = SWID_START,
+ SWID_NULL,
+};
-unsigned char MSG_FIRMWARE[1][33*1024] =
-{
- {
- #include "msg21xx_truly_update_bin.h"
- }
+static unsigned char MSG_FIRMWARE[1][33*1024] = { {
+ #include "msg21xx_truly_update_bin.h"
+ }
};
#endif
#define CONFIG_TP_HAVE_KEY
-/*
- * Note.
- * If the below virtual key value definition are not consistent with those that defined in key layout file of platform,
- * please change the below virtual key value to follow the platform that you are using.
- */
-#ifdef CONFIG_TP_HAVE_KEY
-#define TOUCH_KEY_MENU (139) //229
-#define TOUCH_KEY_HOME (172) //102
-#define TOUCH_KEY_BACK (158)
-#define TOUCH_KEY_SEARCH (217)
-
-const U16 tp_key_array[] = {TOUCH_KEY_MENU, TOUCH_KEY_HOME, TOUCH_KEY_BACK, TOUCH_KEY_SEARCH};
-#define MAX_KEY_NUM (sizeof(tp_key_array)/sizeof(tp_key_array[0]))
-#endif
+#define PINCTRL_STATE_ACTIVE "pmx_ts_active"
+#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend"
+#define PINCTRL_STATE_RELEASE "pmx_ts_release"
-#define SLAVE_I2C_ID_DBBUS (0xC4>>1)
-#define SLAVE_I2C_ID_DWI2C (0x4C>>1)
+#define SLAVE_I2C_ID_DBBUS (0xC4>>1)
-#define DEMO_MODE_PACKET_LENGTH (8)
-#define MAX_TOUCH_NUM (2) //5
+#define DEMO_MODE_PACKET_LENGTH (8)
+#define MAX_TOUCH_NUM (2)
#define TP_PRINT
#ifdef TP_PRINT
static void tp_print_create_entry(void);
#endif
-static char *fw_version = NULL; // customer firmware version
-static U16 fw_version_major = 0;
-static U16 fw_version_minor = 0;
-static U8 temp[94][1024];
-static U32 crc32_table[256];
-static int FwDataCnt = 0;
-static U8 bFwUpdating = 0;
-static struct class *firmware_class = NULL;
-static struct device *firmware_cmd_dev = NULL;
+static char *fw_version; /* customer firmware version */
+static unsigned short fw_version_major;
+static unsigned short fw_version_minor;
+static unsigned char temp[94][1024];
+static unsigned int crc32_table[256];
+static int FwDataCnt;
+static unsigned char bFwUpdating;
+static struct class *firmware_class;
+static struct device *firmware_cmd_dev;
+
+static struct i2c_client *i2c_client;
+
+static u32 button_map[MAX_BUTTONS];
+
+static u32 num_buttons;
+
+struct msg21xx_ts_platform_data {
+ const char *name;
+ const char *fw_name;
+ u32 irqflags;
+ u32 irq_gpio;
+ u32 irq_gpio_flags;
+ u32 reset_gpio;
+ u32 reset_gpio_flags;
+ u32 family_id;
+ u32 x_max;
+ u32 y_max;
+ u32 x_min;
+ u32 y_min;
+ u32 panel_minx;
+ u32 panel_miny;
+ u32 panel_maxx;
+ u32 panel_maxy;
+ u32 group_id;
+ u32 hard_rst_dly;
+ u32 soft_rst_dly;
+ u32 num_max_touches;
+ bool fw_vkey_support;
+ bool no_force_update;
+ bool i2c_pull_up;
+ bool ignore_id_check;
+ int (*power_init)(bool);
+ int (*power_on)(bool);
+};
+
+static struct msg21xx_ts_platform_data *pdata;
+
+struct msg21xx_ts_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ const struct msg21xx_ts_platform_data *pdata;
+ struct regulator *vdd;
+ struct regulator *vcc_i2c;
+ bool loading_fw;
+ u8 family_id;
+ struct dentry *dir;
+ u16 addr;
+ bool suspended;
+ char *ts_info;
+ u8 *tch_data;
+ u32 tch_data_len;
+ u8 fw_ver[3];
+ u8 fw_vendor_id;
+#if defined(CONFIG_FB)
+ struct notifier_block fb_notif;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ struct early_suspend early_suspend;
+#endif
+ struct pinctrl *ts_pinctrl;
+ struct pinctrl_state *pinctrl_state_active;
+ struct pinctrl_state *pinctrl_state_suspend;
+ struct pinctrl_state *pinctrl_state_release;
+ struct mutex ts_mutex;
+};
-static struct i2c_client *i2c_client = NULL;
+static struct msg21xx_ts_data *ts_data;
#if defined(CONFIG_FB)
-static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
-static struct notifier_block msg21xx_fb_notif;
-#elif defined (CONFIG_HAS_EARLYSUSPEND)
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
static struct early_suspend mstar_ts_early_suspend;
#endif
#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-static U8 bEnableTpProximity = 0;
-static U8 bFaceClosingTp = 0;
+static unsigned char bEnableTpProximity;
+static unsigned char bFaceClosingTp;
#endif
-static U8 bTpInSuspend = 0;
-static int irq_msg21xx = -1;
-static struct work_struct msg21xx_wk;
static struct mutex msg21xx_mutex;
-static struct input_dev *input_dev = NULL;
+static struct input_dev *input_dev;
-/*=============================================================*/
-// Data Type Definition
-/*=============================================================*/
-typedef struct
-{
- U16 x;
- U16 y;
-} touchPoint_t;
+/* Data Type Definition */
-/// max 80+1+1 = 82 bytes
-typedef struct
-{
- touchPoint_t point[MAX_TOUCH_NUM];
- U8 count;
- U8 keycode;
-} touchInfo_t;
+struct touchPoint_t {
+ unsigned short x;
+ unsigned short y;
+};
-enum i2c_speed
-{
- I2C_SLOW = 0,
- I2C_NORMAL = 1, /* Enable erasing/writing for 10 msec. */
- I2C_FAST = 2, /* Disable EWENB before 10 msec timeout. */
+struct touchInfo_t {
+ struct touchPoint_t point[MAX_TOUCH_NUM];
+ unsigned char count;
+ unsigned char keycode;
};
-typedef enum
-{
- EMEM_ALL = 0,
- EMEM_MAIN,
- EMEM_INFO,
-} EMEM_TYPE_t;
+enum i2c_speed {
+ I2C_SLOW = 0,
+ I2C_NORMAL = 1, /* Enable erasing/writing for 10 msec. */
+ I2C_FAST = 2, /* Disable EWENB before 10 msec timeout. */
+};
-/*=============================================================*/
-// Function Definition
-/*=============================================================*/
+enum EMEM_TYPE_t {
+ EMEM_ALL = 0,
+ EMEM_MAIN,
+ EMEM_INFO,
+};
-/// CRC
-static U32 _CRC_doReflect(U32 ref, S8 ch)
-{
- U32 value = 0;
- U32 i = 0;
-
- for (i = 1; i < (ch + 1); i ++)
- {
- if (ref & 1)
- {
- value |= 1 << (ch - i);
- }
- ref >>= 1;
- }
-
- return value;
-}
+/* Function Definition */
-U32 _CRC_getValue(U32 text, U32 prevCRC)
+static unsigned int _CRC_doReflect(unsigned int ref, signed char ch)
{
- U32 ulCRC = prevCRC;
+ unsigned int value = 0;
+ unsigned int i = 0;
- ulCRC = (ulCRC >> 8) ^ crc32_table[(ulCRC & 0xFF) ^ text];
+ for (i = 1; i < (ch + 1); i++) {
+ if (ref & 1)
+ value |= 1 << (ch - i);
+ ref >>= 1;
+ }
- return ulCRC;
+ return value;
}
-static void _CRC_initTable(void)
-{
- U32 magic_number = 0x04c11db7;
- U32 i, j;
-
- for (i = 0; i <= 0xFF; i ++)
- {
- crc32_table[i] = _CRC_doReflect (i, 8) << 24;
- for (j = 0; j < 8; j ++)
- {
- crc32_table[i] = (crc32_table[i] << 1) ^ (crc32_table[i] & (0x80000000L) ? magic_number : 0);
- }
- crc32_table[i] = _CRC_doReflect(crc32_table[i], 32);
- }
-}
-
-static void reset_hw(void)
+static unsigned int _CRC_getValue(unsigned int text, unsigned int prevCRC)
{
- DBG("reset_hw()\n");
+ unsigned int ulCRC = prevCRC;
- gpio_direction_output(MS_TS_MSG21XX_GPIO_RST, 1);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
- mdelay(100); /* Note that the RST must be in LOW 10ms at least */
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 1);
- mdelay(100); /* Enable the interrupt service thread/routine for INT after 50ms */
-}
+ ulCRC = (ulCRC >> 8) ^ crc32_table[(ulCRC & 0xFF) ^ text];
-static int read_i2c_seq(U8 addr, U8* buf, U16 size)
-{
- int rc = 0;
- struct i2c_msg msgs[] =
- {
- {
- .addr = addr,
- .flags = I2C_M_RD, // read flag
- .len = size,
- .buf = buf,
- },
- };
-
- /* If everything went ok (i.e. 1 msg transmitted), return #bytes
- transmitted, else error code. */
- if (i2c_client != NULL)
- {
- rc = i2c_transfer(i2c_client->adapter, msgs, 1);
- if (rc < 0)
- {
- DBG("read_i2c_seq() error %d\n", rc);
- }
- }
- else
- {
- DBG("i2c_client is NULL\n");
- }
-
- return rc;
+ return ulCRC;
}
-static int write_i2c_seq(U8 addr, U8* buf, U16 size)
+static void _CRC_initTable(void)
{
- int rc = 0;
- struct i2c_msg msgs[] =
- {
- {
- .addr = addr,
- .flags = 0, // if read flag is undefined, then it means write flag.
- .len = size,
- .buf = buf,
- },
- };
-
- /* If everything went ok (i.e. 1 msg transmitted), return #bytes
- transmitted, else error code. */
- if (i2c_client != NULL)
- {
- rc = i2c_transfer(i2c_client->adapter, msgs, 1);
- if ( rc < 0 )
- {
- DBG("write_i2c_seq() error %d\n", rc);
- }
- }
- else
- {
- DBG("i2c_client is NULL\n");
- }
-
- return rc;
+ unsigned int magic_number = 0x04c11db7;
+ unsigned int i, j;
+
+ for (i = 0; i <= 0xFF; i++) {
+ crc32_table[i] = _CRC_doReflect(i, 8) << 24;
+ for (j = 0; j < 8; j++)
+ crc32_table[i] = (crc32_table[i] << 1) ^
+ (crc32_table[i] & (0x80000000L) ?
+ magic_number : 0);
+ crc32_table[i] = _CRC_doReflect(crc32_table[i], 32);
+ }
}
-static U16 read_reg(U8 bank, U8 addr)
+static void reset_hw(void)
{
- U8 tx_data[3] = {0x10, bank, addr};
- U8 rx_data[2] = {0};
-
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 3);
- read_i2c_seq(SLAVE_I2C_ID_DBBUS, &rx_data[0], 2);
-
- return (rx_data[1] << 8 | rx_data[0]);
+ DBG("reset_hw()\n");
+
+ gpio_direction_output(pdata->reset_gpio, 1);
+ gpio_set_value_cansleep(pdata->reset_gpio, 0);
+ msleep(100); /* Note that the RST must be in LOW 10ms at least */
+ gpio_set_value_cansleep(pdata->reset_gpio, 1);
+ /* Enable the interrupt service thread/routine for INT after 50ms */
+ msleep(100);
}
-static void write_reg(U8 bank, U8 addr, U16 data)
+static int read_i2c_seq(unsigned char addr, unsigned char *buf,
+ unsigned short size)
{
- U8 tx_data[5] = {0x10, bank, addr, data & 0xFF, data >> 8};
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 5);
+ int rc = 0;
+ struct i2c_msg msgs[] = {
+ {
+ .addr = addr,
+ .flags = I2C_M_RD, /* read flag*/
+ .len = size,
+ .buf = buf,
+ },
+ };
+
+ /* If everything went ok (i.e. 1 msg transmitted), return #bytes
+ * transmitted, else error code.
+ */
+ if (i2c_client != NULL) {
+ rc = i2c_transfer(i2c_client->adapter, msgs, 1);
+ if (rc < 0)
+ DBG("read_i2c_seq() error %d\n", rc);
+ } else {
+ DBG("i2c_client is NULL\n");
+ }
+
+ return rc;
}
-static void write_reg_8bit(U8 bank, U8 addr, U8 data)
+static int write_i2c_seq(unsigned char addr, unsigned char *buf,
+ unsigned short size)
{
- U8 tx_data[4] = {0x10, bank, addr, data};
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 4);
+ int rc = 0;
+ struct i2c_msg msgs[] = {
+ {
+ .addr = addr,
+ /* if read flag is undefined,
+ * then it means write flag.
+ */
+ .flags = 0,
+ .len = size,
+ .buf = buf,
+ },
+ };
+
+ /* If everything went ok (i.e. 1 msg transmitted), return #bytes
+ * transmitted, else error code.
+ */
+ if (i2c_client != NULL) {
+ rc = i2c_transfer(i2c_client->adapter, msgs, 1);
+ if (rc < 0)
+ DBG("write_i2c_seq() error %d\n", rc);
+ } else {
+ DBG("i2c_client is NULL\n");
+ }
+
+ return rc;
}
-void dbbusDWIICEnterSerialDebugMode(void)
+static unsigned short read_reg(unsigned char bank, unsigned char addr)
{
- U8 data[5];
+ unsigned char tx_data[3] = {0x10, bank, addr};
+ unsigned char rx_data[2] = {0};
- // Enter the Serial Debug Mode
- data[0] = 0x53;
- data[1] = 0x45;
- data[2] = 0x52;
- data[3] = 0x44;
- data[4] = 0x42;
+ write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 3);
+ read_i2c_seq(SLAVE_I2C_ID_DBBUS, &rx_data[0], 2);
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 5);
+ return rx_data[1] << 8 | rx_data[0];
}
-void dbbusDWIICStopMCU(void)
+static void write_reg(unsigned char bank, unsigned char addr,
+ unsigned short data)
{
- U8 data[1];
-
- // Stop the MCU
- data[0] = 0x37;
+ unsigned char tx_data[5] = {0x10, bank, addr, data & 0xFF, data >> 8};
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+ write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 5);
}
-void dbbusDWIICIICUseBus(void)
+static void write_reg_8bit(unsigned char bank, unsigned char addr,
+ unsigned char data)
{
- U8 data[1];
+ unsigned char tx_data[4] = {0x10, bank, addr, data};
- // IIC Use Bus
- data[0] = 0x35;
-
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+ write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 4);
}
-void dbbusDWIICIICReshape(void)
+static void dbbusDWIICEnterSerialDebugMode(void)
{
- U8 data[1];
+ unsigned char data[5];
- // IIC Re-shape
- data[0] = 0x71;
+ /* Enter the Serial Debug Mode */
+ data[0] = 0x53;
+ data[1] = 0x45;
+ data[2] = 0x52;
+ data[3] = 0x44;
+ data[4] = 0x42;
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+ write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 5);
}
-void dbbusDWIICIICNotUseBus(void)
+static void dbbusDWIICStopMCU(void)
{
- U8 data[1];
+ unsigned char data[1];
- // IIC Not Use Bus
- data[0] = 0x34;
+ /* Stop the MCU */
+ data[0] = 0x37;
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+ write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
}
-void dbbusDWIICNotStopMCU(void)
+static void dbbusDWIICIICUseBus(void)
{
- U8 data[1];
+ unsigned char data[1];
- // Not Stop the MCU
- data[0] = 0x36;
+ /* IIC Use Bus */
+ data[0] = 0x35;
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+ write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
}
-void dbbusDWIICExitSerialDebugMode(void)
+static void dbbusDWIICIICReshape(void)
{
- U8 data[1];
-
- // Exit the Serial Debug Mode
- data[0] = 0x45;
+ unsigned char data[1];
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
+ /* IIC Re-shape */
+ data[0] = 0x71;
- // Delay some interval to guard the next transaction
- //udelay ( 200 ); // delay about 0.2ms
+ write_i2c_seq(SLAVE_I2C_ID_DBBUS, data, 1);
}
-//---------------------------------------------------------------------//
-
-static U8 get_ic_type(void)
+static unsigned char get_ic_type(void)
{
- U8 ic_type = 0;
-
- reset_hw();
- dbbusDWIICEnterSerialDebugMode();
- dbbusDWIICStopMCU();
- dbbusDWIICIICUseBus();
- dbbusDWIICIICReshape();
- mdelay ( 300 );
-
- // stop mcu
- write_reg_8bit ( 0x0F, 0xE6, 0x01 );
- // disable watch dog
- write_reg ( 0x3C, 0x60, 0xAA55 );
- // get ic type
- ic_type = (0xff)&(read_reg(0x1E, 0xCC));
-
- if (ic_type != 1 //msg2133
- && ic_type != 2 //msg21xxA
- && ic_type != 3) //msg26xxM
- {
- ic_type = 0;
- }
-
- reset_hw();
-
- return ic_type;
+ unsigned char ic_type = 0;
+
+ reset_hw();
+ dbbusDWIICEnterSerialDebugMode();
+ dbbusDWIICStopMCU();
+ dbbusDWIICIICUseBus();
+ dbbusDWIICIICReshape();
+ msleep(300);
+
+ /* stop mcu */
+ write_reg_8bit(0x0F, 0xE6, 0x01);
+ /* disable watch dog */
+ write_reg(0x3C, 0x60, 0xAA55);
+ /* get ic type */
+ ic_type = (0xff)&(read_reg(0x1E, 0xCC));
+
+ if (ic_type != 1 /* msg2133 */
+ && ic_type != 2 /* msg21xxA */
+ && ic_type != 3) /* msg26xxM */ {
+ ic_type = 0;
+ }
+
+ reset_hw();
+
+ return ic_type;
}
static int get_customer_firmware_version(void)
{
- U8 dbbus_tx_data[3] = {0};
- U8 dbbus_rx_data[4] = {0};
- int ret = 0;
+ unsigned char dbbus_tx_data[3] = {0};
+ unsigned char dbbus_rx_data[4] = {0};
+ int ret = 0;
+
+ DBG("get_customer_firmware_version()\n");
- DBG("get_customer_firmware_version()\n");
+ dbbus_tx_data[0] = 0x53;
+ dbbus_tx_data[1] = 0x00;
+ dbbus_tx_data[2] = 0x2A;
+ mutex_lock(&msg21xx_mutex);
+ write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3);
+ read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+ mutex_unlock(&msg21xx_mutex);
+ fw_version_major = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0];
+ fw_version_minor = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2];
- dbbus_tx_data[0] = 0x53;
- dbbus_tx_data[1] = 0x00;
- dbbus_tx_data[2] = 0x2A;
- mutex_lock(&msg21xx_mutex);
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 3);
- read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4);
- mutex_unlock(&msg21xx_mutex);
- fw_version_major = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0];
- fw_version_minor = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2];
+ DBG("*** major = %d ***\n", fw_version_major);
+ DBG("*** minor = %d ***\n", fw_version_minor);
- DBG("*** major = %d ***\n", fw_version_major);
- DBG("*** minor = %d ***\n", fw_version_minor);
+ if (fw_version == NULL)
+ fw_version = kzalloc(sizeof(char), GFP_KERNEL);
- if (fw_version == NULL)
- {
- fw_version = kzalloc(sizeof(char), GFP_KERNEL);
- }
+ snprintf(fw_version, sizeof(char) - 1, "%03d%03d",
+ fw_version_major, fw_version_minor);
- sprintf(fw_version, "%03d%03d", fw_version_major, fw_version_minor);
- return ret;
+ return ret;
}
-static int firmware_erase_c33 ( EMEM_TYPE_t emem_type )
+static int firmware_erase_c33(enum EMEM_TYPE_t emem_type)
{
- // stop mcu
- write_reg ( 0x0F, 0xE6, 0x0001 );
+ /* stop mcu */
+ write_reg(0x0F, 0xE6, 0x0001);
- //disable watch dog
- write_reg_8bit ( 0x3C, 0x60, 0x55 );
- write_reg_8bit ( 0x3C, 0x61, 0xAA );
+ /* disable watch dog */
+ write_reg_8bit(0x3C, 0x60, 0x55);
+ write_reg_8bit(0x3C, 0x61, 0xAA);
- // set PROGRAM password
- write_reg_8bit ( 0x16, 0x1A, 0xBA );
- write_reg_8bit ( 0x16, 0x1B, 0xAB );
+ /* set PROGRAM password */
+ write_reg_8bit(0x16, 0x1A, 0xBA);
+ write_reg_8bit(0x16, 0x1B, 0xAB);
- write_reg_8bit ( 0x16, 0x18, 0x80 );
+ write_reg_8bit(0x16, 0x18, 0x80);
- if ( emem_type == EMEM_ALL )
- {
- write_reg_8bit ( 0x16, 0x08, 0x10 ); //mark
- }
+ if (emem_type == EMEM_ALL)
+ write_reg_8bit(0x16, 0x08, 0x10);
- write_reg_8bit ( 0x16, 0x18, 0x40 );
- mdelay ( 10 );
+ write_reg_8bit(0x16, 0x18, 0x40);
+ msleep(20);
- // clear pce
- write_reg_8bit ( 0x16, 0x18, 0x80 );
+ /* clear pce */
+ write_reg_8bit(0x16, 0x18, 0x80);
- // erase trigger
- if ( emem_type == EMEM_MAIN )
- {
- write_reg_8bit ( 0x16, 0x0E, 0x04 ); //erase main
- }
- else
- {
- write_reg_8bit ( 0x16, 0x0E, 0x08 ); //erase all block
- }
+ /* erase trigger */
+ if (emem_type == EMEM_MAIN)
+ write_reg_8bit(0x16, 0x0E, 0x04); /* erase main */
+ else
+ write_reg_8bit(0x16, 0x0E, 0x08); /* erase all block */
- return ( 1 );
+ return 1;
}
-static ssize_t firmware_update_c33 ( struct device *dev, struct device_attribute *attr,
- const char *buf, size_t size, EMEM_TYPE_t emem_type )
-{
- U32 i, j;
- U32 crc_main, crc_main_tp;
- U32 crc_info, crc_info_tp;
- U16 reg_data = 0;
- int update_pass = 1;
-
- crc_main = 0xffffffff;
- crc_info = 0xffffffff;
-
- reset_hw();
- dbbusDWIICEnterSerialDebugMode();
- dbbusDWIICStopMCU();
- dbbusDWIICIICUseBus();
- dbbusDWIICIICReshape();
- mdelay ( 300 );
-
- //erase main
- firmware_erase_c33 ( EMEM_MAIN );
- mdelay ( 1000 );
-
- reset_hw();
- dbbusDWIICEnterSerialDebugMode();
- dbbusDWIICStopMCU();
- dbbusDWIICIICUseBus();
- dbbusDWIICIICReshape();
- mdelay ( 300 );
-
- /////////////////////////
- // Program
- /////////////////////////
-
- //polling 0x3CE4 is 0x1C70
- if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
- {
- do
- {
- reg_data = read_reg ( 0x3C, 0xE4 );
- }
- while ( reg_data != 0x1C70 );
- }
-
- switch ( emem_type )
- {
- case EMEM_ALL:
- write_reg ( 0x3C, 0xE4, 0xE38F ); // for all-blocks
- break;
- case EMEM_MAIN:
- write_reg ( 0x3C, 0xE4, 0x7731 ); // for main block
- break;
- case EMEM_INFO:
- write_reg ( 0x3C, 0xE4, 0x7731 ); // for info block
-
- write_reg_8bit ( 0x0F, 0xE6, 0x01 );
-
- write_reg_8bit ( 0x3C, 0xE4, 0xC5 );
- write_reg_8bit ( 0x3C, 0xE5, 0x78 );
-
- write_reg_8bit ( 0x1E, 0x04, 0x9F );
- write_reg_8bit ( 0x1E, 0x05, 0x82 );
-
- write_reg_8bit ( 0x0F, 0xE6, 0x00 );
- mdelay ( 100 );
- break;
- }
-
- // polling 0x3CE4 is 0x2F43
- do
- {
- reg_data = read_reg ( 0x3C, 0xE4 );
- }
- while ( reg_data != 0x2F43 );
-
- // calculate CRC 32
- _CRC_initTable ();
-
- for ( i = 0; i < 32; i++ ) // total 32 KB : 2 byte per R/W
- {
- if ( i == 31 )
- {
- temp[i][1014] = 0x5A;
- temp[i][1015] = 0xA5;
-
- for ( j = 0; j < 1016; j++ )
- {
- crc_main = _CRC_getValue ( temp[i][j], crc_main);
- }
- }
- else
- {
- for ( j = 0; j < 1024; j++ )
- {
- crc_main = _CRC_getValue ( temp[i][j], crc_main);
- }
- }
-
- //write_i2c_seq(SLAVE_I2C_ID_DWI2C, temp[i], 1024);
- for (j = 0; j < 8; j++)
- {
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &temp[i][j*128], 128 );
- }
- msleep (100);
-
- // polling 0x3CE4 is 0xD0BC
- do
- {
- reg_data = read_reg ( 0x3C, 0xE4 );
- }
- while ( reg_data != 0xD0BC );
-
- write_reg ( 0x3C, 0xE4, 0x2F43 );
- }
-
- if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
- {
- // write file done and check crc
- write_reg ( 0x3C, 0xE4, 0x1380 );
- }
- mdelay ( 10 );
-
- if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
- {
- // polling 0x3CE4 is 0x9432
- do
- {
- reg_data = read_reg ( 0x3C, 0xE4 );
- }while ( reg_data != 0x9432 );
- }
-
- crc_main = crc_main ^ 0xffffffff;
- crc_info = crc_info ^ 0xffffffff;
-
- if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
- {
- // CRC Main from TP
- crc_main_tp = read_reg ( 0x3C, 0x80 );
- crc_main_tp = ( crc_main_tp << 16 ) | read_reg ( 0x3C, 0x82 );
-
- // CRC Info from TP
- crc_info_tp = read_reg ( 0x3C, 0xA0 );
- crc_info_tp = ( crc_info_tp << 16 ) | read_reg ( 0x3C, 0xA2 );
- }
-
- update_pass = 1;
- if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) )
- {
- if ( crc_main_tp != crc_main )
- update_pass = 0;
-
- /*
- if ( crc_info_tp != crc_info )
- update_pass = 0;
- */
- }
-
- if ( !update_pass )
- {
- DBG( "update_C33 failed\n" );
- reset_hw();
- FwDataCnt = 0;
- return 0;
- }
-
- DBG( "update_C33 OK\n" );
- reset_hw();
- FwDataCnt = 0;
- return size;
+static ssize_t firmware_update_c33(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size,
+ enum EMEM_TYPE_t emem_type) {
+ unsigned int i, j;
+ unsigned int crc_main, crc_main_tp;
+ unsigned int crc_info, crc_info_tp;
+ unsigned short reg_data = 0;
+ int update_pass = 1;
+
+ crc_main = 0xffffffff;
+ crc_info = 0xffffffff;
+
+ reset_hw();
+ dbbusDWIICEnterSerialDebugMode();
+ dbbusDWIICStopMCU();
+ dbbusDWIICIICUseBus();
+ dbbusDWIICIICReshape();
+ msleep(300);
+
+ /* erase main */
+ firmware_erase_c33(EMEM_MAIN);
+ msleep(1000);
+
+ reset_hw();
+ dbbusDWIICEnterSerialDebugMode();
+ dbbusDWIICStopMCU();
+ dbbusDWIICIICUseBus();
+ dbbusDWIICIICReshape();
+ msleep(300);
+
+ /* polling 0x3CE4 is 0x1C70 */
+ if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+ do {
+ reg_data = read_reg(0x3C, 0xE4);
+ } while (reg_data != 0x1C70);
+ }
+
+ switch (emem_type) {
+ case EMEM_ALL:
+ write_reg(0x3C, 0xE4, 0xE38F); /* for all-blocks */
+ break;
+ case EMEM_MAIN:
+ write_reg(0x3C, 0xE4, 0x7731); /* for main block */
+ break;
+ case EMEM_INFO:
+ write_reg(0x3C, 0xE4, 0x7731); /* for info block */
+
+ write_reg_8bit(0x0F, 0xE6, 0x01);
+
+ write_reg_8bit(0x3C, 0xE4, 0xC5);
+ write_reg_8bit(0x3C, 0xE5, 0x78);
+
+ write_reg_8bit(0x1E, 0x04, 0x9F);
+ write_reg_8bit(0x1E, 0x05, 0x82);
+
+ write_reg_8bit(0x0F, 0xE6, 0x00);
+ msleep(100);
+ break;
+ }
+
+ /* polling 0x3CE4 is 0x2F43 */
+ do {
+ reg_data = read_reg(0x3C, 0xE4);
+ } while (reg_data != 0x2F43);
+
+ /* calculate CRC 32 */
+ _CRC_initTable();
+
+ /* total 32 KB : 2 byte per R/W */
+ for (i = 0; i < 32; i++) {
+ if (i == 31) {
+ temp[i][1014] = 0x5A;
+ temp[i][1015] = 0xA5;
+
+ for (j = 0; j < 1016; j++)
+ crc_main = _CRC_getValue(temp[i][j], crc_main);
+ } else {
+ for (j = 0; j < 1024; j++)
+ crc_main = _CRC_getValue(temp[i][j], crc_main);
+ }
+
+ for (j = 0; j < 8; j++)
+ write_i2c_seq(ts_data->client->addr,
+ &temp[i][j*128], 128);
+ msleep(100);
+
+ /* polling 0x3CE4 is 0xD0BC */
+ do {
+ reg_data = read_reg(0x3C, 0xE4);
+ } while (reg_data != 0xD0BC);
+
+ write_reg(0x3C, 0xE4, 0x2F43);
+ }
+
+ if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+ /* write file done and check crc */
+ write_reg(0x3C, 0xE4, 0x1380);
+ }
+ msleep(20);
+
+ if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+ /* polling 0x3CE4 is 0x9432 */
+ do {
+ reg_data = read_reg(0x3C, 0xE4);
+ } while (reg_data != 0x9432);
+ }
+
+ crc_main = crc_main ^ 0xffffffff;
+ crc_info = crc_info ^ 0xffffffff;
+
+ if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+ /* CRC Main from TP */
+ crc_main_tp = read_reg(0x3C, 0x80);
+ crc_main_tp = (crc_main_tp << 16) | read_reg(0x3C, 0x82);
+
+ /* CRC Info from TP */
+ crc_info_tp = read_reg(0x3C, 0xA0);
+ crc_info_tp = (crc_info_tp << 16) | read_reg(0x3C, 0xA2);
+ }
+
+ update_pass = 1;
+ if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
+ if (crc_main_tp != crc_main)
+ update_pass = 0;
+ }
+
+ if (!update_pass) {
+ DBG("update_C33 failed\n");
+ reset_hw();
+ FwDataCnt = 0;
+ return 0;
+ }
+
+ DBG("update_C33 OK\n");
+ reset_hw();
+ FwDataCnt = 0;
+ return size;
}
-
#ifdef FIRMWARE_AUTOUPDATE
-unsigned short main_sw_id = 0x7FF, info_sw_id = 0x7FF;
-U32 bin_conf_crc32 = 0;
+static unsigned short main_sw_id = 0x7FF, info_sw_id = 0x7FF;
+static unsigned int bin_conf_crc32;
-static U32 _CalMainCRC32(void)
+static unsigned int _CalMainCRC32(void)
{
- U32 ret=0;
- U16 reg_data=0;
+ unsigned int ret = 0;
+ unsigned short reg_data = 0;
- reset_hw();
+ reset_hw();
- dbbusDWIICEnterSerialDebugMode();
- dbbusDWIICStopMCU();
- dbbusDWIICIICUseBus();
- dbbusDWIICIICReshape();
- msleep ( 100 );
+ dbbusDWIICEnterSerialDebugMode();
+ dbbusDWIICStopMCU();
+ dbbusDWIICIICUseBus();
+ dbbusDWIICIICReshape();
+ msleep(100);
- //Stop MCU
- write_reg ( 0x0F, 0xE6, 0x0001 );
+ /* Stop MCU */
+ write_reg(0x0F, 0xE6, 0x0001);
- // Stop Watchdog
- write_reg_8bit ( 0x3C, 0x60, 0x55 );
- write_reg_8bit ( 0x3C, 0x61, 0xAA );
+ /* Stop Watchdog */
+ write_reg_8bit(0x3C, 0x60, 0x55);
+ write_reg_8bit(0x3C, 0x61, 0xAA);
- //cmd
- write_reg ( 0x3C, 0xE4, 0xDF4C );
- write_reg ( 0x1E, 0x04, 0x7d60 );
- // TP SW reset
- write_reg ( 0x1E, 0x04, 0x829F );
+ /* cmd */
+ write_reg(0x3C, 0xE4, 0xDF4C);
+ write_reg(0x1E, 0x04, 0x7d60);
+ /* TP SW reset */
+ write_reg(0x1E, 0x04, 0x829F);
- //MCU run
- write_reg ( 0x0F, 0xE6, 0x0000 );
+ /* MCU run */
+ write_reg(0x0F, 0xE6, 0x0000);
- //polling 0x3CE4
- do
- {
- reg_data = read_reg ( 0x3C, 0xE4 );
- }while ( reg_data != 0x9432 );
+ /* polling 0x3CE4 */
+ do {
+ reg_data = read_reg(0x3C, 0xE4);
+ } while (reg_data != 0x9432);
- // Cal CRC Main from TP
- ret = read_reg ( 0x3C, 0x80 );
- ret = ( ret << 16 ) | read_reg ( 0x3C, 0x82 );
+ /* Cal CRC Main from TP */
+ ret = read_reg(0x3C, 0x80);
+ ret = (ret << 16) | read_reg(0x3C, 0x82);
- DBG("[21xxA]:Current main crc32=0x%x\n",ret);
- return (ret);
+ DBG("[21xxA]:Current main crc32=0x%x\n", ret);
+ return ret;
}
-static void _ReadBinConfig ( void )
+static void _ReadBinConfig(void)
{
- U8 dbbus_tx_data[5]={0};
- U8 dbbus_rx_data[4]={0};
- U16 reg_data=0;
-
- reset_hw();
-
- dbbusDWIICEnterSerialDebugMode();
- dbbusDWIICStopMCU();
- dbbusDWIICIICUseBus();
- dbbusDWIICIICReshape();
- msleep ( 100 );
-
- //Stop MCU
- write_reg ( 0x0F, 0xE6, 0x0001 );
-
- // Stop Watchdog
- write_reg_8bit ( 0x3C, 0x60, 0x55 );
- write_reg_8bit ( 0x3C, 0x61, 0xAA );
-
- //cmd
- write_reg ( 0x3C, 0xE4, 0xA4AB );
- write_reg ( 0x1E, 0x04, 0x7d60 );
-
- // TP SW reset
- write_reg ( 0x1E, 0x04, 0x829F );
-
- //MCU run
- write_reg ( 0x0F, 0xE6, 0x0000 );
-
- //polling 0x3CE4
- do
- {
- reg_data = read_reg ( 0x3C, 0xE4 );
- }
- while ( reg_data != 0x5B58 );
-
- dbbus_tx_data[0] = 0x72;
- dbbus_tx_data[1] = 0x7F;
- dbbus_tx_data[2] = 0x55;
- dbbus_tx_data[3] = 0x00;
- dbbus_tx_data[4] = 0x04;
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 5 );
- read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4 );
- if ((dbbus_rx_data[0]>=0x30 && dbbus_rx_data[0]<=0x39)
- &&(dbbus_rx_data[1]>=0x30 && dbbus_rx_data[1]<=0x39)
- &&(dbbus_rx_data[2]>=0x31 && dbbus_rx_data[2]<=0x39))
- {
- main_sw_id = (dbbus_rx_data[0]-0x30)*100+(dbbus_rx_data[1]-0x30)*10+(dbbus_rx_data[2]-0x30);
- }
-
- dbbus_tx_data[0] = 0x72;
- dbbus_tx_data[1] = 0x7F;
- dbbus_tx_data[2] = 0xFC;
- dbbus_tx_data[3] = 0x00;
- dbbus_tx_data[4] = 0x04;
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 5 );
- read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4 );
- bin_conf_crc32 = dbbus_rx_data[0];
- bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[1];
- bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[2];
- bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[3];
-
- dbbus_tx_data[0] = 0x72;
- dbbus_tx_data[1] = 0x83;
- dbbus_tx_data[2] = 0x00;
- dbbus_tx_data[3] = 0x00;
- dbbus_tx_data[4] = 0x04;
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 5 );
- read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4 );
- if ((dbbus_rx_data[0]>=0x30 && dbbus_rx_data[0]<=0x39)
- &&(dbbus_rx_data[1]>=0x30 && dbbus_rx_data[1]<=0x39)
- &&(dbbus_rx_data[2]>=0x31 && dbbus_rx_data[2]<=0x39))
- {
- info_sw_id = (dbbus_rx_data[0]-0x30)*100+(dbbus_rx_data[1]-0x30)*10+(dbbus_rx_data[2]-0x30);
- }
-
- DBG("[21xxA]:main_sw_id = %d, info_sw_id = %d, bin_conf_crc32=0x%x\n", main_sw_id, info_sw_id, bin_conf_crc32);
+ unsigned char dbbus_tx_data[5] = {0};
+ unsigned char dbbus_rx_data[4] = {0};
+ unsigned short reg_data = 0;
+
+ reset_hw();
+
+ dbbusDWIICEnterSerialDebugMode();
+ dbbusDWIICStopMCU();
+ dbbusDWIICIICUseBus();
+ dbbusDWIICIICReshape();
+ msleep(100);
+
+ /* Stop MCU */
+ write_reg(0x0F, 0xE6, 0x0001);
+
+ /* Stop Watchdog */
+ write_reg_8bit(0x3C, 0x60, 0x55);
+ write_reg_8bit(0x3C, 0x61, 0xAA);
+
+ /* cmd */
+ write_reg(0x3C, 0xE4, 0xA4AB);
+ write_reg(0x1E, 0x04, 0x7d60);
+
+ /* TP SW reset */
+ write_reg(0x1E, 0x04, 0x829F);
+
+ /* MCU run */
+ write_reg(0x0F, 0xE6, 0x0000);
+
+ /* polling 0x3CE4 */
+ do {
+ reg_data = read_reg(0x3C, 0xE4);
+ } while (reg_data != 0x5B58);
+
+ dbbus_tx_data[0] = 0x72;
+ dbbus_tx_data[1] = 0x7F;
+ dbbus_tx_data[2] = 0x55;
+ dbbus_tx_data[3] = 0x00;
+ dbbus_tx_data[4] = 0x04;
+ write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5);
+ read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+ if ((dbbus_rx_data[0] >= 0x30 && dbbus_rx_data[0] <= 0x39)
+ && (dbbus_rx_data[1] >= 0x30 && dbbus_rx_data[1] <= 0x39)
+ && (dbbus_rx_data[2] >= 0x31 && dbbus_rx_data[2] <= 0x39)) {
+ main_sw_id = (dbbus_rx_data[0] - 0x30) * 100 +
+ (dbbus_rx_data[1] - 0x30) * 10 +
+ (dbbus_rx_data[2] - 0x30);
+ }
+
+ dbbus_tx_data[0] = 0x72;
+ dbbus_tx_data[1] = 0x7F;
+ dbbus_tx_data[2] = 0xFC;
+ dbbus_tx_data[3] = 0x00;
+ dbbus_tx_data[4] = 0x04;
+ write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5);
+ read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+ bin_conf_crc32 = dbbus_rx_data[0];
+ bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[1];
+ bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[2];
+ bin_conf_crc32 = (bin_conf_crc32<<8)|dbbus_rx_data[3];
+
+ dbbus_tx_data[0] = 0x72;
+ dbbus_tx_data[1] = 0x83;
+ dbbus_tx_data[2] = 0x00;
+ dbbus_tx_data[3] = 0x00;
+ dbbus_tx_data[4] = 0x04;
+ write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 5);
+ read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+ if ((dbbus_rx_data[0] >= 0x30 && dbbus_rx_data[0] <= 0x39)
+ && (dbbus_rx_data[1] >= 0x30 && dbbus_rx_data[1] <= 0x39)
+ && (dbbus_rx_data[2] >= 0x31 && dbbus_rx_data[2] <= 0x39)) {
+ info_sw_id = (dbbus_rx_data[0] - 0x30) * 100 +
+ (dbbus_rx_data[1] - 0x30) * 10 +
+ (dbbus_rx_data[2] - 0x30);
+ }
+
+ DBG("[21xxA]:main_sw_id = %d, info_sw_id = %d, bin_conf_crc32=0x%x\n",
+ main_sw_id, info_sw_id, bin_conf_crc32);
}
static int fwAutoUpdate(void *unused)
{
- int time = 0;
- ssize_t ret = 0;
-
- for (time = 0; time < 5; time++)
- {
- DBG("fwAutoUpdate time = %d\n",time);
- ret = firmware_update_c33(NULL, NULL, NULL, 1, EMEM_MAIN);
- if (ret == 1)
- {
- DBG("AUTO_UPDATE OK!!!");
- break;
- }
- }
- if (time == 5)
- {
- DBG("AUTO_UPDATE failed!!!");
- }
- enable_irq(irq_msg21xx);
- return 0;
+ int time = 0;
+ ssize_t ret = 0;
+
+ for (time = 0; time < 5; time++) {
+ DBG("fwAutoUpdate time = %d\n", time);
+ ret = firmware_update_c33(NULL, NULL, NULL, 1, EMEM_MAIN);
+ if (ret == 1) {
+ DBG("AUTO_UPDATE OK!!!");
+ break;
+ }
+ }
+ if (time == 5)
+ DBG("AUTO_UPDATE failed!!!");
+ enable_irq(ts_data->client->irq);
+ return 0;
}
#endif
-//------------------------------------------------------------------------------//
static ssize_t firmware_update_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
- DBG("*** firmware_update_show() fw_version = %s ***\n", fw_version);
+ DBG("*** firmware_update_show() fw_version = %s ***\n", fw_version);
- return sprintf(buf, "%s\n", fw_version);
+ return snprintf(buf, sizeof(char) - 1, "%s\n", fw_version);
}
static ssize_t firmware_update_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
{
- bFwUpdating = 1;
- disable_irq(irq_msg21xx);
+ bFwUpdating = 1;
+ disable_irq(ts_data->client->irq);
- DBG("*** update fw size = %d ***\n", FwDataCnt);
- size = firmware_update_c33 (dev, attr, buf, size, EMEM_MAIN);
+ DBG("*** update fw size = %d ***\n", FwDataCnt);
+ size = firmware_update_c33(dev, attr, buf, size, EMEM_MAIN);
- enable_irq(irq_msg21xx);
- bFwUpdating = 0;
+ enable_irq(ts_data->client->irq);
+ bFwUpdating = 0;
- return size;
+ return size;
}
-static DEVICE_ATTR(update, SYSFS_AUTHORITY, firmware_update_show, firmware_update_store);
+static DEVICE_ATTR(update, (S_IRUGO | S_IWUSR),
+ firmware_update_show,
+ firmware_update_store);
static ssize_t firmware_version_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
- DBG("*** firmware_version_show() fw_version = %s ***\n", fw_version);
+ DBG("*** firmware_version_show() fw_version = %s ***\n", fw_version);
- return sprintf(buf, "%s\n", fw_version);
+ return snprintf(buf, sizeof(char) - 1, "%s\n", fw_version);
}
static ssize_t firmware_version_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
{
- get_customer_firmware_version();
+ get_customer_firmware_version();
- DBG("*** firmware_version_store() fw_version = %s ***\n", fw_version);
+ DBG("*** firmware_version_store() fw_version = %s ***\n", fw_version);
- return size;
+ return size;
}
-static DEVICE_ATTR(version, SYSFS_AUTHORITY, firmware_version_show, firmware_version_store);
+static DEVICE_ATTR(version, (S_IRUGO | S_IWUSR),
+ firmware_version_show,
+ firmware_version_store);
static ssize_t firmware_data_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
- DBG("*** firmware_data_show() FwDataCnt = %d ***\n", FwDataCnt);
+ DBG("*** firmware_data_show() FwDataCnt = %d ***\n", FwDataCnt);
- return FwDataCnt;
+ return FwDataCnt;
}
static ssize_t firmware_data_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
{
- int count = size / 1024;
- int i;
+ int count = size / 1024;
+ int i;
- for (i = 0; i < count; i ++)
- {
- memcpy(temp[FwDataCnt], buf+(i*1024), 1024);
+ for (i = 0; i < count; i++) {
+ memcpy(temp[FwDataCnt], buf + (i * 1024), 1024);
- FwDataCnt ++;
- }
+ FwDataCnt++;
+ }
- DBG("***FwDataCnt = %d ***\n", FwDataCnt);
+ DBG("***FwDataCnt = %d ***\n", FwDataCnt);
- if (buf != NULL)
- {
- DBG("*** buf[0] = %c ***\n", buf[0]);
- }
+ if (buf != NULL)
+ DBG("*** buf[0] = %c ***\n", buf[0]);
- return size;
+ return size;
}
-static DEVICE_ATTR(data, SYSFS_AUTHORITY, firmware_data_show, firmware_data_store);
+static DEVICE_ATTR(data, (S_IRUGO | S_IWUSR),
+ firmware_data_show, firmware_data_store);
#ifdef TP_PRINT
static ssize_t tp_print_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
- tp_print_proc_read();
+ tp_print_proc_read();
- return sprintf(buf, "%d\n", bTpInSuspend);
+ return snprintf(buf, sizeof(char) - 1, "%d\n", ts_data->suspended);
}
static ssize_t tp_print_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
{
- DBG("*** tp_print_store() ***\n");
+ DBG("*** tp_print_store() ***\n");
- return size;
+ return size;
}
-static DEVICE_ATTR(tpp, SYSFS_AUTHORITY, tp_print_show, tp_print_store);
+static DEVICE_ATTR(tpp, (S_IRUGO | S_IWUSR),
+ tp_print_show, tp_print_store);
#endif
-//------------------------------------------------------------------------------//
#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-static void _msg_enable_proximity(void)
+static void _msg_enable_proximity(void
{
- U8 tx_data[4] = {0};
-
- DBG("_msg_enable_proximity!");
- tx_data[0] = 0x52;
- tx_data[1] = 0x00;
- tx_data[2] = 0x47;
- tx_data[3] = 0xa0;
- mutex_lock(&msg21xx_mutex);
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &tx_data[0], 4);
- mutex_unlock(&msg21xx_mutex);
-
- bEnableTpProximity = 1;
+ unsigned char tx_data[4] = {0};
+
+ DBG("_msg_enable_proximity!");
+ tx_data[0] = 0x52;
+ tx_data[1] = 0x00;
+ tx_data[2] = 0x47;
+ tx_data[3] = 0xa0;
+ mutex_lock(&msg21xx_mutex);
+ write_i2c_seq(ts_data->client->addr, &tx_data[0], 4);
+ mutex_unlock(&msg21xx_mutex);
+
+ bEnableTpProximity = 1;
}
static void _msg_disable_proximity(void)
{
- U8 tx_data[4] = {0};
-
- DBG("_msg_disable_proximity!");
- tx_data[0] = 0x52;
- tx_data[1] = 0x00;
- tx_data[2] = 0x47;
- tx_data[3] = 0xa1;
- mutex_lock(&msg21xx_mutex);
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &tx_data[0], 4);
- mutex_unlock(&msg21xx_mutex);
-
- bEnableTpProximity = 0;
- bFaceClosingTp = 0;
+ unsigned char tx_data[4] = {0};
+
+ DBG("_msg_disable_proximity!");
+ tx_data[0] = 0x52;
+ tx_data[1] = 0x00;
+ tx_data[2] = 0x47;
+ tx_data[3] = 0xa1;
+ mutex_lock(&msg21xx_mutex);
+ write_i2c_seq(ts_data->client->addr, &tx_data[0], 4);
+ mutex_unlock(&msg21xx_mutex);
+
+ bEnableTpProximity = 0;
+ bFaceClosingTp = 0;
}
-void tsps_msg21xx_enable(int en)
+static void tsps_msg21xx_enable(int en)
{
- if (en)
- {
- _msg_enable_proximity();
- }
- else
- {
- _msg_disable_proximity();
- }
+ if (en)
+ _msg_enable_proximity();
+ else
+ _msg_disable_proximity();
}
-int tsps_msg21xx_data(void)
+static int tsps_msg21xx_data(void)
{
- return bFaceClosingTp;
+ return bFaceClosingTp;
}
#endif
-static U8 calculate_checksum(U8 *msg, S32 length)
+static int msg21xx_pinctrl_init(void)
+{
+ int retval;
+
+ /* Get pinctrl if target uses pinctrl */
+ ts_data->ts_pinctrl = devm_pinctrl_get(&(i2c_client->dev));
+ if (IS_ERR_OR_NULL(ts_data->ts_pinctrl)) {
+ retval = PTR_ERR(ts_data->ts_pinctrl);
+ dev_dbg(&i2c_client->dev,
+ "Target does not use pinctrl %d\n", retval);
+ goto err_pinctrl_get;
+ }
+
+ ts_data->pinctrl_state_active = pinctrl_lookup_state(
+ ts_data->ts_pinctrl, PINCTRL_STATE_ACTIVE);
+ if (IS_ERR_OR_NULL(ts_data->pinctrl_state_active)) {
+ retval = PTR_ERR(ts_data->pinctrl_state_active);
+ dev_dbg(&i2c_client->dev,
+ "Can't lookup %s pinstate %d\n",
+ PINCTRL_STATE_ACTIVE, retval);
+ goto err_pinctrl_lookup;
+ }
+
+ ts_data->pinctrl_state_suspend = pinctrl_lookup_state(
+ ts_data->ts_pinctrl, PINCTRL_STATE_SUSPEND);
+ if (IS_ERR_OR_NULL(ts_data->pinctrl_state_suspend)) {
+ retval = PTR_ERR(ts_data->pinctrl_state_suspend);
+ dev_dbg(&i2c_client->dev,
+ "Can't lookup %s pinstate %d\n",
+ PINCTRL_STATE_SUSPEND, retval);
+ goto err_pinctrl_lookup;
+ }
+
+ ts_data->pinctrl_state_release = pinctrl_lookup_state(
+ ts_data->ts_pinctrl, PINCTRL_STATE_RELEASE);
+ if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) {
+ retval = PTR_ERR(ts_data->pinctrl_state_release);
+ dev_dbg(&i2c_client->dev,
+ "Can't lookup %s pinstate %d\n",
+ PINCTRL_STATE_RELEASE, retval);
+ }
+
+ return 0;
+
+err_pinctrl_lookup:
+ devm_pinctrl_put(ts_data->ts_pinctrl);
+err_pinctrl_get:
+ ts_data->ts_pinctrl = NULL;
+ return retval;
+}
+
+static unsigned char calculate_checksum(unsigned char *msg, int length)
{
- S32 Checksum = 0;
- S32 i;
+ int Checksum = 0, i;
- for (i = 0; i < length; i ++)
- {
- Checksum += msg[i];
- }
+ for (i = 0; i < length; i++)
+ Checksum += msg[i];
- return (U8)((-Checksum) & 0xFF);
+ return (unsigned char)((-Checksum) & 0xFF);
}
-static S32 parse_info(touchInfo_t *info)
+static int parse_info(struct touchInfo_t *info)
{
- U8 data[DEMO_MODE_PACKET_LENGTH] = {0};
- U8 checksum = 0;
- U32 x = 0, y = 0;
- U32 x2 = 0, y2 = 0;
- U32 delta_x = 0, delta_y = 0;
-
- mutex_lock(&msg21xx_mutex);
- read_i2c_seq(SLAVE_I2C_ID_DWI2C, &data[0], DEMO_MODE_PACKET_LENGTH);
- mutex_unlock(&msg21xx_mutex);
- checksum = calculate_checksum(&data[0], (DEMO_MODE_PACKET_LENGTH-1));
- DBG("check sum: [%x] == [%x]? \n", data[DEMO_MODE_PACKET_LENGTH-1], checksum);
-
- if(data[DEMO_MODE_PACKET_LENGTH-1] != checksum)
- {
- DBG("WRONG CHECKSUM\n");
- return -1;
- }
-
- if(data[0] != 0x52)
- {
- DBG("WRONG HEADER\n");
- return -1;
- }
-
- info->keycode = 0xFF;
- if ((data[1] == 0xFF) && (data[2] == 0xFF) && (data[3] == 0xFF) && (data[4] == 0xFF) && (data[6] == 0xFF))
- {
- if ((data[5] == 0xFF) || (data[5] == 0))
- {
- info->keycode = 0xFF;
- }
- else if ((data[5] == 1) || (data[5] == 2) || (data[5] == 4) || (data[5] == 8))
- {
- if (data[5] == 1)
- {
- info->keycode = 0;
- }
- else if (data[5] == 2)
- {
- info->keycode = 1;
- }
- else if (data[5] == 4)
- {
- info->keycode = 2;
- }
- else if (data[5] == 8)
- {
- info->keycode = 3;
- }
- }
- #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
- else if (bEnableTpProximity &&((data[5] == 0x80) || (data[5] == 0x40)))
- {
- if (data[5] == 0x80)
- {
- bFaceClosingTp = 1;
- }
- else if (data[5] == 0x40)
- {
- bFaceClosingTp = 0;
- }
- DBG("bEnableTpProximity=%d; bFaceClosingTp=%d; data[5]=%x;\n", bEnableTpProximity, bFaceClosingTp, data[5]);
- return -1;
- }
- #endif
- else
- {
- DBG("WRONG KEY\n");
- return -1;
- }
- }
- else
- {
- x = (((data[1] & 0xF0 ) << 4) | data[2]);
- y = ((( data[1] & 0x0F) << 8) | data[3]);
- delta_x = (((data[4] & 0xF0) << 4 ) | data[5]);
- delta_y = (((data[4] & 0x0F) << 8 ) | data[6]);
-
- if ((delta_x == 0) && (delta_y == 0))
- {
- info->point[0].x = x * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
- info->point[0].y = y * TOUCH_SCREEN_Y_MAX/ TPD_HEIGHT;
- info->count = 1;
- }
- else
- {
- if (delta_x > 2048)
- {
- delta_x -= 4096;
- }
- if (delta_y > 2048)
- {
- delta_y -= 4096;
- }
- x2 = (U32)((S16)x + (S16)delta_x);
- y2 = (U32)((S16)y + (S16)delta_y);
- info->point[0].x = x * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
- info->point[0].y = y * TOUCH_SCREEN_Y_MAX/ TPD_HEIGHT;
- info->point[1].x = x2 * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
- info->point[1].y = y2 * TOUCH_SCREEN_Y_MAX/ TPD_HEIGHT;
- info->count = 2;
- }
- }
-
- return 0;
+ unsigned char data[DEMO_MODE_PACKET_LENGTH] = {0};
+ unsigned char checksum = 0;
+ unsigned int x = 0, y = 0;
+ unsigned int x2 = 0, y2 = 0;
+ unsigned int delta_x = 0, delta_y = 0;
+
+ mutex_lock(&msg21xx_mutex);
+ read_i2c_seq(ts_data->client->addr, &data[0], DEMO_MODE_PACKET_LENGTH);
+ mutex_unlock(&msg21xx_mutex);
+ checksum = calculate_checksum(&data[0], (DEMO_MODE_PACKET_LENGTH-1));
+ DBG("check sum: [%x] == [%x]?\n",
+ data[DEMO_MODE_PACKET_LENGTH-1], checksum);
+
+ if (data[DEMO_MODE_PACKET_LENGTH-1] != checksum) {
+ DBG("WRONG CHECKSUM\n");
+ return -EINVAL;
+ }
+
+ if (data[0] != 0x52) {
+ DBG("WRONG HEADER\n");
+ return -EINVAL;
+ }
+
+ info->keycode = 0xFF;
+ if ((data[1] == 0xFF) && (data[2] == 0xFF) &&
+ (data[3] == 0xFF) && (data[4] == 0xFF) &&
+ (data[6] == 0xFF)) {
+ if ((data[5] == 0xFF) || (data[5] == 0)) {
+ info->keycode = 0xFF;
+ } else if ((data[5] == 1) || (data[5] == 2) ||
+ (data[5] == 4) || (data[5] == 8)) {
+ info->keycode = data[5] >> 1;
+
+ DBG("info->keycode index %d\n", info->keycode);
+ }
+ #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
+ else if (bEnableTpProximity && ((data[5] == 0x80) ||
+ (data[5] == 0x40))) {
+ if (data[5] == 0x80)
+ bFaceClosingTp = 1;
+ else if (data[5] == 0x40)
+ bFaceClosingTp = 0;
+
+ return -EINVAL;
+ }
+ #endif
+ else {
+ DBG("WRONG KEY\n");
+ return -EINVAL;
+ }
+ } else {
+ x = (((data[1] & 0xF0) << 4) | data[2]);
+ y = (((data[1] & 0x0F) << 8) | data[3]);
+ delta_x = (((data[4] & 0xF0) << 4) | data[5]);
+ delta_y = (((data[4] & 0x0F) << 8) | data[6]);
+
+ if ((delta_x == 0) && (delta_y == 0)) {
+ info->point[0].x = x * pdata->x_max / TPD_WIDTH;
+ info->point[0].y = y * pdata->y_max / TPD_HEIGHT;
+ info->count = 1;
+ } else {
+ if (delta_x > 2048)
+ delta_x -= 4096;
+
+ if (delta_y > 2048)
+ delta_y -= 4096;
+
+ x2 = (unsigned int)((signed short)x +
+ (signed short)delta_x);
+ y2 = (unsigned int)((signed short)y +
+ (signed short)delta_y);
+ info->point[0].x = x * pdata->x_max / TPD_WIDTH;
+ info->point[0].y = y * pdata->y_max / TPD_HEIGHT;
+ info->point[1].x = x2 * pdata->x_max / TPD_WIDTH;
+ info->point[1].y = y2 * pdata->y_max / TPD_HEIGHT;
+ info->count = 2;
+ }
+ }
+
+ return 0;
}
-static void touch_driver_touch_pressed(int x, int y)
+static void touch_driver_touch_released(void)
{
- DBG("point touch pressed");
+ int i;
+
+ DBG("point touch released\n");
+
+ for (i = 0; i < MAX_TOUCH_NUM; i++) {
+ input_mt_slot(input_dev, i);
+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
+ }
- input_report_key(input_dev, BTN_TOUCH, 1);
- input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 1);
- input_report_abs(input_dev, ABS_MT_POSITION_X, x);
- input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
- input_mt_sync(input_dev);
+ input_report_key(input_dev, BTN_TOUCH, 0);
+ input_report_key(input_dev, BTN_TOOL_FINGER, 0);
+ input_sync(input_dev);
}
-static void touch_driver_touch_released(void)
+/* read data through I2C then report data to input
+ *sub-system when interrupt occurred
+ */
+static irqreturn_t msg21xx_ts_interrupt(int irq, void *dev_id)
+{
+ struct touchInfo_t info;
+ int i = 0;
+ static int last_keycode = 0xFF;
+ static int last_count;
+
+ DBG("touch_driver_do_work()\n");
+
+ memset(&info, 0x0, sizeof(info));
+ if (parse_info(&info) == 0) {
+ #ifdef CONFIG_TP_HAVE_KEY
+ if (info.keycode != 0xFF) { /* key touch pressed */
+ if (info.keycode < num_buttons) {
+ if (info.keycode != last_keycode) {
+ DBG("key touch pressed");
+
+ input_report_key(input_dev,
+ BTN_TOUCH, 1);
+ input_report_key(input_dev,
+ button_map[info.keycode], 1);
+
+ last_keycode = info.keycode;
+ } else {
+ /* pass duplicate key-pressing */
+ DBG("REPEATED KEY\n");
+ }
+ } else {
+ DBG("WRONG KEY\n");
+ }
+ } else { /* key touch released */
+ if (last_keycode != 0xFF) {
+ DBG("key touch released");
+
+ input_report_key(input_dev,
+ BTN_TOUCH, 0);
+ input_report_key(input_dev,
+ button_map[last_keycode],
+ 0);
+
+ last_keycode = 0xFF;
+ }
+ }
+ #endif /* CONFIG_TP_HAVE_KEY */
+
+ if (info.count > 0) { /* point touch pressed */
+ for (i = 0; i < info.count; i++) {
+ input_mt_slot(input_dev, i);
+ input_mt_report_slot_state(input_dev,
+ MT_TOOL_FINGER, 1);
+ input_report_abs(input_dev,
+ ABS_MT_TOUCH_MAJOR, 1);
+ input_report_abs(input_dev,
+ ABS_MT_POSITION_X,
+ info.point[i].x);
+ input_report_abs(input_dev,
+ ABS_MT_POSITION_Y,
+ info.point[i].y);
+ }
+ last_count = info.count;
+ } else if (last_count > 0) { /* point touch released */
+ for (i = 0; i < last_count; i++) {
+ input_mt_slot(input_dev, i);
+ input_mt_report_slot_state(input_dev,
+ MT_TOOL_FINGER, 0);
+ }
+ last_count = 0;
+ }
+
+ input_report_key(input_dev, BTN_TOUCH, info.count > 0);
+ input_report_key(input_dev, BTN_TOOL_FINGER, info.count > 0);
+
+ input_sync(input_dev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+
+static int msg21xx_ts_power_init(void)
+{
+ int rc;
+
+ vdd = regulator_get(&i2c_client->dev, "vdd");
+ if (IS_ERR(vdd)) {
+ rc = PTR_ERR(vdd);
+ dev_err(&i2c_client->dev,
+ "Regulator get failed vdd rc=%d\n", rc);
+ return rc;
+ }
+
+ if (regulator_count_voltages(vdd) > 0) {
+ rc = regulator_set_voltage(vdd, MSTAR_VTG_MIN_UV,
+ MSTAR_VTG_MAX_UV);
+ if (rc) {
+ dev_err(&i2c_client->dev,
+ "Regulator set_vtg failed vdd rc=%d\n", rc);
+ goto reg_vdd_put;
+ }
+ }
+
+ vcc_i2c = regulator_get(&i2c_client->dev, "vcc_i2c");
+ if (IS_ERR(vcc_i2c)) {
+ rc = PTR_ERR(vcc_i2c);
+ dev_err(&i2c_client->dev,
+ "Regulator get failed vcc_i2c rc=%d\n", rc);
+ goto reg_vdd_set_vtg;
+ }
+
+ if (regulator_count_voltages(vcc_i2c) > 0) {
+ rc = regulator_set_voltage(vcc_i2c, MSTAR_I2C_VTG_MIN_UV,
+ MSTAR_I2C_VTG_MAX_UV);
+ if (rc) {
+ dev_err(&i2c_client->dev,
+ "Regulator set_vtg failed vcc_i2c rc=%d\n", rc);
+ goto reg_vcc_i2c_put;
+ }
+ }
+
+ return 0;
+
+reg_vcc_i2c_put:
+ regulator_put(vcc_i2c);
+reg_vdd_set_vtg:
+ if (regulator_count_voltages(vdd) > 0)
+ regulator_set_voltage(vdd, 0, MSTAR_VTG_MAX_UV);
+reg_vdd_put:
+ regulator_put(vdd);
+ return rc;
+}
+
+
+static int msg21xx_ts_power_deinit(void)
+{
+ if (regulator_count_voltages(vdd) > 0)
+ regulator_set_voltage(vdd, 0, MSTAR_VTG_MAX_UV);
+
+ regulator_put(vdd);
+
+ if (regulator_count_voltages(vcc_i2c) > 0)
+ regulator_set_voltage(vcc_i2c, 0, MSTAR_I2C_VTG_MAX_UV);
+
+ regulator_put(vcc_i2c);
+ return 0;
+}
+
+static int msg21xx_ts_power_on(void)
{
- DBG("point touch released");
+ int rc;
+
+ DBG("*** %s ***\n", __func__);
+ rc = regulator_enable(vdd);
+ if (rc) {
+ dev_err(&i2c_client->dev,
+ "Regulator vdd enable failed rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = regulator_enable(vcc_i2c);
+ if (rc) {
+ dev_err(&i2c_client->dev,
+ "Regulator vcc_i2c enable failed rc=%d\n", rc);
+ regulator_disable(vdd);
+ }
+
+ return rc;
+}
+
+static int msg21xx_ts_power_off(void)
+{
+ int rc;
+
+ DBG("*** %s ***\n", __func__);
+ rc = regulator_disable(vdd);
+ if (rc) {
+ dev_err(&i2c_client->dev,
+ "Regulator vdd disable failed rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = regulator_disable(vcc_i2c);
+ if (rc) {
+ dev_err(&i2c_client->dev,
+ "Regulator vcc_i2c disable failed rc=%d\n", rc);
+ rc = regulator_enable(vdd);
+ }
+
+ return rc;
+}
- input_report_key(input_dev, BTN_TOUCH, 0);
- input_mt_sync(input_dev);
+static int msg21xx_ts_gpio_configure(bool on)
+{
+ int ret = 0;
+
+ if (on) {
+ if (gpio_is_valid(pdata->irq_gpio)) {
+ ret = gpio_request(pdata->irq_gpio, "msg21xx_irq_gpio");
+ if (ret) {
+ dev_err(&i2c_client->dev,
+ "Failed to request GPIO[%d], %d\n",
+ pdata->irq_gpio, ret);
+ goto err_irq_gpio_req;
+ }
+ ret = gpio_direction_input(pdata->irq_gpio);
+ if (ret) {
+ dev_err(&i2c_client->dev,
+ "Failed to set direction for gpio[%d], %d\n",
+ pdata->irq_gpio, ret);
+ goto err_irq_gpio_dir;
+ }
+ gpio_set_value_cansleep(pdata->irq_gpio, 1);
+ } else {
+ dev_err(&i2c_client->dev, "irq gpio not provided\n");
+ goto err_irq_gpio_req;
+ }
+
+ if (gpio_is_valid(pdata->reset_gpio)) {
+ ret = gpio_request(pdata->reset_gpio,
+ "msg21xx_reset_gpio");
+ if (ret) {
+ dev_err(&i2c_client->dev,
+ "Failed to request GPIO[%d], %d\n",
+ pdata->reset_gpio, ret);
+ goto err_reset_gpio_req;
+ }
+
+ /* power on TP */
+ ret = gpio_direction_output(pdata->reset_gpio, 1);
+ if (ret) {
+ dev_err(&i2c_client->dev,
+ "Failed to set direction for GPIO[%d], %d\n",
+ pdata->reset_gpio, ret);
+ goto err_reset_gpio_dir;
+ }
+ msleep(100);
+ gpio_set_value_cansleep(pdata->reset_gpio, 0);
+ msleep(20);
+ gpio_set_value_cansleep(pdata->reset_gpio, 1);
+ msleep(200);
+ } else {
+ dev_err(&i2c_client->dev, "reset gpio not provided\n");
+ goto err_reset_gpio_req;
+ }
+
+ } else {
+ if (gpio_is_valid(pdata->irq_gpio))
+ gpio_free(pdata->irq_gpio);
+ if (gpio_is_valid(pdata->reset_gpio)) {
+ gpio_set_value_cansleep(pdata->reset_gpio, 0);
+ ret = gpio_direction_input(pdata->reset_gpio);
+ if (ret)
+ dev_err(&i2c_client->dev,
+ "Unable to set direction for gpio [%d]\n",
+ pdata->reset_gpio);
+ gpio_free(pdata->reset_gpio);
+ }
+ }
+ return 0;
+err_reset_gpio_dir:
+ if (gpio_is_valid(pdata->reset_gpio))
+ gpio_free(pdata->irq_gpio);
+err_reset_gpio_req:
+err_irq_gpio_dir:
+ if (gpio_is_valid(pdata->irq_gpio))
+ gpio_free(pdata->irq_gpio);
+err_irq_gpio_req:
+ return ret;
}
-/* read data through I2C then report data to input sub-system when interrupt occurred */
-void touch_driver_do_work(struct work_struct *work)
+#ifdef CONFIG_PM
+static int msg21xx_ts_resume(struct device *dev)
{
- touchInfo_t info;
- int i = 0;
- static int last_keycode = 0xFF;
- static int last_count = 0;
-
- DBG("touch_driver_do_work()\n");
-
- memset(&info, 0x0, sizeof(info));
- if (0 == parse_info(&info))
- {
- #ifdef CONFIG_TP_HAVE_KEY
- if (info.keycode != 0xFF) //key touch pressed
- {
- DBG("touch_driver_do_work() info.keycode=%x, last_keycode=%x, tp_key_array[%d]=%d\n", info.keycode, last_keycode, info.keycode, tp_key_array[info.keycode]);
- if (info.keycode < MAX_KEY_NUM)
- {
- if (info.keycode != last_keycode)
- {
- DBG("key touch pressed");
-
- input_report_key(input_dev, BTN_TOUCH, 1);
- input_report_key(input_dev, tp_key_array[info.keycode], 1);
-
- last_keycode = info.keycode;
- }
- else
- {
- /// pass duplicate key-pressing
- DBG("REPEATED KEY\n");
- }
- }
- else
- {
- DBG("WRONG KEY\n");
- }
- }
- else //key touch released
- {
- if (last_keycode != 0xFF)
- {
- DBG("key touch released");
-
- input_report_key(input_dev, BTN_TOUCH, 0);
- input_report_key(input_dev, tp_key_array[last_keycode], 0);
-
- last_keycode = 0xFF;
- }
- }
- #endif //CONFIG_TP_HAVE_KEY
-
- if (info.count > 0) //point touch pressed
- {
- for (i = 0; i < info.count; i ++)
- {
- touch_driver_touch_pressed(info.point[i].x, info.point[i].y);
- }
- last_count = info.count;
- }
- else if (last_count > 0) //point touch released
- {
- touch_driver_touch_released();
- last_count = 0;
- }
-
- input_sync(input_dev);
- }
-
- enable_irq(irq_msg21xx);
+ int retval;
+
+ mutex_lock(&ts_data->ts_mutex);
+ if (ts_data->suspended) {
+ if (ts_data->ts_pinctrl) {
+ retval = pinctrl_select_state(ts_data->ts_pinctrl,
+ ts_data->pinctrl_state_active);
+ if (retval < 0) {
+ dev_err(dev, "Cannot get active pinctrl state\n");
+ mutex_unlock(&ts_data->ts_mutex);
+ return retval;
+ }
+ }
+
+ retval = msg21xx_ts_gpio_configure(true);
+ if (retval) {
+ dev_err(dev, "Failed to put gpios in active state %d",
+ retval);
+ mutex_unlock(&ts_data->ts_mutex);
+ return retval;
+ }
+
+ enable_irq(ts_data->client->irq);
+
+ retval = msg21xx_ts_power_on();
+ if (retval) {
+ dev_err(dev, "msg21xx_ts power on failed");
+ mutex_unlock(&ts_data->ts_mutex);
+ return retval;
+ }
+
+ ts_data->suspended = 0;
+ } else {
+ dev_info(dev, "msg21xx_ts already in resume\n");
+ }
+ mutex_unlock(&ts_data->ts_mutex);
+
+ return 0;
}
-/* The interrupt service routine will be triggered when interrupt occurred */
-irqreturn_t touch_driver_isr(int irq, void *dev_id)
+static int msg21xx_ts_suspend(struct device *dev)
{
- DBG("touch_driver_isr()\n");
+ int retval;
+
+ if (bFwUpdating) {
+ DBG("suspend bFwUpdating=%d\n", bFwUpdating);
+ return 0;
+ }
- disable_irq_nosync(irq_msg21xx);
- schedule_work(&msg21xx_wk);
+#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
+ if (bEnableTpProximity) {
+ DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity);
+ return 0;
+ }
+#endif
- return IRQ_HANDLED;
+ mutex_lock(&ts_data->ts_mutex);
+ if (ts_data->suspended == 0) {
+ disable_irq(ts_data->client->irq);
+
+ touch_driver_touch_released();
+
+ retval = msg21xx_ts_power_off();
+ if (retval) {
+ dev_err(dev, "msg21xx_ts power off failed");
+ mutex_unlock(&ts_data->ts_mutex);
+ return retval;
+ }
+
+ if (ts_data->ts_pinctrl) {
+ retval = pinctrl_select_state(ts_data->ts_pinctrl,
+ ts_data->pinctrl_state_suspend);
+ if (retval < 0) {
+ dev_err(&i2c_client->dev, "Cannot get idle pinctrl state\n");
+ mutex_unlock(&ts_data->ts_mutex);
+ return retval;
+ }
+ }
+
+ retval = msg21xx_ts_gpio_configure(false);
+ if (retval) {
+ dev_err(dev, "Failed to put gpios in idle state %d",
+ retval);
+ mutex_unlock(&ts_data->ts_mutex);
+ return retval;
+ }
+
+ ts_data->suspended = 1;
+ } else {
+ dev_err(dev, "msg21xx_ts already in suspend\n");
+ }
+ mutex_unlock(&ts_data->ts_mutex);
+
+
+ return 0;
}
+#else
+static int msg21xx_ts_resume(struct device *dev)
+{
+ return 0;
+}
+static int msg21xx_ts_suspend(struct device *dev)
+{
+ return 0;
+}
+#endif
#if defined(CONFIG_FB)
-static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data)
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
{
- struct fb_event *evdata = data;
- int *blank;
-
- if (evdata && evdata->data && event == FB_EVENT_BLANK )
- {
- blank = evdata->data;
- if (*blank == FB_BLANK_UNBLANK)
- {
- if (bTpInSuspend)
- {
- gpio_direction_output(MS_TS_MSG21XX_GPIO_RST, 1);
- mdelay(10);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
- mdelay(10);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 1);
- mdelay(200);
-
- touch_driver_touch_released();
- input_sync(input_dev);
-
- enable_irq(irq_msg21xx);
- }
- bTpInSuspend = 0;
- }
- else if (*blank == FB_BLANK_POWERDOWN)
- {
- if (bFwUpdating)
- {
- DBG("suspend bFwUpdating=%d\n", bFwUpdating);
- return 0;
- }
-
- #ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
- if (bEnableTpProximity)
- {
- DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity);
- return 0;
- }
- #endif
-
- if (bTpInSuspend == 0)
- {
- disable_irq(irq_msg21xx);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
- }
- bTpInSuspend = 1;
- }
- }
-
- return 0;
+ struct fb_event *evdata = data;
+ int *blank;
+
+ if (evdata && evdata->data && event == FB_EVENT_BLANK) {
+ blank = evdata->data;
+ if (*blank == FB_BLANK_UNBLANK)
+ msg21xx_ts_resume(&i2c_client->dev);
+ else if (*blank == FB_BLANK_POWERDOWN)
+ msg21xx_ts_suspend(&i2c_client->dev);
+ }
+
+ return 0;
}
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
-void touch_driver_early_suspend(struct early_suspend *p)
+static void touch_driver_early_suspend(struct early_suspend *p)
{
- DBG("touch_driver_early_suspend()\n");
+ DBG("touch_driver_early_suspend()\n");
- if (bFwUpdating)
- {
- DBG("suspend bFwUpdating=%d\n", bFwUpdating);
- return;
- }
+ if (bFwUpdating) {
+ DBG("suspend bFwUpdating=%d\n", bFwUpdating);
+ return;
+ }
#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
- if (bEnableTpProximity)
- {
- DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity);
- return;
- }
+ if (bEnableTpProximity) {
+ DBG("suspend bEnableTpProximity=%d\n", bEnableTpProximity);
+ return;
+ }
#endif
- if (bTpInSuspend == 0)
- {
- disable_irq(irq_msg21xx);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
- }
- bTpInSuspend = 1;
+ if (bTpInSuspend == 0) {
+ disable_irq(ts_data->client->irq);
+ gpio_set_value_cansleep(pdata->reset_gpio, 0);
+ }
+
+
+ if (msg21xx_ts_power_off())
+ return;
+ bTpInSuspend = 1;
}
-void touch_driver_early_resume(struct early_suspend *p)
+static void touch_driver_early_resume(struct early_suspend *p)
{
- DBG("touch_driver_early_resume() bTpInSuspend=%d\n", bTpInSuspend);
-
- if (bTpInSuspend)
- {
- gpio_direction_output(MS_TS_MSG21XX_GPIO_RST, 1);
- mdelay(10);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
- mdelay(10);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 1);
- mdelay(200);
-
- touch_driver_touch_released();
- input_sync(input_dev);
-
- enable_irq(irq_msg21xx);
- }
- bTpInSuspend = 0;
+ DBG("touch_driver_early_resume() bTpInSuspend=%d\n", bTpInSuspend);
+
+ if (bTpInSuspend) {
+ gpio_direction_output(pdata->reset_gpio, 1);
+ msleep(20);
+ gpio_set_value_cansleep(pdata->reset_gpio, 0);
+ msleep(20);
+ gpio_set_value_cansleep(pdata->reset_gpio, 1);
+ msleep(200);
+
+ touch_driver_touch_released();
+ input_sync(input_dev);
+
+ enable_irq(ts_data->client->irq);
+
+ if (msg21xx_ts_power_on())
+ return;
+ }
+ bTpInSuspend = 0;
}
#endif
-/* probe function is used for matching and initializing input device */
-static int touch_driver_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int msg21xx_get_dt_coords(struct device *dev, char *name,
+ struct msg21xx_ts_platform_data *pdata)
+{
+ u32 coords[FT_COORDS_ARR_SIZE];
+ struct property *prop;
+ struct device_node *np = dev->of_node;
+ int coords_size, rc;
+
+ prop = of_find_property(np, name, NULL);
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+
+ coords_size = prop->length / sizeof(u32);
+ if (coords_size != FT_COORDS_ARR_SIZE) {
+ dev_err(dev, "invalid %s\n", name);
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32_array(np, name, coords, coords_size);
+ if (rc && (rc != -EINVAL)) {
+ dev_err(dev, "Unable to read %s\n", name);
+ return rc;
+ }
+
+ if (!strcmp(name, "mstar,panel-coords")) {
+ pdata->panel_minx = coords[0];
+ pdata->panel_miny = coords[1];
+ pdata->panel_maxx = coords[2];
+ pdata->panel_maxy = coords[3];
+ } else if (!strcmp(name, "mstar,display-coords")) {
+ pdata->x_min = coords[0];
+ pdata->y_min = coords[1];
+ pdata->x_max = coords[2];
+ pdata->y_max = coords[3];
+ } else {
+ dev_err(dev, "unsupported property %s\n", name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int msg21xx_parse_dt(struct device *dev,
+ struct msg21xx_ts_platform_data *pdata)
{
+ int rc;
+ struct device_node *np = dev->of_node;
+ struct property *prop;
+ u32 temp_val;
+
+ rc = msg21xx_get_dt_coords(dev, "mstar,panel-coords", pdata);
+ if (rc && (rc != -EINVAL))
+ return rc;
+
+ rc = msg21xx_get_dt_coords(dev, "mstar,display-coords", pdata);
+ if (rc)
+ return rc;
+
+ /* reset, irq gpio info */
+ pdata->reset_gpio = of_get_named_gpio_flags(np, "mstar,reset-gpio",
+ 0, &pdata->reset_gpio_flags);
+ if (pdata->reset_gpio < 0)
+ return pdata->reset_gpio;
+
+ pdata->irq_gpio = of_get_named_gpio_flags(np, "mstar,irq-gpio",
+ 0, &pdata->irq_gpio_flags);
+ if (pdata->irq_gpio < 0)
+ return pdata->irq_gpio;
+
+
+ prop = of_find_property(np, "mstar,button-map", NULL);
+ if (prop) {
+ num_buttons = prop->length / sizeof(temp_val);
+ if (num_buttons > MAX_BUTTONS)
+ return -EINVAL;
+
+ rc = of_property_read_u32_array(np,
+ "mstar,button-map", button_map,
+ num_buttons);
+ if (rc) {
+ dev_err(dev, "Unable to read key codes\n");
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+/* probe function is used for matching and initializing input device */
+static int msg21xx_ts_probe(struct i2c_client *client,
+ const struct i2c_device_id *id) {
#ifdef FIRMWARE_AUTOUPDATE
- unsigned short update_bin_major = 0, update_bin_minor = 0;
- int i, update_flag = 0;
+ unsigned short update_bin_major = 0, update_bin_minor = 0;
+ int i, update_flag = 0;
#endif
- int ret = 0;
-
- if (input_dev != NULL)
- {
- DBG("input device has found\n");
- return -1;
- }
-
- DBG("*** %s ***\n", __FUNCTION__);
-
- i2c_client = client;
-
- ret = gpio_request(MS_TS_MSG21XX_GPIO_RST, "reset");
- if (ret < 0)
- {
- pr_err("*** Failed to request GPIO %d, error %d ***\n", MS_TS_MSG21XX_GPIO_RST, ret);
- goto err0;
- }
-
- // power on TP
- gpio_direction_output(MS_TS_MSG21XX_GPIO_RST, 1);
- mdelay(100);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 0);
- mdelay(10);
- gpio_set_value(MS_TS_MSG21XX_GPIO_RST, 1);
- mdelay(200);
- if (0 == get_ic_type())
- {
- pr_err("the currnet ic is not Mstar\n");
- ret = -1;
- goto err0;
- }
-
- mutex_init(&msg21xx_mutex);
-
- /* allocate an input device */
- input_dev = input_allocate_device();
- if (!input_dev)
- {
- ret = -ENOMEM;
- pr_err("*** input device allocation failed ***\n");
- goto err1;
- }
-
- input_dev->name = client->name;
- input_dev->phys = "I2C";
- input_dev->dev.parent = &client->dev;
- input_dev->id.bustype = BUS_I2C;
-
- /* set the supported event type for input device */
- set_bit(EV_ABS, input_dev->evbit);
- set_bit(EV_SYN, input_dev->evbit);
- set_bit(EV_KEY, input_dev->evbit);
- set_bit(BTN_TOUCH, input_dev->keybit);
- set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+ int ret = 0;
+
+ if (input_dev != NULL) {
+ DBG("input device has found\n");
+ return -EINVAL;
+ }
+
+ if (client->dev.of_node) {
+ pdata = devm_kzalloc(&client->dev,
+ sizeof(struct msg21xx_ts_platform_data), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ ret = msg21xx_parse_dt(&client->dev, pdata);
+ if (ret) {
+ dev_err(&client->dev, "DT parsing failed\n");
+ return ret;
+ }
+ } else
+ pdata = client->dev.platform_data;
+
+ ts_data = devm_kzalloc(&client->dev,
+ sizeof(struct msg21xx_ts_data), GFP_KERNEL);
+ if (!ts_data)
+ return -ENOMEM;
+
+ DBG("*** %s ***\n", __func__);
+
+ i2c_client = client;
+
+ ret = msg21xx_ts_power_init();
+ if (ret)
+ dev_err(&client->dev, "Mstar power init failed\n");
+
+ ret = msg21xx_ts_power_on();
+ if (ret) {
+ dev_err(&client->dev, "Mstar power on failed\n");
+ goto exit_deinit_power;
+ }
+
+ ret = msg21xx_pinctrl_init();
+ if (!ret && ts_data->ts_pinctrl) {
+ ret = pinctrl_select_state(ts_data->ts_pinctrl,
+ ts_data->pinctrl_state_active);
+ if (ret < 0)
+ goto exit_pinctrl_select;
+ } else {
+ goto exit_pinctrl_init;
+ }
+
+ ret = msg21xx_ts_gpio_configure(true);
+ if (ret) {
+ dev_err(&client->dev, "Failed to configure gpio %d\n", ret);
+ goto exit_gpio_config;
+ }
+
+ if (get_ic_type() == 0) {
+ pr_err("the currnet ic is not Mstar\n");
+ ret = -1;
+ goto err_wrong_ic_type;
+ }
+
+ mutex_init(&msg21xx_mutex);
+ mutex_init(&ts_data->ts_mutex);
+
+ /* allocate an input device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ ret = -ENOMEM;
+ pr_err("*** input device allocation failed ***\n");
+ goto err_input_allocate_dev;
+ }
+
+ input_dev->name = client->name;
+ input_dev->phys = "I2C";
+ input_dev->dev.parent = &client->dev;
+ input_dev->id.bustype = BUS_I2C;
+
+ /* set the supported event type for input device */
+ set_bit(EV_ABS, input_dev->evbit);
+ set_bit(EV_SYN, input_dev->evbit);
+ set_bit(EV_KEY, input_dev->evbit);
+ set_bit(BTN_TOUCH, input_dev->keybit);
+ set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+ set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
+ ts_data->input_dev = input_dev;
+ ts_data->client = client;
+ ts_data->pdata = pdata;
+
+ input_set_drvdata(input_dev, ts_data);
+ i2c_set_clientdata(client, ts_data);
#ifdef CONFIG_TP_HAVE_KEY
- {
- int i;
- for (i = 0; i < MAX_KEY_NUM; i ++)
- {
- input_set_capability(input_dev, EV_KEY, tp_key_array[i]);
- }
- }
+ {
+ int i;
+
+ for (i = 0; i < num_buttons; i++)
+ input_set_capability(input_dev, EV_KEY, button_map[i]);
+ }
#endif
- input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 2, 0, 0);
- input_set_abs_params(input_dev, ABS_MT_POSITION_X, TOUCH_SCREEN_X_MIN, TOUCH_SCREEN_X_MAX, 0, 0);
- input_set_abs_params(input_dev, ABS_MT_POSITION_Y, TOUCH_SCREEN_Y_MIN, TOUCH_SCREEN_Y_MAX, 0, 0);
-
- /* register the input device to input sub-system */
- ret = input_register_device(input_dev);
- if (ret < 0)
- {
- pr_err("*** Unable to register ms-touchscreen input device ***\n");
- goto err1;
- }
-
- /* set sysfs for firmware */
- firmware_class = class_create(THIS_MODULE, "ms-touchscreen-msg20xx"); //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");
- if (IS_ERR(firmware_cmd_dev))
- pr_err("Failed to create device(firmware_cmd_dev)!\n");
-
- // 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
- 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
- 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);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+ 0, 2, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+ TOUCH_SCREEN_X_MIN, pdata->x_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+ TOUCH_SCREEN_Y_MIN, pdata->y_max, 0, 0);
+ input_mt_init_slots(input_dev, MAX_TOUCH_NUM, 0);
+
+ /* register the input device to input sub-system */
+ ret = input_register_device(input_dev);
+ if (ret < 0) {
+ pr_err("*** Unable to register ms-touchscreen input device ***\n");
+ goto err_input_reg_dev;
+ }
+
+ /* set sysfs for firmware */
+ firmware_class = class_create(THIS_MODULE, "ms-touchscreen-msg20xx");
+ if (IS_ERR(firmware_class))
+ pr_err("Failed to create class(firmware)!\n");
+
+ firmware_cmd_dev = device_create(firmware_class, NULL, 0,
+ NULL, "device");
+ if (IS_ERR(firmware_cmd_dev))
+ pr_err("Failed to create device(firmware_cmd_dev)!\n");
+
+ /* 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 */
+ 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 */
+ 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);
#ifdef TP_PRINT
- tp_print_create_entry();
+ tp_print_create_entry();
#endif
- dev_set_drvdata(firmware_cmd_dev, NULL);
+ dev_set_drvdata(firmware_cmd_dev, NULL);
- /* initialize the work queue */
- INIT_WORK(&msg21xx_wk, touch_driver_do_work);
+ ret = request_threaded_irq(client->irq, NULL,
+ msg21xx_ts_interrupt,
+ pdata->irq_gpio_flags | IRQF_ONESHOT,
+ "msg21xx", ts_data);
+ if (ret)
+ goto err_req_irq;
- ret = gpio_request(MS_TS_MSG21XX_GPIO_INT, "interrupt");
- if (ret < 0)
- {
- pr_err("*** Failed to request GPIO %d, error %d ***\n", MS_TS_MSG21XX_GPIO_INT, ret);
- goto err2;
- }
- gpio_direction_input(MS_TS_MSG21XX_GPIO_INT);
- gpio_set_value(MS_TS_MSG21XX_GPIO_INT, 1);
-
- irq_msg21xx = gpio_to_irq(MS_TS_MSG21XX_GPIO_INT);
-
- /* request an irq and register the isr */
- ret = request_irq(irq_msg21xx, touch_driver_isr, IRQF_TRIGGER_RISING, "msg21xx", NULL);
- if (ret != 0)
- {
- pr_err("*** Unable to claim irq %d; error %d ***\n", MS_TS_MSG21XX_GPIO_INT, ret);
- goto err3;
- }
-
- disable_irq(irq_msg21xx);
+ disable_irq(ts_data->client->irq);
#if defined(CONFIG_FB)
- msg21xx_fb_notif.notifier_call = fb_notifier_callback;
- ret = fb_register_client(&msg21xx_fb_notif);
-#elif defined (CONFIG_HAS_EARLYSUSPEND)
- mstar_ts_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
- mstar_ts_early_suspend.suspend = touch_driver_early_suspend;
- mstar_ts_early_suspend.resume = touch_driver_early_resume;
- register_early_suspend(&mstar_ts_early_suspend);
+ ts_data->fb_notif.notifier_call = fb_notifier_callback;
+ ret = fb_register_client(&ts_data->fb_notif);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ mstar_ts_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
+ mstar_ts_early_suspend.suspend = touch_driver_early_suspend;
+ mstar_ts_early_suspend.resume = touch_driver_early_resume;
+ register_early_suspend(&mstar_ts_early_suspend);
#endif
-#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
- tsps_assist_register_callback("msg21xx", &tsps_msg21xx_enable, &tsps_msg21xx_data);
+#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
+ tsps_assist_register_callback("msg21xx", &tsps_msg21xx_enable,
+ &tsps_msg21xx_data);
#endif
#ifdef FIRMWARE_AUTOUPDATE
- get_customer_firmware_version();
- _ReadBinConfig();
-
- if (main_sw_id == info_sw_id)
- {
- if (_CalMainCRC32() == bin_conf_crc32)
- {
- if ((main_sw_id >= SWID_START) && (main_sw_id < SWID_NULL))
- {
- update_bin_major= (MSG_FIRMWARE[main_sw_id-SWID_START][0x7f4f] << 8) + MSG_FIRMWARE[main_sw_id-SWID_START][0x7f4e];
- update_bin_minor= (MSG_FIRMWARE[main_sw_id-SWID_START][0x7f51] << 8) + MSG_FIRMWARE[main_sw_id-SWID_START][0x7f50];
-
- //check upgrading
- if ((update_bin_major == fw_version_major) && (update_bin_minor > fw_version_minor))
- {
- update_flag = 1;
- }
- }
- DBG("MAIN sw_id=%d,update_flag=%d,update_bin_major=%d,update_bin_minor=%d\n",main_sw_id,update_flag,update_bin_major,update_bin_minor);
- }
- else
- {
- if ((info_sw_id >= SWID_START) && (info_sw_id < SWID_NULL))
- {
- update_bin_major= (MSG_FIRMWARE[info_sw_id-SWID_START][0x7f4f] << 8) + MSG_FIRMWARE[info_sw_id-SWID_START][0x7f4e];
- update_bin_minor= (MSG_FIRMWARE[info_sw_id-SWID_START][0x7f51] << 8) + MSG_FIRMWARE[info_sw_id-SWID_START][0x7f50];
- update_flag = 1;
- }
- DBG("INFO1 sw_id=%d,update_flag=%d,update_bin_major=%d,update_bin_minor=%d\n",info_sw_id,update_flag,update_bin_major,update_bin_minor);
- }
- }
- else
- {
- if ((info_sw_id >= SWID_START) && (info_sw_id < SWID_NULL))
- {
- update_bin_major= (MSG_FIRMWARE[info_sw_id-SWID_START][0x7f4f] << 8) + MSG_FIRMWARE[info_sw_id-SWID_START][0x7f4e];
- update_bin_minor= (MSG_FIRMWARE[info_sw_id-SWID_START][0x7f51] << 8) + MSG_FIRMWARE[info_sw_id-SWID_START][0x7f50];
- update_flag = 1;
- }
- DBG("INFO2 sw_id=%d,update_flag=%d,update_bin_major=%d,update_bin_minor=%d\n",info_sw_id,update_flag,update_bin_major,update_bin_minor);
- }
-
- if (update_flag == 1)
- {
- DBG("MSG21XX_fw_auto_update begin....\n");
- //transfer data
- for (i = 0; i < 33; i++)
- {
- firmware_data_store(NULL, NULL, &(MSG_FIRMWARE[info_sw_id-SWID_START][i*1024]), 1024);
- }
-
- kthread_run(fwAutoUpdate, 0, "MSG21XX_fw_auto_update");
- DBG("*** mstar touch screen registered ***\n");
- return 0;
- }
-
- reset_hw();
+ get_customer_firmware_version();
+ _ReadBinConfig();
+
+ if (main_sw_id == info_sw_id) {
+ if (_CalMainCRC32() == bin_conf_crc32) {
+ if ((main_sw_id >= SWID_START) &&
+ (main_sw_id < SWID_NULL)) {
+ update_bin_major = (MSG_FIRMWARE
+ [main_sw_id - SWID_START][0x7f4f] << 8)
+ + MSG_FIRMWARE[main_sw_id - SWID_START][0x7f4e];
+ update_bin_minor = (MSG_FIRMWARE
+ [main_sw_id - SWID_START][0x7f51] << 8)
+ + MSG_FIRMWARE[main_sw_id - SWID_START][0x7f50];
+
+ /* check upgrading */
+ if ((update_bin_major == fw_version_major) &&
+ (update_bin_minor > fw_version_minor)) {
+ update_flag = 1;
+ }
+ }
+ } else {
+ if ((info_sw_id >= SWID_START) &&
+ (info_sw_id < SWID_NULL)) {
+ update_bin_major = (MSG_FIRMWARE
+ [info_sw_id - SWID_START][0x7f4f] << 8)
+ + MSG_FIRMWARE
+ [info_sw_id - SWID_START][0x7f4e];
+ update_bin_minor = (MSG_FIRMWARE
+ [info_sw_id - SWID_START][0x7f51] << 8)
+ + MSG_FIRMWARE
+ [info_sw_id - SWID_START][0x7f50];
+ update_flag = 1;
+ }
+ }
+ } else {
+ if ((info_sw_id >= SWID_START) && (info_sw_id < SWID_NULL)) {
+ update_bin_major = (MSG_FIRMWARE
+ [info_sw_id - SWID_START][0x7f4f] << 8)
+ + MSG_FIRMWARE
+ [info_sw_id - SWID_START][0x7f4e];
+ update_bin_minor = (MSG_FIRMWARE
+ [info_sw_id - SWID_START][0x7f51] << 8)
+ + MSG_FIRMWARE
+ [info_sw_id - SWID_START][0x7f50];
+ update_flag = 1;
+ }
+ }
+
+ if (update_flag == 1) {
+ DBG("MSG21XX_fw_auto_update begin....\n");
+ /* transfer data */
+ for (i = 0; i < 33; i++) {
+ firmware_data_store(NULL, NULL,
+ &(MSG_FIRMWARE[info_sw_id - SWID_START][i * 1024]),
+ 1024);
+ }
+
+ kthread_run(fwAutoUpdate, 0, "MSG21XX_fw_auto_update");
+ DBG("*** mstar touch screen registered ***\n");
+ return 0;
+ }
+
+ reset_hw();
#endif
- DBG("*** mstar touch screen registered ***\n");
- enable_irq(irq_msg21xx);
- return 0;
-
-err3:
- free_irq(irq_msg21xx, input_dev);
-
-err2:
- gpio_free(MS_TS_MSG21XX_GPIO_INT);
-
-err1:
- mutex_destroy(&msg21xx_mutex);
- input_unregister_device(input_dev);
- input_free_device(input_dev);
- input_dev = NULL;
-
-err0:
- gpio_free(MS_TS_MSG21XX_GPIO_RST);
-
- return ret;
+ DBG("*** mstar touch screen registered ***\n");
+ enable_irq(ts_data->client->irq);
+ return 0;
+
+err_req_irq:
+ free_irq(ts_data->client->irq, input_dev);
+
+err_input_reg_dev:
+err_input_allocate_dev:
+ mutex_destroy(&msg21xx_mutex);
+ mutex_destroy(&ts_data->ts_mutex);
+ input_unregister_device(input_dev);
+ input_free_device(input_dev);
+ input_dev = NULL;
+
+err_wrong_ic_type:
+ msg21xx_ts_gpio_configure(false);
+exit_gpio_config:
+exit_pinctrl_select:
+ if (ts_data->ts_pinctrl) {
+ if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) {
+ devm_pinctrl_put(ts_data->ts_pinctrl);
+ ts_data->ts_pinctrl = NULL;
+ } else {
+ ret = pinctrl_select_state(ts_data->ts_pinctrl,
+ ts_data->pinctrl_state_release);
+ if (ret < 0)
+ pr_err("Cannot get release pinctrl state\n");
+ }
+ }
+exit_pinctrl_init:
+ msg21xx_ts_power_off();
+exit_deinit_power:
+ msg21xx_ts_power_deinit();
+
+ return ret;
}
-/* remove function is triggered when the input device is removed from input sub-system */
+/* remove function is triggered when the input device is removed
+ *from input sub-system
+ */
static int touch_driver_remove(struct i2c_client *client)
{
- DBG("touch_driver_remove()\n");
-
- free_irq(irq_msg21xx, input_dev);
- gpio_free(MS_TS_MSG21XX_GPIO_INT);
- gpio_free(MS_TS_MSG21XX_GPIO_RST);
- input_unregister_device(input_dev);
- mutex_destroy(&msg21xx_mutex);
-
- return 0;
+ int retval = 0;
+
+ DBG("touch_driver_remove()\n");
+
+ free_irq(ts_data->client->irq, input_dev);
+ gpio_free(pdata->irq_gpio);
+ gpio_free(pdata->reset_gpio);
+
+ if (ts_data->ts_pinctrl) {
+ if (IS_ERR_OR_NULL(ts_data->pinctrl_state_release)) {
+ devm_pinctrl_put(ts_data->ts_pinctrl);
+ ts_data->ts_pinctrl = NULL;
+ } else {
+ retval = pinctrl_select_state(ts_data->ts_pinctrl,
+ ts_data->pinctrl_state_release);
+ if (retval < 0)
+ pr_err("Cannot get release pinctrl state\n");
+ }
+ }
+
+ input_unregister_device(input_dev);
+ mutex_destroy(&msg21xx_mutex);
+ mutex_destroy(&ts_data->ts_mutex);
+
+ return retval;
}
-/* The I2C device list is used for matching I2C device and I2C device driver. */
-static const struct i2c_device_id touch_device_id[] =
-{
- {"msg21xx", 0},
- {}, /* should not omitted */
+/* The I2C device list is used for matching I2C device
+ *and I2C device driver.
+ */
+static const struct i2c_device_id touch_device_id[] = {
+ {"msg21xx", 0},
+ {}, /* should not omitted */
+};
+
+static const struct of_device_id msg21xx_match_table[] = {
+ { .compatible = "mstar,msg21xx", },
+ { },
};
MODULE_DEVICE_TABLE(i2c, touch_device_id);
-static struct i2c_driver touch_device_driver =
-{
- .driver = {
- .name = "msg21xx",
- .owner = THIS_MODULE,
- },
- .probe = touch_driver_probe,
- .remove = touch_driver_remove,
- .id_table = touch_device_id,
+static struct i2c_driver touch_device_driver = {
+ .driver = {
+ .name = "ms-msg21xx",
+ .owner = THIS_MODULE,
+ .of_match_table = msg21xx_match_table,
+ },
+ .probe = msg21xx_ts_probe,
+ .remove = touch_driver_remove,
+ .id_table = touch_device_id,
};
static int __init touch_driver_init(void)
{
- int ret;
-
- /* register driver */
- ret = i2c_add_driver(&touch_device_driver);
- if (ret < 0)
- {
- DBG("add touch_device_driver i2c driver failed.\n");
- return -ENODEV;
- }
- DBG("add touch_device_driver i2c driver.\n");
-
- return ret;
+ int ret;
+
+ /* register driver */
+ ret = i2c_add_driver(&touch_device_driver);
+ if (ret < 0) {
+ DBG("add touch_device_driver i2c driver failed.\n");
+ return -ENODEV;
+ }
+ DBG("add touch_device_driver i2c driver.\n");
+
+ return ret;
}
static void __exit touch_driver_exit(void)
{
- DBG("remove touch_device_driver i2c driver.\n");
+ DBG("remove touch_device_driver i2c driver.\n");
- i2c_del_driver(&touch_device_driver);
+ i2c_del_driver(&touch_device_driver);
}
#ifdef TP_PRINT
#include <linux/proc_fs.h>
-static U16 InfoAddr = 0x0F, PoolAddr = 0x10, TransLen = 256;
-static U8 row, units, cnt;
+static unsigned short InfoAddr = 0x0F, PoolAddr = 0x10, TransLen = 256;
+static unsigned char row, units, cnt;
static int tp_print_proc_read(void)
{
- U16 i, j;
- U16 left, offset = 0;
- U8 dbbus_tx_data[3] = {0};
- U8 u8Data;
- S16 s16Data;
- S32 s32Data;
- char *buf = NULL;
-
- left = cnt*row*units;
- if ((bTpInSuspend == 0) && (InfoAddr != 0x0F) && (PoolAddr != 0x10) && (left > 0))
- {
- buf = kmalloc(left, GFP_KERNEL);
- if (buf != NULL)
- {
- printk("tpp: \n");
-
- while (left > 0)
- {
- dbbus_tx_data[0] = 0x53;
- dbbus_tx_data[1] = ((PoolAddr + offset) >> 8) & 0xFF;
- dbbus_tx_data[2] = (PoolAddr + offset) & 0xFF;
- mutex_lock(&msg21xx_mutex);
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 3);
- read_i2c_seq(SLAVE_I2C_ID_DWI2C, &buf[offset], left > TransLen ? TransLen : left);
- mutex_unlock(&msg21xx_mutex);
-
- if (left > TransLen)
- {
- left -= TransLen;
- offset += TransLen;
- }
- else
- {
- left = 0;
- }
- }
-
- for (i = 0; i < cnt; i++)
- {
- printk("tpp: ");
- for (j = 0; j < row; j++)
- {
- if (units == 1)
- {
- u8Data = buf[i*row*units + j*units];
- printk("%d\t", u8Data);
- }
- else if (units == 2)
- {
- s16Data = buf[i*row*units + j*units] + (buf[i*row*units + j*units + 1] << 8);
- printk("%d\t", s16Data);
- }
- else if (units == 4)
- {
- s32Data = buf[i*row*units + j*units] + (buf[i*row*units + j*units + 1] << 8) + (buf[i*row*units + j*units + 2] << 16) + (buf[i*row*units + j*units + 3] << 24);
- printk("%d\t", s32Data);
- }
- }
- printk("\n");
- }
-
- kfree(buf);
- }
- }
-
- return 0;
+ unsigned short i, j;
+ unsigned short left, offset = 0;
+ unsigned char dbbus_tx_data[3] = {0};
+ unsigned char u8Data;
+ signed short s16Data;
+ int s32Data;
+ char *buf = NULL;
+
+ left = cnt*row*units;
+ if ((ts_data->suspended == 0) &&
+ (InfoAddr != 0x0F) &&
+ (PoolAddr != 0x10) &&
+ (left > 0)) {
+ buf = kmalloc(left, GFP_KERNEL);
+ if (buf != NULL) {
+
+ while (left > 0) {
+ dbbus_tx_data[0] = 0x53;
+ dbbus_tx_data[1] = ((PoolAddr + offset) >> 8)
+ & 0xFF;
+ dbbus_tx_data[2] = (PoolAddr + offset) & 0xFF;
+ mutex_lock(&msg21xx_mutex);
+ write_i2c_seq(ts_data->client->addr,
+ &dbbus_tx_data[0], 3);
+ read_i2c_seq(ts_data->client->addr,
+ &buf[offset],
+ left > TransLen ? TransLen : left);
+ mutex_unlock(&msg21xx_mutex);
+
+ if (left > TransLen) {
+ left -= TransLen;
+ offset += TransLen;
+ } else {
+ left = 0;
+ }
+ }
+
+ for (i = 0; i < cnt; i++) {
+ for (j = 0; j < row; j++) {
+ if (units == 1) {
+ u8Data = buf[i * row * units +
+ j * units];
+ } else if (units == 2) {
+ s16Data = buf[i * row * units +
+ j * units] +
+ (buf[i * row * units +
+ j * units + 1] << 8);
+ } else if (units == 4) {
+ s32Data = buf[i * row * units +
+ j * units] +
+ (buf[i * row * units +
+ j * units + 1] << 8) +
+ (buf[i * row * units +
+ j * units + 2] << 16) +
+ (buf[i * row * units +
+ j * units + 3] << 24);
+ }
+ }
+ }
+
+ kfree(buf);
+ }
+ }
+
+ return 0;
}
static void tp_print_create_entry(void)
{
- U8 dbbus_tx_data[3] = {0};
- U8 dbbus_rx_data[8] = {0};
-
- dbbus_tx_data[0] = 0x53;
- dbbus_tx_data[1] = 0x00;
- dbbus_tx_data[2] = 0x58;
- mutex_lock(&msg21xx_mutex);
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 3);
- read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 4);
- mutex_unlock(&msg21xx_mutex);
- InfoAddr = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0];
- PoolAddr = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2];
- printk("InfoAddr=0x%X\n", InfoAddr);
- printk("PoolAddr=0x%X\n", PoolAddr);
-
- if ((InfoAddr != 0x0F) && (PoolAddr != 0x10))
- {
- msleep(10);
- dbbus_tx_data[0] = 0x53;
- dbbus_tx_data[1] = (InfoAddr >> 8) & 0xFF;
- dbbus_tx_data[2] = InfoAddr & 0xFF;
- mutex_lock(&msg21xx_mutex);
- write_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_tx_data[0], 3);
- read_i2c_seq(SLAVE_I2C_ID_DWI2C, &dbbus_rx_data[0], 8);
- mutex_unlock(&msg21xx_mutex);
-
- units = dbbus_rx_data[0];
- row = dbbus_rx_data[1];
- cnt = dbbus_rx_data[2];
- TransLen = (dbbus_rx_data[7]<<8) + dbbus_rx_data[6];
- printk("tpp: row=%d, units=%d\n", row, units);
- printk("tpp: cnt=%d, TransLen=%d\n", cnt, TransLen);
-
- // tpp
- if (device_create_file(firmware_cmd_dev, &dev_attr_tpp) < 0)
- {
- pr_err("Failed to create device file(%s)!\n", dev_attr_tpp.attr.name);
- }
- }
+ unsigned char dbbus_tx_data[3] = {0};
+ unsigned char dbbus_rx_data[8] = {0};
+
+ dbbus_tx_data[0] = 0x53;
+ dbbus_tx_data[1] = 0x00;
+ dbbus_tx_data[2] = 0x58;
+ mutex_lock(&msg21xx_mutex);
+ write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3);
+ read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 4);
+ mutex_unlock(&msg21xx_mutex);
+ InfoAddr = (dbbus_rx_data[1]<<8) + dbbus_rx_data[0];
+ PoolAddr = (dbbus_rx_data[3]<<8) + dbbus_rx_data[2];
+
+ if ((InfoAddr != 0x0F) && (PoolAddr != 0x10)) {
+ msleep(20);
+ dbbus_tx_data[0] = 0x53;
+ dbbus_tx_data[1] = (InfoAddr >> 8) & 0xFF;
+ dbbus_tx_data[2] = InfoAddr & 0xFF;
+ mutex_lock(&msg21xx_mutex);
+ write_i2c_seq(ts_data->client->addr, &dbbus_tx_data[0], 3);
+ read_i2c_seq(ts_data->client->addr, &dbbus_rx_data[0], 8);
+ mutex_unlock(&msg21xx_mutex);
+
+ units = dbbus_rx_data[0];
+ row = dbbus_rx_data[1];
+ cnt = dbbus_rx_data[2];
+ TransLen = (dbbus_rx_data[7]<<8) + dbbus_rx_data[6];
+
+ if (device_create_file(firmware_cmd_dev, &dev_attr_tpp) < 0) {
+ pr_err("Failed to create device file(%s)!\n",
+ dev_attr_tpp.attr.name);
+ }
+ }
}
#endif
module_exit(touch_driver_exit);
MODULE_AUTHOR("MStar Semiconductor, Inc.");
MODULE_LICENSE("GPL v2");
-