DivestOS/Patches/Linux_CVEs/CVE-2017-6421/0.patch

2399 lines
63 KiB
Diff

From be42c7ff1f0396484882451fd18f47144c8f1b6b Mon Sep 17 00:00:00 2001
From: Shantanu Jain <shjain@codeaurora.org>
Date: Thu, 16 Feb 2017 11:39:44 +0530
Subject: input: touchscreen: remove msg21xx mstar touch driver
Remove msg21xx mstar touch driver from the kernel code
as it has never been used in any of the recent platforms.
Change-Id: I0ac1f93d9736c402732b6c4a8d22b1bf3500e4c4
Signed-off-by: Vevek Venkatesan <vevekv@codeaurora.org>
Signed-off-by: Shantanu Jain <shjain@codeaurora.org>
---
.../bindings/input/touchscreen/msg21xx-ts.txt | 71 -
drivers/input/touchscreen/Kconfig | 11 -
drivers/input/touchscreen/Makefile | 1 -
drivers/input/touchscreen/msg21xx_ts.c | 2260 --------------------
4 files changed, 2343 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/msg21xx-ts.txt
delete mode 100644 drivers/input/touchscreen/msg21xx_ts.c
diff --git a/Documentation/devicetree/bindings/input/touchscreen/msg21xx-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/msg21xx-ts.txt
deleted file mode 100644
index 7315aef..0000000
--- a/Documentation/devicetree/bindings/input/touchscreen/msg21xx-ts.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-Mstar touch controller
-
-The mstar controller is connected to host processor
-via i2c. The controller generates interrupts when the
-user touches the panel. The host controller is expected
-to read the touch coordinates over i2c and pass the coordinates
-to the rest of the system.
-
-Required properties:
-
- - compatible : should be "mstar,msg21xx".
- - reg : i2c slave address of the device.
- - interrupt-parent : parent of interrupt.
- - interrupts : touch sample interrupt to indicate presense or release
- of fingers on the panel.
- - vdd-supply : Power supply needed to power up the device.
- - vcc_i2c-supply : Power source required to power up i2c bus.
- - mstar,irq-gpio : irq gpio which is to provide interrupts to host,
- same as "interrupts" node. It will also
- contain active low or active high information.
- - mstar,reset-gpio : reset gpio to control the reset of chip.
- - mstar,display-coords : display coords in pixels. It is a four
- tuple consisting of min x, min y, max x and
- max y values.
- - pinctrl-names : This should be defined if a target uses pinctrl framework.
- See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt.
- Specify the names of the configs that pinctrl can install in driver.
- Following are the pinctrl configs that can be installed:
- "pmx_ts_active" : Active configuration of pins, this should specify active
- config defined in pin groups of interrupt and reset gpio.
- "pmx_ts_suspend" : Disabled configuration of pins, this should specify sleep
- config defined in pin groups of interrupt and reset gpio.
- "pmx_ts_release" : Release configuration of pins, this should specify
- release config defined in pin groups of interrupt and reset gpio.
- - mstar,num-max-touches: It defines the maximum number of touch supported by the controller.
- - mstar,hard-reset-delay-ms : hard reset delay in ms
- - mstar,post-hard-reset-delay-ms : post hard reset delay in ms
-
-Optional properties:
-
- - mstar,button-map : button map of key codes. It is a three tuple consisting of key codes.
- - mstar,panel-coords : panel coords for the chip in pixels.
- It is a four tuple consisting of min x,
- min y, max x and max y values.
- - mstar,ic-type : It defines the ic-type of the controller. Values are as folows:
- 1 -> msg2133.
- 2 -> msg21xxA.
- 3 -> msg26xxM.
-
-Example:
- i2c@78b9000 { /* BLSP1 QUP5 */
- mstar@26 {
- compatible = "mstar,msg21xx";
- reg = <0x26>;
- interrupt-parent = <&msm_gpio>;
- interrupts = <13 0x2008>;
- mstar,irq-gpio = <&msm_gpio 13 0x00000001>;
- mstar,reset-gpio = <&msm_gpio 12 0x0>;
- vdd-supply = <&pm8916_l17>;
- vcc_i2c-supply = <&pm8916_l6>;
- mstar,display-coords = <0 0 480 854>;
- pinctrl-names = "pmx_ts_active","pmx_ts_suspend";
- pinctrl-0 = <&ts_int_active &ts_reset_active>;
- pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
- mstar,button-map = <172 139 158>;
- mstar,ic-type = <2>;
- mstar,num_max_touches = <2>;
- mstar,hard-reset-delay-ms = <100>;
- mstar,post-hard-reset-delay-ms = <100>;
- };
- };
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 49df5e0..9044bb5 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1128,17 +1128,6 @@ config TOUCHSCREEN_FT5X06_GESTURE
If unsure, say N.
-config TOUCHSCREEN_MSTAR21XX
- tristate "Mstar touchscreens"
- depends on I2C
- help
- Say Y here if you have a mstar touchscreen.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called msg21xx_ts.
-
config TOUCHSCREEN_ROHM_BU21023
tristate "ROHM BU21023/24 Dual touch support resistive touchscreens"
depends on I2C
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 06953a6..1b6844b 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -98,5 +98,4 @@ obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o
obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o
obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
-obj-$(CONFIG_TOUCHSCREEN_MSTAR21XX) += msg21xx_ts.o
obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/
diff --git a/drivers/input/touchscreen/msg21xx_ts.c b/drivers/input/touchscreen/msg21xx_ts.c
deleted file mode 100644
index fe8c6e164..0000000
--- a/drivers/input/touchscreen/msg21xx_ts.c
+++ /dev/null
@@ -1,2260 +0,0 @@
-/*
- * MStar MSG21XX touchscreen driver
- *
- * Copyright (c) 2006-2012 MStar Semiconductor, Inc.
- *
- * 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
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/input.h>
-#include <linux/input/mt.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
-#include <linux/sysfs.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/debugfs.h>
-#include <linux/regulator/consumer.h>
-
-#if defined(CONFIG_FB)
-#include <linux/notifier.h>
-#include <linux/fb.h>
-#endif
-#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-#include <linux/input/vir_ps.h>
-#endif
-
-/* Macro Definition */
-
-#define TOUCH_DRIVER_DEBUG 0
-#if (TOUCH_DRIVER_DEBUG == 1)
-#define DBG(fmt, arg...) pr_info(fmt, ##arg)
-#else
-#define DBG(fmt, arg...)
-#endif
-
-/* Constant Value & Variable Definition */
-
-#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 MAX_BUTTONS 4
-#define FT_COORDS_ARR_SIZE 4
-#define MSTAR_FW_NAME_MAX_LEN 50
-
-#define MSTAR_CHIPTOP_REGISTER_BANK 0x1E
-#define MSTAR_CHIPTOP_REGISTER_ICTYPE 0xCC
-#define MSTAR_INIT_SW_ID 0x7FF
-#define MSTAR_DEBUG_DIR_NAME "ts_debug"
-
-#define MSG_FW_FILE_MAJOR_VERSION(x) \
- (((x)->data[0x7f4f] << 8) + ((x)->data[0x7f4e]))
-
-#define MSG_FW_FILE_MINOR_VERSION(x) \
- (((x)->data[0x7f51] << 8) + ((x)->data[0x7f50]))
-
-/*
- * Note.
- * Please do not change the below setting.
- */
-#define TPD_WIDTH (2048)
-#define TPD_HEIGHT (2048)
-
-#ifdef FIRMWARE_AUTOUPDATE
-enum {
- SWID_START = 1,
- SWID_TRULY = SWID_START,
- SWID_NULL,
-};
-
-static unsigned char MSG_FIRMWARE[1][33*1024] = { {
- #include "msg21xx_truly_update_bin.h"
- }
-};
-#endif
-
-#define CONFIG_TP_HAVE_KEY
-#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 DEMO_MODE_PACKET_LENGTH (8)
-
-#define TP_PRINT
-
-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 unsigned short fw_file_major, fw_file_minor;
-static unsigned short main_sw_id = MSTAR_INIT_SW_ID;
-static unsigned short info_sw_id = MSTAR_INIT_SW_ID;
-static unsigned int bin_conf_crc32;
-
-struct msg21xx_ts_platform_data {
- const char *name;
- char fw_name[MSTAR_FW_NAME_MAX_LEN];
- u8 fw_version_major;
- u8 fw_version_minor;
- u32 irq_gpio;
- u32 irq_gpio_flags;
- u32 reset_gpio;
- u32 reset_gpio_flags;
- 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 num_max_touches;
- bool no_force_update;
- bool i2c_pull_up;
- bool ignore_id_check;
- int (*power_init)(bool);
- int (*power_on)(bool);
- int (*power_init)(bool);
- int (*power_on)(bool);
- u8 ic_type;
- u32 button_map[MAX_BUTTONS];
- u32 num_buttons;
- u32 hard_reset_delay_ms;
- u32 post_hard_reset_delay_ms;
- bool updating_fw;
-};
-
-/* Touch Data Type Definition */
-struct touchPoint_t {
- unsigned short x;
- unsigned short y;
-};
-
-struct touchInfo_t {
- struct touchPoint_t *point;
- unsigned char count;
- unsigned char keycode;
-};
-
-struct msg21xx_ts_data {
- struct i2c_client *client;
- struct input_dev *input_dev;
- struct msg21xx_ts_platform_data *pdata;
- struct regulator *vdd;
- struct regulator *vcc_i2c;
- bool suspended;
-#if defined(CONFIG_FB)
- struct notifier_block fb_notif;
-#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;
- struct touchInfo_t info;
-};
-
-#if defined(CONFIG_FB)
-static int fb_notifier_callback(struct notifier_block *self,
- unsigned long event, void *data);
-#endif
-
-#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-static unsigned char bEnableTpProximity;
-static unsigned char bFaceClosingTp;
-#endif
-
-#ifdef TP_PRINT
-static int tp_print_proc_read(struct msg21xx_ts_data *ts_data);
-static void tp_print_create_entry(struct msg21xx_ts_data *ts_data);
-#endif
-
-static void _ReadBinConfig(struct msg21xx_ts_data *ts_data);
-static unsigned int _CalMainCRC32(struct msg21xx_ts_data *ts_data);
-
-static struct mutex msg21xx_mutex;
-
-enum EMEM_TYPE_t {
- EMEM_ALL = 0,
- EMEM_MAIN,
- EMEM_INFO,
-};
-
-/* Function Definition */
-
-static unsigned int _CRC_doReflect(unsigned int ref, signed char ch)
-{
- unsigned int value = 0;
- unsigned int i = 0;
-
- for (i = 1; i < (ch + 1); i++) {
- if (ref & 1)
- value |= 1 << (ch - i);
- ref >>= 1;
- }
-
- return value;
-}
-
-static unsigned int _CRC_getValue(unsigned int text, unsigned int prevCRC)
-{
- unsigned int ulCRC = prevCRC;
-
- ulCRC = (ulCRC >> 8) ^ crc32_table[(ulCRC & 0xFF) ^ text];
-
- return ulCRC;
-}
-
-static void _CRC_initTable(void)
-{
- 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 void msg21xx_reset_hw(struct msg21xx_ts_platform_data *pdata)
-{
- gpio_direction_output(pdata->reset_gpio, 1);
- gpio_set_value_cansleep(pdata->reset_gpio, 0);
- /* Note that the RST must be in LOW 10ms at least */
- usleep(pdata->hard_reset_delay_ms * 1000);
- gpio_set_value_cansleep(pdata->reset_gpio, 1);
- /* Enable the interrupt service thread/routine for INT after 50ms */
- usleep(pdata->post_hard_reset_delay_ms * 1000);
-}
-
-static int read_i2c_seq(struct msg21xx_ts_data *ts_data, unsigned char addr,
- unsigned char *buf, unsigned short 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 (ts_data->client != NULL) {
- rc = i2c_transfer(ts_data->client->adapter, msgs, 1);
- if (rc < 0)
- dev_err(&ts_data->client->dev,
- "%s error %d\n", __func__, rc);
- } else {
- dev_err(&ts_data->client->dev, "ts_data->client is NULL\n");
- }
-
- return rc;
-}
-
-static int write_i2c_seq(struct msg21xx_ts_data *ts_data, unsigned char addr,
- unsigned char *buf, unsigned short size)
-{
- 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 (ts_data->client != NULL) {
- rc = i2c_transfer(ts_data->client->adapter, msgs, 1);
- if (rc < 0)
- dev_err(&ts_data->client->dev,
- "%s error %d\n", __func__, rc);
- } else {
- dev_err(&ts_data->client->dev, "ts_data->client is NULL\n");
- }
-
- return rc;
-}
-
-static unsigned short read_reg(struct msg21xx_ts_data *ts_data,
- unsigned char bank, unsigned char addr)
-{
- unsigned char tx_data[3] = {0x10, bank, addr};
- unsigned char rx_data[2] = {0};
-
- write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, tx_data, sizeof(tx_data));
- read_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, rx_data, sizeof(rx_data));
-
- return rx_data[1] << 8 | rx_data[0];
-}
-
-static void write_reg(struct msg21xx_ts_data *ts_data, unsigned char bank,
- unsigned char addr,
- unsigned short data)
-{
- unsigned char tx_data[5] = {0x10, bank, addr, data & 0xFF, data >> 8};
-
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 5);
- write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, tx_data, sizeof(tx_data));
-}
-
-static void write_reg_8bit(struct msg21xx_ts_data *ts_data, unsigned char bank,
- unsigned char addr,
- unsigned char data)
-{
- unsigned char tx_data[4] = {0x10, bank, addr, data};
-
- write_i2c_seq(SLAVE_I2C_ID_DBBUS, &tx_data[0], 4);
- write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, tx_data, sizeof(tx_data));
-}
-
-static void dbbusDWIICEnterSerialDebugMode(struct msg21xx_ts_data *ts_data)
-{
- unsigned char data[5];
-
- /* Enter the Serial Debug Mode */
- data[0] = 0x53;
- data[1] = 0x45;
- data[2] = 0x52;
- data[3] = 0x44;
- data[4] = 0x42;
-
- write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, data, sizeof(data));
-}
-
-static void dbbusDWIICStopMCU(struct msg21xx_ts_data *ts_data)
-{
- unsigned char data[1];
-
- /* Stop the MCU */
- data[0] = 0x37;
-
- write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, data, sizeof(data));
-}
-
-static void dbbusDWIICIICUseBus(struct msg21xx_ts_data *ts_data)
-{
- unsigned char data[1];
-
- /* IIC Use Bus */
- data[0] = 0x35;
-
- write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, data, sizeof(data));
-}
-
-static void dbbusDWIICIICReshape(struct msg21xx_ts_data *ts_data)
-{
- unsigned char data[1];
-
- /* IIC Re-shape */
- data[0] = 0x71;
-
- write_i2c_seq(ts_data, SLAVE_I2C_ID_DBBUS, data, sizeof(data));
-}
-
-static unsigned char msg21xx_get_ic_type(struct msg21xx_ts_data *ts_data)
-{
- unsigned char ic_type = 0;
- unsigned char bank;
- unsigned char addr;
-
- msg21xx_reset_hw(ts_data->pdata);
- dbbusDWIICEnterSerialDebugMode(ts_data);
- dbbusDWIICStopMCU(ts_data);
- dbbusDWIICIICUseBus(ts_data);
- dbbusDWIICIICReshape(ts_data);
- msleep(300);
-
- /* stop mcu */
- write_reg_8bit(ts_data, 0x0F, 0xE6, 0x01);
- /* disable watch dog */
- write_reg(ts_data, 0x3C, 0x60, 0xAA55);
- /* get ic type */
- bank = MSTAR_CHIPTOP_REGISTER_BANK;
- addr = MSTAR_CHIPTOP_REGISTER_ICTYPE;
- ic_type = (0xff)&(read_reg(ts_data, bank, addr));
-
- if (ic_type != ts_data->pdata->ic_type)
- ic_type = 0;
-
- msg21xx_reset_hw(ts_data->pdata);
-
- return ic_type;
-}
-
-static int msg21xx_read_firmware_id(struct msg21xx_ts_data *ts_data)
-{
- unsigned char command[3] = { 0x53, 0x00, 0x2A};
- unsigned char response[4] = { 0 };
-
- mutex_lock(&msg21xx_mutex);
- write_i2c_seq(ts_data, ts_data->client->addr, command, sizeof(command));
- read_i2c_seq(ts_data, ts_data->client->addr, response,
- sizeof(response));
- mutex_unlock(&msg21xx_mutex);
- ts_data->pdata->fw_version_major = (response[1]<<8) + response[0];
- ts_data->pdata->fw_version_minor = (response[3]<<8) + response[2];
-
- dev_info(&ts_data->client->dev, "major num = %d, minor num = %d\n",
- ts_data->pdata->fw_version_major,
- ts_data->pdata->fw_version_minor);
-
- return 0;
-}
-
-static int firmware_erase_c33(struct msg21xx_ts_data *ts_data,
- enum EMEM_TYPE_t emem_type)
-{
- /* stop mcu */
- write_reg(ts_data, 0x0F, 0xE6, 0x0001);
-
- /* disable watch dog */
- write_reg_8bit(ts_data, 0x3C, 0x60, 0x55);
- write_reg_8bit(ts_data, 0x3C, 0x61, 0xAA);
-
- /* set PROGRAM password */
- write_reg_8bit(ts_data, 0x16, 0x1A, 0xBA);
- write_reg_8bit(ts_data, 0x16, 0x1B, 0xAB);
-
- write_reg_8bit(ts_data, 0x16, 0x18, 0x80);
-
- if (emem_type == EMEM_ALL)
- write_reg_8bit(ts_data, 0x16, 0x08, 0x10);
-
- write_reg_8bit(ts_data, 0x16, 0x18, 0x40);
- msleep(20);
-
- /* clear pce */
- write_reg_8bit(0x16, 0x18, 0x80);
-
- /* erase trigger */
- if (emem_type == EMEM_MAIN)
- write_reg_8bit(ts_data, 0x16, 0x0E, 0x04); /* erase main */
- else
- write_reg_8bit(0x16, 0x0E, 0x08); /* erase all block */
-
- return 1;
-}
-
-static void _ReadBinConfig(void);
-static unsigned int _CalMainCRC32(void);
-
-static int check_fw_update(void)
-{
- int ret = 0;
-
- msg21xx_read_firmware_id();
- _ReadBinConfig();
- if (main_sw_id == info_sw_id) {
- if (_CalMainCRC32() == bin_conf_crc32) {
- /*check upgrading*/
- if ((update_bin_major == pdata->fw_version_major) &&
- (update_bin_minor > pdata->fw_version_minor)) {
- ret = 1;
- }
- }
- }
- return ret;
- write_reg_8bit(ts_data, 0x16, 0x0E, 0x08); /* erase all block */
-
- return 0;
-}
-
-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,
- bool isForce) {
- 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;
- bool fw_upgrade = false;
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- crc_main = 0xffffffff;
- crc_info = 0xffffffff;
-
- msg21xx_reset_hw(ts_data->pdata);
-
- msg21xx_read_firmware_id(ts_data);
- _ReadBinConfig(ts_data);
- if ((main_sw_id == info_sw_id) &&
- (_CalMainCRC32(ts_data) == bin_conf_crc32) &&
- (fw_file_major == ts_data->pdata->fw_version_major) &&
- (fw_file_minor > ts_data->pdata->fw_version_minor)) {
- fw_upgrade = true;
- }
-
- if (!fw_upgrade && !isForce) {
- dev_dbg(dev, "no need to update\n");
- msg21xx_reset_hw(ts_data->pdata);
- return size;
- }
- msg21xx_reset_hw(ts_data->pdata);
- msleep(300);
-
- dbbusDWIICEnterSerialDebugMode(ts_data);
- dbbusDWIICStopMCU(ts_data);
- dbbusDWIICIICUseBus(ts_data);
- dbbusDWIICIICReshape(ts_data);
- msleep(300);
-
- /* erase main */
- firmware_erase_c33(ts_data, EMEM_MAIN);
- msleep(1000);
-
- msg21xx_reset_hw(ts_data->pdata);
- dbbusDWIICEnterSerialDebugMode(ts_data);
- dbbusDWIICStopMCU(ts_data);
- dbbusDWIICIICUseBus(ts_data);
- dbbusDWIICIICReshape(ts_data);
- msleep(300);
- /*
- * Program
- */
- /* polling 0x3CE4 is 0x1C70 */
- if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
- do {
- reg_data = read_reg(ts_data, 0x3C, 0xE4);
- } while (reg_data != 0x1C70);
- }
-
- switch (emem_type) {
- case EMEM_ALL:
- write_reg(ts_data, 0x3C, 0xE4, 0xE38F); /* for all-blocks */
- break;
- case EMEM_MAIN:
- write_reg(ts_data, 0x3C, 0xE4, 0x7731); /* for main block */
- break;
- case EMEM_INFO:
- write_reg(ts_data, 0x3C, 0xE4, 0x7731); /* for info block */
-
- write_reg_8bit(ts_data, 0x0F, 0xE6, 0x01);
-
- write_reg_8bit(ts_data, 0x3C, 0xE4, 0xC5);
- write_reg_8bit(ts_data, 0x3C, 0xE5, 0x78);
-
- write_reg_8bit(ts_data, MSTAR_CHIPTOP_REGISTER_BANK,
- 0x04, 0x9F);
- write_reg_8bit(ts_data, MSTAR_CHIPTOP_REGISTER_BANK,
- 0x05, 0x82);
-
- write_reg_8bit(ts_data, 0x0F, 0xE6, 0x00);
- msleep(100);
- break;
- }
-
- /* polling 0x3CE4 is 0x2F43 */
- do {
- reg_data = read_reg(ts_data, 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) {
- fw_bin_data[i][1014] = 0x5A;
- fw_bin_data[i][1015] = 0xA5;
-
- for (j = 0; j < 1016; j++)
- crc_main = _CRC_getValue(fw_bin_data[i][j],
- crc_main);
- } else {
- for (j = 0; j < 1024; j++)
- crc_main = _CRC_getValue(fw_bin_data[i][j],
- crc_main);
- }
-
- for (j = 0; j < 8; j++)
- write_i2c_seq(ts_data, ts_data->client->addr,
- &fw_bin_data[i][j * 128], 128);
- msleep(100);
-
- /* polling 0x3CE4 is 0xD0BC */
- do {
- reg_data = read_reg(ts_data, 0x3C, 0xE4);
- } while (reg_data != 0xD0BC);
-
- write_reg(ts_data, 0x3C, 0xE4, 0x2F43);
- }
-
- if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
- /* write file done and check crc */
- write_reg(ts_data, 0x3C, 0xE4, 0x1380);
- }
- msleep(20);
-
- if ((emem_type == EMEM_ALL) || (emem_type == EMEM_MAIN)) {
- /* polling 0x3CE4 is 0x9432 */
- do {
- reg_data = read_reg(ts_data, 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(ts_data, 0x3C, 0x80);
- crc_main_tp = (crc_main_tp << 16) |
- read_reg(ts_data, 0x3C, 0x82);
-
- /* CRC Info from TP */
- crc_info_tp = read_reg(ts_data, 0x3C, 0xA0);
- crc_info_tp = (crc_info_tp << 16) |
- read_reg(ts_data, 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) {
- dev_err(dev, "update_C33 failed\n");
- msg21xx_reset_hw(ts_data->pdata);
- return 0;
- }
-
- dev_dbg(dev, "update_C33 OK\n");
- msg21xx_reset_hw(ts_data->pdata);
- return size;
-}
-
-static unsigned int _CalMainCRC32(struct msg21xx_ts_data *ts_data)
-{
- unsigned int ret = 0;
- unsigned short reg_data = 0;
-
- msg21xx_reset_hw(ts_data->pdata);
-
- dbbusDWIICEnterSerialDebugMode(ts_data);
- dbbusDWIICStopMCU(ts_data);
- dbbusDWIICIICUseBus(ts_data);
- dbbusDWIICIICReshape(ts_data);
- msleep(100);
-
- /* Stop MCU */
- write_reg(ts_data, 0x0F, 0xE6, 0x0001);
-
- /* Stop Watchdog */
- write_reg_8bit(ts_data, 0x3C, 0x60, 0x55);
- write_reg_8bit(ts_data, 0x3C, 0x61, 0xAA);
-
- /* cmd */
- write_reg(ts_data, 0x3C, 0xE4, 0xDF4C);
- write_reg(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x7d60);
- /* TP SW reset */
- write_reg(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x829F);
-
- /* MCU run */
- write_reg(ts_data, 0x0F, 0xE6, 0x0000);
-
- /* polling 0x3CE4 */
- do {
- reg_data = read_reg(ts_data, 0x3C, 0xE4);
- } while (reg_data != 0x9432);
-
- /* Cal CRC Main from TP */
- ret = read_reg(ts_data, 0x3C, 0x80);
- ret = (ret << 16) | read_reg(ts_data, 0x3C, 0x82);
-
- dev_dbg(&ts_data->client->dev,
- "[21xxA]:Current main crc32=0x%x\n", ret);
- return ret;
-}
-
-static void _ReadBinConfig(struct msg21xx_ts_data *ts_data)
-{
- unsigned char dbbus_tx_data[5] = {0};
- unsigned char dbbus_rx_data[4] = {0};
- unsigned short reg_data = 0;
-
- msg21xx_reset_hw(ts_data->pdata);
-
- dbbusDWIICEnterSerialDebugMode(ts_data);
- dbbusDWIICStopMCU(ts_data);
- dbbusDWIICIICUseBus(ts_data);
- dbbusDWIICIICReshape(ts_data);
- msleep(100);
-
- /* Stop MCU */
- write_reg(ts_data, 0x0F, 0xE6, 0x0001);
-
- /* Stop Watchdog */
- write_reg_8bit(ts_data, 0x3C, 0x60, 0x55);
- write_reg_8bit(ts_data, 0x3C, 0x61, 0xAA);
-
- /* cmd */
- write_reg(ts_data, 0x3C, 0xE4, 0xA4AB);
- write_reg(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x7d60);
-
- /* TP SW reset */
- write_reg(ts_data, MSTAR_CHIPTOP_REGISTER_BANK, 0x04, 0x829F);
-
- /* MCU run */
- write_reg(ts_data, 0x0F, 0xE6, 0x0000);
-
- /* polling 0x3CE4 */
- do {
- reg_data = read_reg(ts_data, 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, ts_data->client->addr, &dbbus_tx_data[0], 5);
- read_i2c_seq(ts_data, 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, ts_data->client->addr, &dbbus_tx_data[0], 5);
- read_i2c_seq(ts_data, ts_data->client->addr, &dbbus_rx_data[0], 4);
- bin_conf_crc32 = (dbbus_rx_data[0] << 24) |
- (dbbus_rx_data[1] << 16) |
- (dbbus_rx_data[2] << 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, ts_data->client->addr, &dbbus_tx_data[0], 5);
- read_i2c_seq(ts_data, 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);
- }
-
- dev_dbg(&ts_data->client->dev,
- "[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 ssize_t firmware_update_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- return snprintf(buf, 3, "%d\n", ts_data->pdata->updating_fw);
-}
-
-static ssize_t firmware_update_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t size)
-{
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- ts_data->pdata->updating_fw = true;
- disable_irq(ts_data->client->irq);
-
- size = firmware_update_c33(dev, attr, buf, size, EMEM_MAIN, false);
-
- enable_irq(ts_data->client->irq);
- ts_data->pdata->updating_fw = false;
-
- return size;
-}
-
-static DEVICE_ATTR(update, (S_IRUGO | S_IWUSR),
- firmware_update_show,
- firmware_update_store);
-
-static int prepare_fw_data(struct device *dev)
-{
- int count;
- int i;
- int ret;
- const struct firmware *fw = NULL;
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- ret = request_firmware(&fw, ts_data->pdata->fw_name, dev);
- if (ret < 0) {
- dev_err(dev, "Request firmware failed - %s (%d)\n",
- ts_data->pdata->fw_name, ret);
- return ret;
- }
-
- count = fw->size / 1024;
-
- for (i = 0; i < count; i++)
- memcpy(fw_bin_data[i], fw->data + (i * 1024), 1024);
-
- fw_file_major = MSG_FW_FILE_MAJOR_VERSION(fw);
- fw_file_minor = MSG_FW_FILE_MINOR_VERSION(fw);
- dev_dbg(dev, "New firmware: %d.%d",
- fw_file_major, fw_file_minor);
-
- return fw->size;
-}
-
-static ssize_t firmware_update_smart_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t size)
-{
- int ret;
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- ret = prepare_fw_data(dev);
- if (ret < 0) {
- dev_err(dev, "Request firmware failed -(%d)\n", ret);
- return ret;
- }
- ts_data->pdata->updating_fw = true;
- disable_irq(ts_data->client->irq);
-
- ret = firmware_update_c33(dev, attr, buf, size, EMEM_MAIN, false);
- if (ret == 0)
- dev_err(dev, "firmware_update_c33 ret = %d\n", ret);
-
- enable_irq(ts_data->client->irq);
- ts_data->pdata->updating_fw = false;
-
- return ret;
-}
-
-static ssize_t firmware_force_update_smart_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t size)
-{
- int ret;
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- ret = prepare_fw_data(dev);
- if (ret < 0) {
- dev_err(dev, "Request firmware failed -(%d)\n", ret);
- return ret;
- }
- ts_data->pdata->updating_fw = true;
- disable_irq(ts_data->client->irq);
-
- ret = firmware_update_c33(dev, attr, buf, size, EMEM_MAIN, true);
- if (ret == 0)
- dev_err(dev, "firmware_update_c33 et = %d\n", ret);
-
- enable_irq(ts_data->client->irq);
- ts_data->pdata->updating_fw = false;
-
- return ret;
-}
-
-static DEVICE_ATTR(update_fw, (S_IRUGO | S_IWUSR),
- firmware_update_show,
- firmware_update_smart_store);
-
-static DEVICE_ATTR(force_update_fw, (S_IRUGO | S_IWUSR),
- firmware_update_show,
- firmware_force_update_smart_store);
-
-static ssize_t firmware_version_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- msg21xx_read_firmware_id(ts_data);
- return snprintf(buf, sizeof(char) * 8, "%03d%03d\n",
- ts_data->pdata->fw_version_major,
- ts_data->pdata->fw_version_minor);
-}
-
-static DEVICE_ATTR(version, S_IRUGO,
- firmware_version_show,
- NULL);
-
-
-static ssize_t msg21xx_fw_name_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- return snprintf(buf, MSTAR_FW_NAME_MAX_LEN - 1,
- "%s\n", ts_data->pdata->fw_name);
-}
-
-static ssize_t msg21xx_fw_name_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- if (size > MSTAR_FW_NAME_MAX_LEN - 1)
- return -EINVAL;
-
- strlcpy(ts_data->pdata->fw_name, buf, size);
- if (ts_data->pdata->fw_name[size - 1] == '\n')
- ts_data->pdata->fw_name[size - 1] = 0;
-
- return size;
-}
-
-static DEVICE_ATTR(fw_name, (S_IRUGO | S_IWUSR),
- msg21xx_fw_name_show, msg21xx_fw_name_store);
-
-static ssize_t firmware_data_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t size)
-{
- int count = size / 1024;
- int i;
-
- for (i = 0; i < count; i++)
- memcpy(fw_bin_data[i], buf + (i * 1024), 1024);
-
- if (buf != NULL)
- dev_dbg(dev, "buf[0] = %c\n", buf[0]);
-
- return size;
-}
-
-static DEVICE_ATTR(data, S_IWUSR, NULL, firmware_data_store);
-
-static ssize_t tp_print_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- tp_print_proc_read(ts_data);
-
- return snprintf(buf, 3, "%d\n", ts_data->suspended);
-}
-
-static ssize_t tp_print_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t size)
-{
- return size;
-}
-
-static DEVICE_ATTR(tpp, (S_IRUGO | S_IWUSR),
- tp_print_show, tp_print_store);
-
-#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
-static void _msg_enable_proximity(void)
-{
- unsigned char tx_data[4] = {0};
-
- 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)
-{
- unsigned char tx_data[4] = {0};
-
- 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;
-}
-
-static void tsps_msg21xx_enable(int en)
-{
- if (en)
- _msg_enable_proximity();
- else
- _msg_disable_proximity();
-}
-
-static int tsps_msg21xx_data(void)
-{
- return bFaceClosingTp;
-}
-#endif
-
-static int msg21xx_pinctrl_init(struct msg21xx_ts_data *ts_data)
-{
- int retval;
-
- /* Get pinctrl if target uses pinctrl */
- ts_data->ts_pinctrl = devm_pinctrl_get(&(ts_data->client->dev));
- if (IS_ERR_OR_NULL(ts_data->ts_pinctrl)) {
- retval = PTR_ERR(ts_data->ts_pinctrl);
- dev_dbg(&ts_data->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(&ts_data->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(&ts_data->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(&ts_data->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)
-{
- int checksum = 0, i;
-
- for (i = 0; i < length; i++)
- checksum += msg[i];
-
- return (unsigned char)((-checksum) & 0xFF);
-}
-
-static int parse_info(struct msg21xx_ts_data *ts_data)
-{
- 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, ts_data->client->addr, &data[0],
- DEMO_MODE_PACKET_LENGTH);
- mutex_unlock(&msg21xx_mutex);
- checksum = calculate_checksum(&data[0], (DEMO_MODE_PACKET_LENGTH-1));
- dev_dbg(&ts_data->client->dev, "check sum: [%x] == [%x]?\n",
- data[DEMO_MODE_PACKET_LENGTH-1], checksum);
-
- if (data[DEMO_MODE_PACKET_LENGTH-1] != checksum) {
- dev_err(&ts_data->client->dev, "WRONG CHECKSUM\n");
- return -EINVAL;
- }
-
- if (data[0] != 0x52) {
- dev_err(&ts_data->client->dev, "WRONG HEADER\n");
- return -EINVAL;
- }
-
- ts_data->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)) {
- ts_data->info.keycode = 0xFF;
- } else if ((data[5] == 1) || (data[5] == 2) ||
- (data[5] == 4) || (data[5] == 8)) {
- ts_data->info.keycode = data[5] >> 1;
-
- dev_dbg(&ts_data->client->dev,
- "ts_data->info.keycode index %d\n",
- ts_data->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 {
- dev_err(&ts_data->client->dev, "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)) {
- ts_data->info.point[0].x =
- x * ts_data->pdata->x_max / TPD_WIDTH;
- ts_data->info.point[0].y =
- y * ts_data->pdata->y_max / TPD_HEIGHT;
- ts_data->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);
- ts_data->info.point[0].x =
- x * ts_data->pdata->x_max / TPD_WIDTH;
- ts_data->info.point[0].y =
- y * ts_data->pdata->y_max / TPD_HEIGHT;
- ts_data->info.point[1].x =
- x2 * ts_data->pdata->x_max / TPD_WIDTH;
- ts_data->info.point[1].y =
- y2 * ts_data->pdata->y_max / TPD_HEIGHT;
- ts_data->info.count = ts_data->pdata->num_max_touches;
- }
- }
-
- return 0;
-}
-
-static void touch_driver_touch_released(struct msg21xx_ts_data *ts_data)
-{
- int i;
-
- for (i = 0; i < ts_data->pdata->num_max_touches; i++) {
- input_mt_slot(ts_data->input_dev, i);
- input_mt_report_slot_state(ts_data->input_dev,
- MT_TOOL_FINGER, 0);
- }
-
- input_report_key(ts_data->input_dev, BTN_TOUCH, 0);
- input_report_key(ts_data->input_dev, BTN_TOOL_FINGER, 0);
- input_sync(ts_data->input_dev);
-}
-
-/* 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)
-{
- int i = 0;
- static int last_keycode = 0xFF;
- static int last_count;
- struct msg21xx_ts_data *ts_data = dev_id;
-
- ts_data->info.count = 0;
- if (parse_info(ts_data) == 0) {
- if (ts_data->info.keycode != 0xFF) { /* key touch pressed */
- if (ts_data->info.keycode <
- ts_data->pdata->num_buttons) {
- if (ts_data->info.keycode != last_keycode) {
- dev_dbg(&ts_data->client->dev,
- "key touch pressed");
-
- input_report_key(ts_data->input_dev,
- BTN_TOUCH, 1);
- input_report_key(ts_data->input_dev,
- ts_data->pdata->button_map[
- ts_data->info.keycode], 1);
-
- last_keycode = ts_data->info.keycode;
- } else {
- /* pass duplicate key-pressing */
- dev_dbg(&ts_data->client->dev,
- "REPEATED KEY\n");
- }
- } else {
- dev_dbg(&ts_data->client->dev, "WRONG KEY\n");
- }
- } else { /* key touch released */
- if (last_keycode != 0xFF) {
- dev_dbg(&ts_data->client->dev, "key touch released");
-
- input_report_key(ts_data->input_dev,
- BTN_TOUCH, 0);
- input_report_key(ts_data->input_dev,
- ts_data->pdata->button_map[last_keycode],
- 0);
-
- last_keycode = 0xFF;
- }
- }
-
- if (ts_data->info.count > 0) { /* point touch pressed */
- for (i = 0; i < ts_data->info.count; i++) {
- input_mt_slot(ts_data->input_dev, i);
- input_mt_report_slot_state(ts_data->input_dev,
- MT_TOOL_FINGER, 1);
- input_report_abs(ts_data->input_dev,
- ABS_MT_TOUCH_MAJOR, 1);
- input_report_abs(ts_data->input_dev,
- ABS_MT_POSITION_X,
- ts_data->info.point[i].x);
- input_report_abs(ts_data->input_dev,
- ABS_MT_POSITION_Y,
- ts_data->info.point[i].y);
- }
- }
-
- if (last_count > info.count) {
- for (i = info.count; i < MAX_TOUCH_NUM; i++) {
- input_mt_slot(input_dev, i);
- input_mt_report_slot_state(input_dev,
- }
-
- if (last_count > ts_data->info.count) {
- for (i = ts_data->info.count;
- i < ts_data->pdata->num_max_touches;
- i++) {
- input_mt_slot(ts_data->input_dev, i);
- input_mt_report_slot_state(ts_data->input_dev,
- MT_TOOL_FINGER, 0);
- }
- }
- last_count = ts_data->info.count;
-
- input_report_key(ts_data->input_dev, BTN_TOUCH,
- ts_data->info.count > 0);
- input_report_key(ts_data->input_dev, BTN_TOOL_FINGER,
- ts_data->info.count > 0);
-
- input_sync(ts_data->input_dev);
- }
-
- return IRQ_HANDLED;
-}
-
-static int msg21xx_ts_power_init(struct msg21xx_ts_data *ts_data, bool init)
-{
- int rc;
-
- if (init) {
- ts_data->vdd = regulator_get(&ts_data->client->dev,
- "vdd");
- if (IS_ERR(ts_data->vdd)) {
- rc = PTR_ERR(ts_data->vdd);
- dev_err(&ts_data->client->dev,
- "Regulator get failed vdd rc=%d\n", rc);
- return rc;
- }
-
- if (regulator_count_voltages(ts_data->vdd) > 0) {
- rc = regulator_set_voltage(ts_data->vdd,
- MSTAR_VTG_MIN_UV,
- MSTAR_VTG_MAX_UV);
- if (rc) {
- dev_err(&ts_data->client->dev,
- "Regulator set_vtg failed vdd rc=%d\n",
- rc);
- goto reg_vdd_put;
- }
- }
-
- ts_data->vcc_i2c = regulator_get(&ts_data->client->dev,
- "vcc_i2c");
- if (IS_ERR(ts_data->vcc_i2c)) {
- rc = PTR_ERR(ts_data->vcc_i2c);
- dev_err(&ts_data->client->dev,
- "Regulator get failed vcc_i2c rc=%d\n", rc);
- goto reg_vdd_set_vtg;
- }
-
- if (regulator_count_voltages(ts_data->vcc_i2c) > 0) {
- rc = regulator_set_voltage(ts_data->vcc_i2c,
- MSTAR_I2C_VTG_MIN_UV,
- MSTAR_I2C_VTG_MAX_UV);
- if (rc) {
- dev_err(&ts_data->client->dev,
- "Regulator set_vtg failed vcc_i2c rc=%d\n", rc);
- goto reg_vcc_i2c_put;
- }
- }
- } else {
- if (regulator_count_voltages(ts_data->vdd) > 0)
- regulator_set_voltage(ts_data->vdd, 0,
- MSTAR_VTG_MAX_UV);
-
- regulator_put(ts_data->vdd);
-
- if (regulator_count_voltages(ts_data->vcc_i2c) > 0)
- regulator_set_voltage(ts_data->vcc_i2c, 0,
- MSTAR_I2C_VTG_MAX_UV);
-
- regulator_put(ts_data->vcc_i2c);
- }
-
- return 0;
-
-reg_vcc_i2c_put:
- regulator_put(ts_data->vcc_i2c);
-reg_vdd_set_vtg:
- if (regulator_count_voltages(ts_data->vdd) > 0)
- regulator_set_voltage(ts_data->vdd, 0, MSTAR_VTG_MAX_UV);
-reg_vdd_put:
- regulator_put(ts_data->vdd);
- return rc;
-}
-
-static int msg21xx_ts_power_on(struct msg21xx_ts_data *ts_data, bool on)
-{
- int rc;
-
- if (!on)
- goto power_off;
-
- rc = regulator_enable(ts_data->vdd);
- if (rc) {
- dev_err(&ts_data->client->dev,
- "Regulator vdd enable failed rc=%d\n", rc);
- return rc;
- }
-
- rc = regulator_enable(ts_data->vcc_i2c);
- if (rc) {
- dev_err(&ts_data->client->dev,
- "Regulator vcc_i2c enable failed rc=%d\n", rc);
- regulator_disable(ts_data->vdd);
- }
-
- return rc;
-
- DBG("*** %s ***\n", __func__);
- rc = regulator_disable(vdd);
-power_off:
- rc = regulator_disable(ts_data->vdd);
- if (rc) {
- dev_err(&ts_data->client->dev,
- "Regulator vdd disable failed rc=%d\n", rc);
- return rc;
- }
-
- rc = regulator_disable(ts_data->vcc_i2c);
- if (rc) {
- dev_err(&ts_data->client->dev,
- "Regulator vcc_i2c disable failed rc=%d\n", rc);
- rc = regulator_enable(ts_data->vdd);
- }
-
- return rc;
-}
-
-static int msg21xx_ts_gpio_configure(struct msg21xx_ts_data *ts_data, bool on)
-{
- int ret = 0;
-
- if (!on)
- goto pwr_deinit;
-
- if (gpio_is_valid(ts_data->pdata->irq_gpio)) {
- ret = gpio_request(ts_data->pdata->irq_gpio,
- "msg21xx_irq_gpio");
- if (ret) {
- dev_err(&ts_data->client->dev,
- "Failed to request GPIO[%d], %d\n",
- ts_data->pdata->irq_gpio, ret);
- goto err_irq_gpio_req;
- }
- ret = gpio_direction_input(ts_data->pdata->irq_gpio);
- if (ret) {
- dev_err(&ts_data->client->dev,
- "Failed to set direction for gpio[%d], %d\n",
- ts_data->pdata->irq_gpio, ret);
- goto err_irq_gpio_dir;
- }
- gpio_set_value_cansleep(ts_data->pdata->irq_gpio, 1);
- } else {
- dev_err(&ts_data->client->dev, "irq gpio not provided\n");
- goto err_irq_gpio_req;
- }
-
- if (gpio_is_valid(ts_data->pdata->reset_gpio)) {
- ret = gpio_request(ts_data->pdata->reset_gpio,
- "msg21xx_reset_gpio");
- if (ret) {
- dev_err(&ts_data->client->dev,
- "Failed to request GPIO[%d], %d\n",
- ts_data->pdata->reset_gpio, ret);
- 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;
- /* power on TP */
- ret = gpio_direction_output(
- ts_data->pdata->reset_gpio, 1);
- if (ret) {
- dev_err(&ts_data->client->dev,
- "Failed to set direction for GPIO[%d], %d\n",
- ts_data->pdata->reset_gpio, ret);
- goto err_reset_gpio_dir;
- }
- msleep(100);
- gpio_set_value_cansleep(ts_data->pdata->reset_gpio, 0);
- msleep(20);
- gpio_set_value_cansleep(ts_data->pdata->reset_gpio, 1);
- msleep(200);
- } else {
- dev_err(&ts_data->client->dev, "reset gpio not provided\n");
- goto err_reset_gpio_req;
- }
-
- return 0;
-
-err_reset_gpio_dir:
- if (gpio_is_valid(ts_data->pdata->reset_gpio))
- gpio_free(ts_data->pdata->irq_gpio);
-err_reset_gpio_req:
-err_irq_gpio_dir:
- if (gpio_is_valid(ts_data->pdata->irq_gpio))
- gpio_free(ts_data->pdata->irq_gpio);
-err_irq_gpio_req:
- return ret;
-
-pwr_deinit:
- if (gpio_is_valid(ts_data->pdata->irq_gpio))
- gpio_free(ts_data->pdata->irq_gpio);
- if (gpio_is_valid(ts_data->pdata->reset_gpio)) {
- gpio_set_value_cansleep(ts_data->pdata->reset_gpio, 0);
- ret = gpio_direction_input(ts_data->pdata->reset_gpio);
- if (ret)
- dev_err(&ts_data->client->dev,
- "Unable to set direction for gpio [%d]\n",
- ts_data->pdata->reset_gpio);
- gpio_free(ts_data->pdata->reset_gpio);
- }
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int msg21xx_ts_resume(struct device *dev)
-{
- int retval;
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- if (!ts_data->suspended) {
- dev_info(dev, "msg21xx_ts already in resume\n");
- return 0;
- }
-
- mutex_lock(&ts_data->ts_mutex);
-
- retval = msg21xx_ts_power_on(ts_data, true);
- if (retval) {
- dev_err(dev, "msg21xx_ts power on 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_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(ts_data, 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);
- ts_data->suspended = false;
-
- mutex_unlock(&ts_data->ts_mutex);
-
- return 0;
-}
-
-static int msg21xx_ts_suspend(struct device *dev)
-{
- int retval;
- struct msg21xx_ts_data *ts_data = dev_get_drvdata(dev);
-
- if (ts_data->pdata->updating_fw) {
- dev_info(dev, "Firmware loading in progress\n");
- return 0;
- }
-
- if (ts_data->suspended) {
- dev_info(dev, "msg21xx_ts already in suspend\n");
- return 0;
- }
-
-#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
- if (bEnableTpProximity) {
- dev_dbg(dev, "suspend bEnableTpProximity=%d\n",
- bEnableTpProximity);
- return 0;
- }
-#endif
-
- mutex_lock(&ts_data->ts_mutex);
-
- disable_irq(ts_data->client->irq);
-
- touch_driver_touch_released(ts_data);
-
- if (ts_data->ts_pinctrl) {
- retval = pinctrl_select_state(ts_data->ts_pinctrl,
- ts_data->pinctrl_state_suspend);
- if (retval < 0) {
- dev_err(dev, "Cannot get idle pinctrl state %d\n",
- retval);
- mutex_unlock(&ts_data->ts_mutex);
- return retval;
- }
- }
-
- retval = msg21xx_ts_gpio_configure(ts_data, false);
- if (retval) {
- dev_err(dev, "Failed to put gpios in idle state %d",
- retval);
- mutex_unlock(&ts_data->ts_mutex);
- return retval;
- }
-
- retval = msg21xx_ts_power_on(ts_data, false);
- if (retval) {
- dev_err(dev, "msg21xx_ts power off failed");
- mutex_unlock(&ts_data->ts_mutex);
- return retval;
- }
-
- ts_data->suspended = true;
-
- 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
-
-static int msg21xx_debug_suspend_set(void *_data, u64 val)
-{
- struct msg21xx_ts_data *data = _data;
-
- mutex_lock(&data->input_dev->mutex);
-
- if (val)
- msg21xx_ts_suspend(&data->client->dev);
- else
- msg21xx_ts_resume(&data->client->dev);
-
- mutex_unlock(&data->input_dev->mutex);
-
- return 0;
-}
-
-static int msg21xx_debug_suspend_get(void *_data, u64 *val)
-{
- struct msg21xx_ts_data *data = _data;
-
- mutex_lock(&data->input_dev->mutex);
- *val = data->suspended;
- mutex_unlock(&data->input_dev->mutex);
-
- return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, msg21xx_debug_suspend_get,
- msg21xx_debug_suspend_set, "%lld\n");
-
-
-#if defined(CONFIG_FB)
-static int fb_notifier_callback(struct notifier_block *self,
- unsigned long event, void *data)
-{
- struct fb_event *evdata = data;
- int *blank;
- struct msg21xx_ts_data *ts_data =
- container_of(self, struct msg21xx_ts_data, fb_notif);
-
- if (evdata && evdata->data && event == FB_EVENT_BLANK) {
- blank = evdata->data;
- if (*blank == FB_BLANK_UNBLANK)
- msg21xx_ts_resume(&ts_data->client->dev);
- else if (*blank == FB_BLANK_POWERDOWN)
- msg21xx_ts_suspend(&ts_data->client->dev);
- }
-
- return 0;
-}
-#endif
-
-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;
-
- rc = of_property_read_u32(np, "mstar,hard-reset-delay-ms",
- &temp_val);
- if (!rc)
- pdata->hard_reset_delay_ms = temp_val;
- else
- return rc;
-
- rc = of_property_read_u32(np, "mstar,post-hard-reset-delay-ms",
- &temp_val);
- if (!rc)
- pdata->post_hard_reset_delay_ms = temp_val;
- else
- 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;
-
- rc = of_property_read_u32(np, "mstar,ic-type", &temp_val);
- if (rc && (rc != -EINVAL))
- return rc;
-
- pdata->ic_type = temp_val;
-
- rc = of_property_read_u32(np, "mstar,num-max-touches", &temp_val);
- if (!rc)
- pdata->num_max_touches = temp_val;
- else
- return rc;
-
- prop = of_find_property(np, "mstar,button-map", NULL);
- if (prop) {
- pdata->num_buttons = prop->length / sizeof(temp_val);
- if (pdata->num_buttons > MAX_BUTTONS)
- return -EINVAL;
-
- rc = of_property_read_u32_array(np,
- "mstar,button-map", pdata->button_map,
- pdata->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) {
-
- int ret = 0, i;
- struct dentry *temp, *dir;
- struct input_dev *input_dev;
- struct msg21xx_ts_data *ts_data;
- struct msg21xx_ts_platform_data *pdata;
-
- 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;
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- dev_err(&client->dev, "I2C not supported\n");
- return -ENODEV;
- }
-
- ts_data = devm_kzalloc(&client->dev,
- sizeof(struct msg21xx_ts_data), GFP_KERNEL);
- if (!ts_data)
- return -ENOMEM;
-
- ts_data->client = client;
- ts_data->info.point = devm_kzalloc(&client->dev,
- sizeof(struct touchPoint_t) * pdata->num_max_touches,
- GFP_KERNEL);
- if (!ts_data->info.point) {
- dev_err(&client->dev, "Not enough memory\n");
- return -ENOMEM;
- }
-
- /* allocate an input device */
- input_dev = input_allocate_device();
- if (!input_dev) {
- ret = -ENOMEM;
- dev_err(&client->dev, "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;
-
- 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);
-
- ret = msg21xx_ts_power_init(ts_data, true);
- if (ret) {
- dev_err(&client->dev, "Mstar power init failed\n");
- return ret;
- }
-
- ret = msg21xx_ts_power_on(ts_data, true);
- if (ret) {
- dev_err(&client->dev, "Mstar power on failed\n");
- goto exit_deinit_power;
- }
-
- ret = msg21xx_pinctrl_init(ts_data);
- if (!ret && ts_data->ts_pinctrl) {
- /*
- * Pinctrl handle is optional. If pinctrl handle is found
- * let pins to be configured in active state. If not
- * found continue further without error.
- */
- ret = pinctrl_select_state(ts_data->ts_pinctrl,
- ts_data->pinctrl_state_active);
- if (ret < 0)
- dev_err(&client->dev,
- "Failed to select %s pinatate %d\n",
- PINCTRL_STATE_ACTIVE, ret);
- }
-
- ret = msg21xx_ts_gpio_configure(ts_data, true);
- if (ret) {
- dev_err(&client->dev, "Failed to configure gpio %d\n", ret);
- goto exit_gpio_config;
- }
-
- if (msg21xx_get_ic_type(ts_data) == 0) {
- dev_err(&client->dev, "The current IC is not Mstar\n");
- ret = -1;
- goto err_wrong_ic_type;
- }
-
- mutex_init(&msg21xx_mutex);
- mutex_init(&ts_data->ts_mutex);
-
- /* 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);
-
- for (i = 0; i < pdata->num_buttons; i++)
- input_set_capability(input_dev, EV_KEY, pdata->button_map[i]);
-
- input_set_drvdata(input_dev, ts_data);
- i2c_set_clientdata(client, ts_data);
-
-#ifdef CONFIG_TP_HAVE_KEY
- {
- 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_TOUCH_MAJOR, 0, 2, 0, 0);
- input_set_abs_params(input_dev, ABS_MT_POSITION_X,
- 0, pdata->x_max, 0, 0);
- input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
- 0, pdata->y_max, 0, 0);
- ret = input_mt_init_slots(input_dev, pdata->num_max_touches, 0);
- if (ret) {
- dev_err(&client->dev,
- "Error %d initialising slots\n", ret);
- goto err_free_mem;
- }
-
- /* register the input device to input sub-system */
- ret = input_register_device(input_dev);
- if (ret < 0) {
- dev_err(&client->dev,
- "Unable to register ms-touchscreen input device\n");
- goto err_input_reg_dev;
- }
-
- /* version */
- if (device_create_file(&client->dev, &dev_attr_version) < 0) {
- dev_err(&client->dev,
- "Failed to create device file(%s)!\n",
- dev_attr_version.attr.name);
- goto err_create_fw_ver_file;
- }
- /* update */
- if (device_create_file(&client->dev, &dev_attr_update) < 0) {
- dev_err(&client->dev,
- "Failed to create device file(%s)!\n",
- dev_attr_update.attr.name);
- goto err_create_fw_update_file;
- }
- /* data */
- if (device_create_file(&client->dev, &dev_attr_data) < 0) {
- dev_err(&client->dev,
- "Failed to create device file(%s)!\n",
- dev_attr_data.attr.name);
- goto err_create_fw_data_file;
- }
- /* fw name */
- if (device_create_file(&client->dev, &dev_attr_fw_name) < 0) {
- dev_err(&client->dev,
- "Failed to create device file(%s)!\n",
- dev_attr_fw_name.attr.name);
- goto err_create_fw_name_file;
- }
- /* smart fw update */
- if (device_create_file(&client->dev, &dev_attr_update_fw) < 0) {
- dev_err(&client->dev,
- "Failed to create device file(%s)!\n",
- dev_attr_update_fw.attr.name);
- goto err_create_update_fw_file;
- }
- /* smart fw force update */
- if (device_create_file(&client->dev,
- &dev_attr_force_update_fw) < 0) {
- dev_err(&client->dev,
- "Failed to create device file(%s)!\n",
- dev_attr_force_update_fw.attr.name);
- goto err_create_force_update_fw_file;
- }
- dir = debugfs_create_dir(MSTAR_DEBUG_DIR_NAME, NULL);
- temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, dir,
- ts_data, &debug_suspend_fops);
- if (temp == NULL || IS_ERR(temp)) {
- dev_err(&client->dev,
- "debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
- goto free_debug_dir;
- }
-
-#ifdef TP_PRINT
- tp_print_create_entry(ts_data);
-#endif
-
- 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;
-
- disable_irq(client->irq);
-
-#if defined(CONFIG_FB)
- ts_data->fb_notif.notifier_call = fb_notifier_callback;
- ret = fb_register_client(&ts_data->fb_notif);
-#endif
-
-#ifdef CONFIG_TOUCHSCREEN_PROXIMITY_SENSOR
- tsps_assist_register_callback("msg21xx", &tsps_msg21xx_enable,
- &tsps_msg21xx_data);
-#endif
-
- dev_dbg(&client->dev, "mstar touch screen registered\n");
- enable_irq(client->irq);
- return 0;
-
-err_req_irq:
- free_irq(client->irq, ts_data);
- device_remove_file(&client->dev, &dev_attr_data);
-free_debug_dir:
- debugfs_remove_recursive(dir);
-err_create_fw_data_file:
- device_remove_file(&client->dev, &dev_attr_update);
-err_create_fw_update_file:
- device_remove_file(&client->dev, &dev_attr_version);
-err_create_fw_name_file:
- device_remove_file(&client->dev, &dev_attr_fw_name);
-err_create_update_fw_file:
- device_remove_file(&client->dev, &dev_attr_update_fw);
-err_create_force_update_fw_file:
- device_remove_file(&client->dev, &dev_attr_force_update_fw);
-err_create_fw_ver_file:
- input_unregister_device(input_dev);
-
-err_input_reg_dev:
- input_free_device(input_dev);
- input_dev = NULL;
-err_input_allocate_dev:
- mutex_destroy(&msg21xx_mutex);
- mutex_destroy(&ts_data->ts_mutex);
-
-err_wrong_ic_type:
- msg21xx_ts_gpio_configure(ts_data, false);
-exit_gpio_config:
- 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)
- dev_err(&ts_data->client->dev,
- "Cannot get release pinctrl state\n");
- }
- }
- msg21xx_ts_power_on(ts_data, false);
-exit_deinit_power:
- msg21xx_ts_power_init(ts_data, false);
-err_free_mem:
- input_free_device(input_dev);
-
- return ret;
-}
-
-/* remove function is triggered when the input device is removed
- *from input sub-system
- */
-static int touch_driver_remove(struct i2c_client *client)
-{
- int retval = 0;
- struct msg21xx_ts_data *ts_data = i2c_get_clientdata(client);
-
- free_irq(ts_data->client->irq, ts_data);
- gpio_free(ts_data->pdata->irq_gpio);
- gpio_free(ts_data->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)
- dev_err(&ts_data->client->dev,
- "Cannot get release pinctrl state\n");
- }
- }
-
- input_unregister_device(ts_data->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 */
-};
-
-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 = "ms-msg21xx",
- .owner = THIS_MODULE,
- .of_match_table = msg21xx_match_table,
- },
- .probe = msg21xx_ts_probe,
- .remove = touch_driver_remove,
- .id_table = touch_device_id,
-};
-
-module_i2c_driver(touch_device_driver);
-
-#ifdef TP_PRINT
-#include <linux/proc_fs.h>
-
-static unsigned short InfoAddr = 0x0F, PoolAddr = 0x10, TransLen = 256;
-static unsigned char row, units, cnt;
-
-static int tp_print_proc_read(struct msg21xx_ts_data *ts_data)
-{
- 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, ts_data->client->addr,
- &dbbus_tx_data[0], 3);
- read_i2c_seq(ts_data, 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(struct msg21xx_ts_data *ts_data)
-{
- 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, ts_data->client->addr, &dbbus_tx_data[0], 3);
- read_i2c_seq(ts_data, 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, ts_data->client->addr,
- &dbbus_tx_data[0], 3);
- read_i2c_seq(ts_data, 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(&ts_data->client->dev,
- &dev_attr_tpp) < 0)
- dev_err(&ts_data->client->dev, "Failed to create device file(%s)!\n",
- dev_attr_tpp.attr.name);
- }
-}
-#endif
-
-MODULE_AUTHOR("MStar Semiconductor, Inc.");
-MODULE_LICENSE("GPL v2");
--
cgit v1.1