From 1698e9414403094db9352482da5ddaa4de6c792d Mon Sep 17 00:00:00 2001 From: z00112798 <zhaoxuewen@huawei.com> Date: Sun, 8 Feb 2015 16:08:03 +0800 Subject: [PATCH] Input:Touch:Delete old synaptics TP driver Change-Id: Ib1abbdf12eb1167f980462f19a6dcb45a837100f Conflicts: arch/arm/configs/apq8026-lw_defconfig drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.h drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c drivers/input/touchscreen/synaptics_i2c_rmi4.c drivers/input/touchscreen/synaptics_i2c_rmi4.h include/linux/input/synaptics_dsx.h --- arch/arm/configs/apq8026-lw_defconfig | 0 drivers/input/touchscreen/Kconfig | 15 - drivers/input/touchscreen/Makefile | 5 +- .../input/touchscreen/synaptics_dsx/Kconfig | 86 - .../input/touchscreen/synaptics_dsx/Makefile | 12 - .../synaptics_dsx/synaptics_dsx_core.c | 4014 --------------- .../synaptics_dsx/synaptics_dsx_core.h | 381 -- .../synaptics_dsx/synaptics_dsx_fw_update.c | 1978 -------- .../synaptics_dsx/synaptics_dsx_i2c.c | 486 -- .../synaptics_dsx/synaptics_dsx_proximity.c | 671 --- .../synaptics_dsx/synaptics_dsx_rmi_dev.c | 781 --- .../synaptics_dsx/synaptics_dsx_spi.c | 335 -- .../input/touchscreen/synaptics_fw_update.c | 2306 --------- .../input/touchscreen/synaptics_i2c_rmi4.c | 4378 ----------------- .../input/touchscreen/synaptics_i2c_rmi4.h | 324 -- drivers/input/touchscreen/synaptics_rmi_dev.c | 711 --- include/linux/input/synaptics_dsx.h | 88 - 17 files changed, 1 insertion(+), 16570 deletions(-) mode change 100644 => 100755 arch/arm/configs/apq8026-lw_defconfig mode change 100644 => 100755 drivers/input/touchscreen/Kconfig mode change 100644 => 100755 drivers/input/touchscreen/Makefile delete mode 100644 drivers/input/touchscreen/synaptics_dsx/Kconfig delete mode 100644 drivers/input/touchscreen/synaptics_dsx/Makefile delete mode 100644 drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.h delete mode 100644 drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c delete mode 100755 drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c delete mode 100755 drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_proximity.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c delete mode 100755 drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_spi.c delete mode 100644 drivers/input/touchscreen/synaptics_fw_update.c delete mode 100644 drivers/input/touchscreen/synaptics_i2c_rmi4.c delete mode 100644 drivers/input/touchscreen/synaptics_i2c_rmi4.h delete mode 100644 drivers/input/touchscreen/synaptics_rmi_dev.c delete mode 100644 include/linux/input/synaptics_dsx.h diff --git a/arch/arm/configs/apq8026-lw_defconfig b/arch/arm/configs/apq8026-lw_defconfig old mode 100644 new mode 100755 diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig old mode 100644 new mode 100755 index 3eccb1ab760f..c95a0af5e2d7 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -11,7 +11,6 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN -source "drivers/input/touchscreen/synaptics_dsx/Kconfig" config TOUCHSCREEN_88PM860X tristate "Marvell 88PM860x touchscreen" @@ -975,20 +974,6 @@ config TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV To compile this driver as a module, choose M here: the module will be called synaptics_dsx_rmi4_dev. -config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE - tristate "Synaptics I2C touchscreen firmware update" - depends on TOUCHSCREEN_SYNAPTICS_I2C_RMI4 - help - This enables support for firmware update for Synaptics RMI4 - touchscreens. - - Say Y here if you have a Synaptics DSX I2C touchscreen - connected to your system. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_fw_update. config SECURE_TOUCH bool "Secure Touch" diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile old mode 100644 new mode 100755 index 632fdde4ad3c..de1657b013ac --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -53,7 +53,7 @@ obj-$(CONFIG_TOUCHSCREEN_PIXCIR) += pixcir_i2c_ts.o obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_v21) += synaptics_dsx/ + obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o @@ -76,8 +76,5 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o obj-$(CONFIG_TOUCHSCREEN_FT5X06) += ft5x06_ts.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV) += synaptics_rmi_dev.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) += synaptics_fw_update.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/ obj-$(CONFIG_TOUCHSCREEN_IT7260_I2C) += it7258_ts_i2c.o diff --git a/drivers/input/touchscreen/synaptics_dsx/Kconfig b/drivers/input/touchscreen/synaptics_dsx/Kconfig deleted file mode 100644 index 86263fddacea..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/Kconfig +++ /dev/null @@ -1,86 +0,0 @@ -# -# Synaptics DSX touchscreen driver configuration -# -menuconfig TOUCHSCREEN_SYNAPTICS_DSX_v21 - bool "Synaptics DSX touchscreen" - default y - help - Say Y here if you have a Synaptics DSX touchscreen connected - to your system. - - If unsure, say N. - -if TOUCHSCREEN_SYNAPTICS_DSX_v21 - -choice - default TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21 - prompt "Synaptics DSX touchscreen bus interface" - -config TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21 - bool "I2C" - depends on I2C - help - Say Y here if you have a Synaptics DSX touchscreen interfaced - to the host processor over I2C - - If unsure, say N. - - This module uses the services of DSX CORE - -config TOUCHSCREEN_SYNAPTICS_DSX_SPI_v21 - bool "SPI" - depends on SPI_MASTER - help - Say Y here if you have a Synaptics DSX touchscreen interfaced - to the host processor over SPI - - If unsure, say N. - - This module uses the services of DSX CORE -endchoice - -config TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 - tristate "Synaptics DSX core driver module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21 || TOUCHSCREEN_SYNAPTICS_DSX_SPI_v21 - help - Say Y here to enable basic touch reporting functionalities. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_core. - -config TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v21 - tristate "Synaptics DSX touchscreen RMI device module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 - help - Say Y here to enable support for direct RMI register access. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_rmi_dev. - -config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21 - tristate "Synaptics DSX touchscreen firmware update module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 - help - Say Y here to enable support for carrying out firmware update. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_fw_update. - -config TOUCHSCREEN_SYNAPTICS_DSX_PROXIMITY_v21 - tristate "Synaptics DSX touchscreen proximity module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 - help - Say Y here to enable support for proximity functionalities. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_proximity. - -endif diff --git a/drivers/input/touchscreen/synaptics_dsx/Makefile b/drivers/input/touchscreen/synaptics_dsx/Makefile deleted file mode 100644 index b35b222d5ae2..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the Synaptics DSX touchscreen driver. -# - -# Each configuration option enables a list of files. - -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21) += synaptics_dsx_i2c.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_SPI_v21) += synaptics_dsx_spi.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21) += synaptics_dsx_core.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v21) += synaptics_dsx_rmi_dev.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21) += synaptics_dsx_fw_update.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_PROXIMITY_v21) += synaptics_dsx_proximity.o diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c deleted file mode 100644 index 478fd42d5aa1..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c +++ /dev/null @@ -1,4014 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * Copyright (c) 2014, 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> -#include <linux/regulator/consumer.h> -#include <linux/input/synaptics_dsx_v2.h> -#include "synaptics_dsx_core.h" -#ifdef KERNEL_ABOVE_2_6_38 -#include <linux/input/mt.h> -#endif -#if defined(CONFIG_SECURE_TOUCH) -#include <linux/errno.h> -#include <asm/system.h> -#endif - -#define INPUT_PHYS_NAME "synaptics_dsx/input0" -#define DEBUGFS_DIR_NAME "ts_debug" - -#ifdef KERNEL_ABOVE_2_6_38 -#define TYPE_B_PROTOCOL -#endif - -#define NO_0D_WHILE_2D -#define REPORT_2D_Z -#define REPORT_2D_W - -#define F12_DATA_15_WORKAROUND - -/* -#define IGNORE_FN_INIT_FAILURE -*/ - -#define RPT_TYPE (1 << 0) -#define RPT_X_LSB (1 << 1) -#define RPT_X_MSB (1 << 2) -#define RPT_Y_LSB (1 << 3) -#define RPT_Y_MSB (1 << 4) -#define RPT_Z (1 << 5) -#define RPT_WX (1 << 6) -#define RPT_WY (1 << 7) -#define RPT_DEFAULT (RPT_TYPE | RPT_X_LSB | RPT_X_MSB | RPT_Y_LSB | RPT_Y_MSB) - -#define EXP_FN_WORK_DELAY_MS 1000 /* ms */ -#define MAX_F11_TOUCH_WIDTH 15 - -#define CHECK_STATUS_TIMEOUT_MS 100 - -#define F01_STD_QUERY_LEN 21 -#define F01_BUID_ID_OFFSET 18 -#define F11_STD_QUERY_LEN 9 -#define F11_STD_CTRL_LEN 10 -#define F11_STD_DATA_LEN 12 - -#define STATUS_NO_ERROR 0x00 -#define STATUS_RESET_OCCURRED 0x01 -#define STATUS_INVALID_CONFIG 0x02 -#define STATUS_DEVICE_FAILURE 0x03 -#define STATUS_CONFIG_CRC_FAILURE 0x04 -#define STATUS_FIRMWARE_CRC_FAILURE 0x05 -#define STATUS_CRC_IN_PROGRESS 0x06 - -#define NORMAL_OPERATION (0 << 0) -#define SENSOR_SLEEP (1 << 0) -#define NO_SLEEP_OFF (0 << 2) -#define NO_SLEEP_ON (1 << 2) -#define CONFIGURED (1 << 7) - -#define SYNA_F11_MAX 4096 -#define SYNA_F12_MAX 65536 - -static int synaptics_rmi4_f12_set_enables(struct synaptics_rmi4_data *rmi4_data, - unsigned short ctrl28); - -static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data); -static int synaptics_rmi4_reinit_device(struct synaptics_rmi4_data *rmi4_data); -static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data); - -static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -#if defined(CONFIG_FB) -static int fb_notifier_callback(struct notifier_block *self, - unsigned long event, void *data); -#elif defined(CONFIG_HAS_EARLYSUSPEND) -static void synaptics_rmi4_early_suspend(struct early_suspend *h); - -static void synaptics_rmi4_late_resume(struct early_suspend *h); -#endif - -static int synaptics_rmi4_suspend(struct device *dev); - -static int synaptics_rmi4_resume(struct device *dev); - -static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static irqreturn_t synaptics_rmi4_irq(int irq, void *data); - -#if defined(CONFIG_SECURE_TOUCH) -static ssize_t synaptics_secure_touch_enable_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_secure_touch_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_secure_touch_show(struct device *dev, - struct device_attribute *attr, char *buf); -#endif - -struct synaptics_rmi4_f01_device_status { - union { - struct { - unsigned char status_code:4; - unsigned char reserved:2; - unsigned char flash_prog:1; - unsigned char unconfigured:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f12_query_5 { - union { - struct { - unsigned char size_of_query6; - struct { - unsigned char ctrl0_is_present:1; - unsigned char ctrl1_is_present:1; - unsigned char ctrl2_is_present:1; - unsigned char ctrl3_is_present:1; - unsigned char ctrl4_is_present:1; - unsigned char ctrl5_is_present:1; - unsigned char ctrl6_is_present:1; - unsigned char ctrl7_is_present:1; - } __packed; - struct { - unsigned char ctrl8_is_present:1; - unsigned char ctrl9_is_present:1; - unsigned char ctrl10_is_present:1; - unsigned char ctrl11_is_present:1; - unsigned char ctrl12_is_present:1; - unsigned char ctrl13_is_present:1; - unsigned char ctrl14_is_present:1; - unsigned char ctrl15_is_present:1; - } __packed; - struct { - unsigned char ctrl16_is_present:1; - unsigned char ctrl17_is_present:1; - unsigned char ctrl18_is_present:1; - unsigned char ctrl19_is_present:1; - unsigned char ctrl20_is_present:1; - unsigned char ctrl21_is_present:1; - unsigned char ctrl22_is_present:1; - unsigned char ctrl23_is_present:1; - } __packed; - struct { - unsigned char ctrl24_is_present:1; - unsigned char ctrl25_is_present:1; - unsigned char ctrl26_is_present:1; - unsigned char ctrl27_is_present:1; - unsigned char ctrl28_is_present:1; - unsigned char ctrl29_is_present:1; - unsigned char ctrl30_is_present:1; - unsigned char ctrl31_is_present:1; - } __packed; - }; - unsigned char data[5]; - }; -}; - -struct synaptics_rmi4_f12_query_8 { - union { - struct { - unsigned char size_of_query9; - struct { - unsigned char data0_is_present:1; - unsigned char data1_is_present:1; - unsigned char data2_is_present:1; - unsigned char data3_is_present:1; - unsigned char data4_is_present:1; - unsigned char data5_is_present:1; - unsigned char data6_is_present:1; - unsigned char data7_is_present:1; - } __packed; - struct { - unsigned char data8_is_present:1; - unsigned char data9_is_present:1; - unsigned char data10_is_present:1; - unsigned char data11_is_present:1; - unsigned char data12_is_present:1; - unsigned char data13_is_present:1; - unsigned char data14_is_present:1; - unsigned char data15_is_present:1; - } __packed; - }; - unsigned char data[3]; - }; -}; - -struct synaptics_rmi4_f12_ctrl_8 { - union { - struct { - unsigned char max_x_coord_lsb; - unsigned char max_x_coord_msb; - unsigned char max_y_coord_lsb; - unsigned char max_y_coord_msb; - unsigned char rx_pitch_lsb; - unsigned char rx_pitch_msb; - unsigned char tx_pitch_lsb; - unsigned char tx_pitch_msb; - unsigned char low_rx_clip; - unsigned char high_rx_clip; - unsigned char low_tx_clip; - unsigned char high_tx_clip; - unsigned char num_of_rx; - unsigned char num_of_tx; - }; - unsigned char data[14]; - }; -}; - -struct synaptics_rmi4_f12_ctrl_23 { - union { - struct { - unsigned char obj_type_enable; - unsigned char max_reported_objects; - }; - unsigned char data[2]; - }; -}; - -struct synaptics_rmi4_f12_finger_data { - unsigned char object_type_and_status; - unsigned char x_lsb; - unsigned char x_msb; - unsigned char y_lsb; - unsigned char y_msb; -#ifdef REPORT_2D_Z - unsigned char z; -#endif -#ifdef REPORT_2D_W - unsigned char wx; - unsigned char wy; -#endif -}; - -struct synaptics_rmi4_f1a_query { - union { - struct { - unsigned char max_button_count:3; - unsigned char reserved:5; - unsigned char has_general_control:1; - unsigned char has_interrupt_enable:1; - unsigned char has_multibutton_select:1; - unsigned char has_tx_rx_map:1; - unsigned char has_perbutton_threshold:1; - unsigned char has_release_threshold:1; - unsigned char has_strongestbtn_hysteresis:1; - unsigned char has_filter_strength:1; - } __packed; - unsigned char data[2]; - }; -}; - -struct synaptics_rmi4_f1a_control_0 { - union { - struct { - unsigned char multibutton_report:2; - unsigned char filter_mode:2; - unsigned char reserved:4; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f1a_control { - struct synaptics_rmi4_f1a_control_0 general_control; - unsigned char button_int_enable; - unsigned char multi_button; - unsigned char *txrx_map; - unsigned char *button_threshold; - unsigned char button_release_threshold; - unsigned char strongest_button_hysteresis; - unsigned char filter_strength; -}; - -struct synaptics_rmi4_f1a_handle { - int button_bitmask_size; - unsigned char max_count; - unsigned char valid_button_count; - unsigned char *button_data_buffer; - unsigned char *button_map; - struct synaptics_rmi4_f1a_query button_query; - struct synaptics_rmi4_f1a_control button_control; -}; - -struct synaptics_rmi4_exp_fhandler { - struct synaptics_rmi4_exp_fn *exp_fn; - bool insert; - bool remove; - struct list_head link; -}; - -struct synaptics_rmi4_exp_fn_data { - bool initialized; - bool queue_work; - struct mutex mutex; - struct list_head list; - struct delayed_work work; - struct workqueue_struct *workqueue; - struct synaptics_rmi4_data *rmi4_data; -}; - -static struct synaptics_rmi4_exp_fn_data exp_data; - -static struct device_attribute attrs[] = { - __ATTR(full_pm_cycle, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_full_pm_cycle_show, - synaptics_rmi4_full_pm_cycle_store), - __ATTR(reset, (S_IWUSR | S_IWGRP), - NULL, - synaptics_rmi4_f01_reset_store), - __ATTR(productinfo, S_IRUGO, - synaptics_rmi4_f01_productinfo_show, - synaptics_rmi4_store_error), - __ATTR(buildid, S_IRUGO, - synaptics_rmi4_f01_buildid_show, - synaptics_rmi4_store_error), - __ATTR(flashprog, S_IRUGO, - synaptics_rmi4_f01_flashprog_show, - synaptics_rmi4_store_error), - __ATTR(0dbutton, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_0dbutton_show, - synaptics_rmi4_0dbutton_store), -#if defined(CONFIG_SECURE_TOUCH) - __ATTR(secure_touch_enable, (S_IRUGO | S_IWUGO), - synaptics_secure_touch_enable_show, - synaptics_secure_touch_enable_store), - __ATTR(secure_touch, S_IRUGO , - synaptics_secure_touch_show, - NULL), -#endif -}; - -#define MAX_BUF_SIZE 256 -#define VKEY_VER_CODE "0x01" - -#define HEIGHT_SCALE_NUM 8 -#define HEIGHT_SCALE_DENOM 10 - -/* numerator and denomenator for border equations */ -#define BORDER_ADJUST_NUM 3 -#define BORDER_ADJUST_DENOM 4 - -static struct kobject *vkey_kobj; -static char *vkey_buf; - -static ssize_t vkey_show(struct kobject *obj, - struct kobj_attribute *attr, char *buf) -{ - strlcpy(buf, vkey_buf, MAX_BUF_SIZE); - return strnlen(buf, MAX_BUF_SIZE); -} - -static struct kobj_attribute vkey_obj_attr = { - .attr = { - .mode = S_IRUGO, - .name = "virtualkeys."PLATFORM_DRIVER_NAME, - }, - .show = vkey_show, -}; - -static struct attribute *vkey_attr[] = { - &vkey_obj_attr.attr, - NULL, -}; - -static struct attribute_group vkey_grp = { - .attrs = vkey_attr, -}; - -static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val) -{ - struct synaptics_rmi4_data *rmi4_data = _data; - - if (val) - synaptics_rmi4_suspend(&rmi4_data->input_dev->dev); - else - synaptics_rmi4_resume(&rmi4_data->input_dev->dev); - - return 0; -} - -static int synaptics_rmi4_debug_suspend_get(void *_data, u64 *val) -{ - struct synaptics_rmi4_data *rmi4_data = _data; - - *val = rmi4_data->suspended; - - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, synaptics_rmi4_debug_suspend_get, - synaptics_rmi4_debug_suspend_set, "%lld\n"); - -#if defined(CONFIG_SECURE_TOUCH) -static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) -{ - init_completion(&data->st_powerdown); - init_completion(&data->st_irq_processed); -} -static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *rmi4_data) -{ - sysfs_notify(&rmi4_data->input_dev->dev.kobj, NULL, "secure_touch"); -} -static irqreturn_t synaptics_filter_interrupt( - struct synaptics_rmi4_data *rmi4_data) -{ - if (atomic_read(&rmi4_data->st_enabled)) { - if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, 0, 1) == 0) { - synaptics_secure_touch_notify(rmi4_data); - wait_for_completion_interruptible( - &rmi4_data->st_irq_processed); - } - return IRQ_HANDLED; - } - return IRQ_NONE; -} -static void synaptics_secure_touch_stop( - struct synaptics_rmi4_data *rmi4_data, - int blocking) -{ - if (atomic_read(&rmi4_data->st_enabled)) { - atomic_set(&rmi4_data->st_pending_irqs, -1); - synaptics_secure_touch_notify(rmi4_data); - if (blocking) - wait_for_completion_interruptible( - &rmi4_data->st_powerdown); - } -} -#else -static void synaptics_secure_touch_init(struct synaptics_rmi4_data *rmi4_data) -{ -} -static irqreturn_t synaptics_filter_interrupt( - struct synaptics_rmi4_data *rmi4_data) -{ - return IRQ_NONE; -} -static void synaptics_secure_touch_stop( - struct synaptics_rmi4_data *rmi4_data, - int blocking) -{ -} -#endif - -#if defined(CONFIG_SECURE_TOUCH) -static ssize_t synaptics_secure_touch_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - return scnprintf( - buf, - PAGE_SIZE, - "%d", - atomic_read(&rmi4_data->st_enabled)); -} -/* - * Accept only "0" and "1" valid values. - * "0" will reset the st_enabled flag, then wake up the reading process and - * the interrupt handler. - * The bus driver is notified via pm_runtime that it is not required to stay - * awake anymore. - * It will also make sure the queue of events is emptied in the controller, - * in case a touch happened in between the secure touch being disabled and - * the local ISR being ungated. - * "1" will set the st_enabled flag and clear the st_pending_irqs flag. - * The bus driver is requested via pm_runtime to stay awake. - */ -static ssize_t synaptics_secure_touch_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - unsigned long value; - int err = 0; - - if (count > 2) - return -EINVAL; - - err = kstrtoul(buf, 10, &value); - if (err != 0) - return err; - - err = count; - - switch (value) { - case 0: - if (atomic_read(&rmi4_data->st_enabled) == 0) - break; - - synaptics_rmi4_bus_put(rmi4_data); - atomic_set(&rmi4_data->st_enabled, 0); - synaptics_secure_touch_notify(rmi4_data); - complete(&rmi4_data->st_irq_processed); - synaptics_rmi4_irq(rmi4_data->irq, rmi4_data); - complete(&rmi4_data->st_powerdown); - - break; - case 1: - if (atomic_read(&rmi4_data->st_enabled)) { - err = -EBUSY; - break; - } - - synchronize_irq(rmi4_data->irq); - - if (synaptics_rmi4_bus_get(rmi4_data) < 0) { - dev_err( - rmi4_data->pdev->dev.parent, - "synaptics_rmi4_bus_get failed\n"); - err = -EIO; - break; - } - - INIT_COMPLETION(rmi4_data->st_powerdown); - INIT_COMPLETION(rmi4_data->st_irq_processed); - atomic_set(&rmi4_data->st_enabled, 1); - atomic_set(&rmi4_data->st_pending_irqs, 0); - break; - default: - dev_err( - rmi4_data->pdev->dev.parent, - "unsupported value: %lu\n", value); - err = -EINVAL; - break; - } - return err; -} - -/* - * This function returns whether there are pending interrupts, or - * other error conditions that need to be signaled to the userspace library, - * according tot he following logic: - * - st_enabled is 0 if secure touch is not enabled, returning -EBADF - * - st_pending_irqs is -1 to signal that secure touch is in being stopped, - * returning -EINVAL - * - st_pending_irqs is 1 to signal that there is a pending irq, returning - * the value "1" to the sysfs read operation - * - st_pending_irqs is 0 (only remaining case left) if the pending interrupt - * has been processed, so the interrupt handler can be allowed to continue. - */ -static ssize_t synaptics_secure_touch_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - int val = 0; - if (atomic_read(&rmi4_data->st_enabled) == 0) - return -EBADF; - - if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, -1, 0) == -1) - return -EINVAL; - - if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, 1, 0) == 1) - val = 1; - else - complete(&rmi4_data->st_irq_processed); - - return scnprintf(buf, PAGE_SIZE, "%u", val); - -} -#endif - -static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", - rmi4_data->full_pm_cycle); -} - -static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - rmi4_data->full_pm_cycle = input > 0 ? 1 : 0; - - return count; -} - -static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int reset; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - if (sscanf(buf, "%u", &reset) != 1) - return -EINVAL; - - if (reset != 1) - return -EINVAL; - - retval = synaptics_rmi4_reset_device(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue reset command, error = %d\n", - __func__, retval); - return retval; - } - - return count; -} - -static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "0x%02x 0x%02x\n", - (rmi4_data->rmi4_mod_info.product_info[0]), - (rmi4_data->rmi4_mod_info.product_info[1])); -} - -static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", - rmi4_data->firmware_id); -} - -static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - struct synaptics_rmi4_f01_device_status device_status; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr, - device_status.data, - sizeof(device_status.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read device status, error = %d\n", - __func__, retval); - return retval; - } - - return snprintf(buf, PAGE_SIZE, "%u\n", - device_status.flash_prog); -} - -static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", - rmi4_data->button_0d_enabled); -} - -static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - unsigned char ii; - unsigned char intr_enable; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - input = input > 0 ? 1 : 0; - - if (rmi4_data->button_0d_enabled == input) - return count; - - if (list_empty(&rmi->support_fn_list)) - return -ENODEV; - - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) { - ii = fhandler->intr_reg_num; - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr + 1 + ii, - &intr_enable, - sizeof(intr_enable)); - if (retval < 0) - return retval; - - if (input == 1) - intr_enable |= fhandler->intr_mask; - else - intr_enable &= ~fhandler->intr_mask; - - retval = synaptics_rmi4_reg_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr + 1 + ii, - &intr_enable, - sizeof(intr_enable)); - if (retval < 0) - return retval; - } - } - - rmi4_data->button_0d_enabled = input; - - return count; -} - - /** - * synaptics_rmi4_f11_abs_report() - * - * Called by synaptics_rmi4_report_touch() when valid Function $11 - * finger data has been detected. - * - * This function reads the Function $11 data registers, determines the - * status of each finger supported by the Function, processes any - * necessary coordinate manipulation, reports the finger data to - * the input subsystem, and returns the number of fingers detected. - */ -static int synaptics_rmi4_f11_abs_report(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - unsigned char touch_count = 0; /* number of touch points */ - unsigned char reg_index; - unsigned char finger; - unsigned char fingers_supported; - unsigned char num_of_finger_status_regs; - unsigned char finger_shift; - unsigned char finger_status; - unsigned char data_reg_blk_size; - unsigned char finger_status_reg[3]; - unsigned char data[F11_STD_DATA_LEN]; - unsigned short data_addr; - unsigned short data_offset; - int x; - int y; - int wx; - int wy; - int temp; - - /* - * The number of finger status registers is determined by the - * maximum number of fingers supported - 2 bits per finger. So - * the number of finger status registers to read is: - * register_count = ceil(max_num_of_fingers / 4) - */ - fingers_supported = fhandler->num_of_data_points; - num_of_finger_status_regs = (fingers_supported + 3) / 4; - data_addr = fhandler->full_addr.data_base; - data_reg_blk_size = fhandler->size_of_data_register_block; - - retval = synaptics_rmi4_reg_read(rmi4_data, - data_addr, - finger_status_reg, - num_of_finger_status_regs); - if (retval < 0) - return 0; - - for (finger = 0; finger < fingers_supported; finger++) { - reg_index = finger / 4; - finger_shift = (finger % 4) * 2; - finger_status = (finger_status_reg[reg_index] >> finger_shift) - & MASK_2BIT; - - /* - * Each 2-bit finger status field represents the following: - * 00 = finger not present - * 01 = finger present and data accurate - * 10 = finger present but data may be inaccurate - * 11 = reserved - */ -#ifdef TYPE_B_PROTOCOL - input_mt_slot(rmi4_data->input_dev, finger); - input_mt_report_slot_state(rmi4_data->input_dev, - MT_TOOL_FINGER, finger_status); -#endif - - if (finger_status) { - data_offset = data_addr + - num_of_finger_status_regs + - (finger * data_reg_blk_size); - retval = synaptics_rmi4_reg_read(rmi4_data, - data_offset, - data, - data_reg_blk_size); - if (retval < 0) - return 0; - - x = (data[0] << 4) | (data[2] & MASK_4BIT); - y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT); - wx = (data[3] & MASK_4BIT); - wy = (data[3] >> 4) & MASK_4BIT; - - if (rmi4_data->hw_if->board_data->swap_axes) { - temp = x; - x = y; - y = temp; - temp = wx; - wx = wy; - wy = temp; - } - - if (rmi4_data->hw_if->board_data->x_flip) - x = rmi4_data->sensor_max_x - x; - if (rmi4_data->hw_if->board_data->y_flip) - y = rmi4_data->sensor_max_y - y; - - input_report_key(rmi4_data->input_dev, - BTN_TOUCH, 1); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, 1); - input_report_abs(rmi4_data->input_dev, - ABS_MT_POSITION_X, x); - input_report_abs(rmi4_data->input_dev, - ABS_MT_POSITION_Y, y); -#ifdef REPORT_2D_W - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MAJOR, max(wx, wy)); - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MINOR, min(wx, wy)); -#endif -#ifndef TYPE_B_PROTOCOL - input_mt_sync(rmi4_data->input_dev); -#endif - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Finger %d:\n" - "status = 0x%02x\n" - "x = %d\n" - "y = %d\n" - "wx = %d\n" - "wy = %d\n", - __func__, finger, - finger_status, - x, y, wx, wy); - - touch_count++; - } - } - - if (touch_count == 0) { - input_report_key(rmi4_data->input_dev, - BTN_TOUCH, 0); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, 0); -#ifndef TYPE_B_PROTOCOL - input_mt_sync(rmi4_data->input_dev); -#endif - } - - input_sync(rmi4_data->input_dev); - - return touch_count; -} - - /** - * synaptics_rmi4_f12_abs_report() - * - * Called by synaptics_rmi4_report_touch() when valid Function $12 - * finger data has been detected. - * - * This function reads the Function $12 data registers, determines the - * status of each finger supported by the Function, processes any - * necessary coordinate manipulation, reports the finger data to - * the input subsystem, and returns the number of fingers detected. - */ -static int synaptics_rmi4_f12_abs_report(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - unsigned char touch_count = 0; /* number of touch points */ - unsigned char finger; - unsigned char fingers_to_process; - unsigned char finger_status; - unsigned char size_of_2d_data; - unsigned short data_addr; - int x; - int y; - int wx; - int wy; - int temp; - struct synaptics_rmi4_f12_extra_data *extra_data; - struct synaptics_rmi4_f12_finger_data *data; - struct synaptics_rmi4_f12_finger_data *finger_data; -#ifdef F12_DATA_15_WORKAROUND - static unsigned char fingers_already_present; -#endif - - fingers_to_process = fhandler->num_of_data_points; - data_addr = fhandler->full_addr.data_base; - extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra; - size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data); - - - /* Determine the total number of fingers to process */ - if (extra_data->data15_size) { - retval = synaptics_rmi4_reg_read(rmi4_data, - data_addr + extra_data->data15_offset, - extra_data->data15_data, - extra_data->data15_size); - if (retval < 0) - return 0; - - /* Start checking from the highest bit */ - temp = extra_data->data15_size - 1; /* Highest byte */ - finger = (fingers_to_process - 1) % 8; /* Highest bit */ - do { - if (extra_data->data15_data[temp] & (1 << finger)) - break; - - if (finger) { - finger--; - } else { - temp--; /* Move to the next lower byte */ - finger = 7; - } - - fingers_to_process--; - } while (fingers_to_process); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Number of fingers to process = %d\n", - __func__, fingers_to_process); - } - -#ifdef F12_DATA_15_WORKAROUND - fingers_to_process = max(fingers_to_process, fingers_already_present); -#endif - - if (!fingers_to_process) { - synaptics_rmi4_free_fingers(rmi4_data); - return 0; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - data_addr + extra_data->data1_offset, - (unsigned char *)fhandler->data, - fingers_to_process * size_of_2d_data); - if (retval < 0) - return 0; - - data = (struct synaptics_rmi4_f12_finger_data *)fhandler->data; - - for (finger = 0; finger < fingers_to_process; finger++) { - finger_data = data + finger; - finger_status = finger_data->object_type_and_status; - - if (finger_status == F12_FINGER_STATUS) { -#ifdef TYPE_B_PROTOCOL - input_mt_slot(rmi4_data->input_dev, finger); - input_mt_report_slot_state(rmi4_data->input_dev, - MT_TOOL_FINGER, 1); -#endif - -#ifdef F12_DATA_15_WORKAROUND - fingers_already_present = finger + 1; -#endif - - x = (finger_data->x_msb << 8) | (finger_data->x_lsb); - y = (finger_data->y_msb << 8) | (finger_data->y_lsb); -#ifdef REPORT_2D_W - wx = finger_data->wx; - wy = finger_data->wy; -#endif - - if (rmi4_data->hw_if->board_data->swap_axes) { - temp = x; - x = y; - y = temp; - temp = wx; - wx = wy; - wy = temp; - } - - if (rmi4_data->hw_if->board_data->x_flip) - x = rmi4_data->sensor_max_x - x; - if (rmi4_data->hw_if->board_data->y_flip) - y = rmi4_data->sensor_max_y - y; - - input_report_key(rmi4_data->input_dev, - BTN_TOUCH, 1); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, 1); - input_report_abs(rmi4_data->input_dev, - ABS_MT_POSITION_X, x); - input_report_abs(rmi4_data->input_dev, - ABS_MT_POSITION_Y, y); -#ifdef REPORT_2D_W - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MAJOR, max(wx, wy)); - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MINOR, min(wx, wy)); -#endif -#ifndef TYPE_B_PROTOCOL - input_mt_sync(rmi4_data->input_dev); -#endif - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Finger %d:\n" - "status = 0x%02x\n" - "x = %d\n" - "y = %d\n" - "wx = %d\n" - "wy = %d\n", - __func__, finger, - finger_status, - x, y, wx, wy); - - touch_count++; - } else { -#ifdef TYPE_B_PROTOCOL - input_mt_slot(rmi4_data->input_dev, finger); - input_mt_report_slot_state(rmi4_data->input_dev, - MT_TOOL_FINGER, 0); -#endif - } - } - - if (touch_count == 0) { - input_report_key(rmi4_data->input_dev, - BTN_TOUCH, 0); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, 0); -#ifndef TYPE_B_PROTOCOL - input_mt_sync(rmi4_data->input_dev); -#endif - } - - input_sync(rmi4_data->input_dev); - - return touch_count; -} - -static void synaptics_rmi4_f1a_report(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - unsigned char touch_count = 0; - unsigned char button; - unsigned char index; - unsigned char shift; - unsigned char status; - unsigned char *data; - unsigned short data_addr = fhandler->full_addr.data_base; - struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; - static unsigned char do_once = 1; - static bool current_status[MAX_NUMBER_OF_BUTTONS]; -#ifdef NO_0D_WHILE_2D - static bool before_2d_status[MAX_NUMBER_OF_BUTTONS]; - static bool while_2d_status[MAX_NUMBER_OF_BUTTONS]; -#endif - - if (do_once) { - memset(current_status, 0, sizeof(current_status)); -#ifdef NO_0D_WHILE_2D - memset(before_2d_status, 0, sizeof(before_2d_status)); - memset(while_2d_status, 0, sizeof(while_2d_status)); -#endif - do_once = 0; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - data_addr, - f1a->button_data_buffer, - f1a->button_bitmask_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read button data registers\n", - __func__); - return; - } - - data = f1a->button_data_buffer; - - for (button = 0; button < f1a->valid_button_count; button++) { - index = button / 8; - shift = button % 8; - status = ((data[index] >> shift) & MASK_1BIT); - - if (current_status[button] == status) - continue; - else - current_status[button] = status; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Button %d (code %d) ->%d\n", - __func__, button, - f1a->button_map[button], - status); -#ifdef NO_0D_WHILE_2D - if (rmi4_data->fingers_on_2d == false) { - if (status == 1) { - before_2d_status[button] = 1; - } else { - if (while_2d_status[button] == 1) { - while_2d_status[button] = 0; - continue; - } else { - before_2d_status[button] = 0; - } - } - touch_count++; - input_report_key(rmi4_data->input_dev, - f1a->button_map[button], - status); - } else { - if (before_2d_status[button] == 1) { - before_2d_status[button] = 0; - touch_count++; - input_report_key(rmi4_data->input_dev, - f1a->button_map[button], - status); - } else { - if (status == 1) - while_2d_status[button] = 1; - else - while_2d_status[button] = 0; - } - } -#else - touch_count++; - input_report_key(rmi4_data->input_dev, - f1a->button_map[button], - status); -#endif - } - - if (touch_count) - input_sync(rmi4_data->input_dev); - - return; -} - - /** - * synaptics_rmi4_report_touch() - * - * Called by synaptics_rmi4_sensor_report(). - * - * This function calls the appropriate finger data reporting function - * based on the function handler it receives and returns the number of - * fingers detected. - */ -static void synaptics_rmi4_report_touch(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - unsigned char touch_count_2d; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Function %02x reporting\n", - __func__, fhandler->fn_number); - - switch (fhandler->fn_number) { - case SYNAPTICS_RMI4_F11: - touch_count_2d = synaptics_rmi4_f11_abs_report(rmi4_data, - fhandler); - - if (touch_count_2d) - rmi4_data->fingers_on_2d = true; - else - rmi4_data->fingers_on_2d = false; - break; - case SYNAPTICS_RMI4_F12: - touch_count_2d = synaptics_rmi4_f12_abs_report(rmi4_data, - fhandler); - - if (touch_count_2d) - rmi4_data->fingers_on_2d = true; - else - rmi4_data->fingers_on_2d = false; - break; - case SYNAPTICS_RMI4_F1A: - synaptics_rmi4_f1a_report(rmi4_data, fhandler); - break; - default: - break; - } - - return; -} - - /** - * synaptics_rmi4_sensor_report() - * - * Called by synaptics_rmi4_irq(). - * - * This function determines the interrupt source(s) from the sensor - * and calls synaptics_rmi4_report_touch() with the appropriate - * function handler for each function with valid data inputs. - */ -static void synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char data[MAX_INTR_REGISTERS + 1]; - unsigned char *intr = &data[1]; - struct synaptics_rmi4_f01_device_status status; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - /* - * Get interrupt status information from F01 Data1 register to - * determine the source(s) that are flagging the interrupt. - */ - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr, - data, - rmi4_data->num_of_intr_regs + 1); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read interrupt status\n", - __func__); - return; - } - - status.data[0] = data[0]; - if (status.unconfigured && !status.flash_prog) { - pr_notice("%s: spontaneous reset detected\n", __func__); - retval = synaptics_rmi4_reinit_device(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to reinit device\n", - __func__); - } - return; - } - - /* - * Traverse the function handler list and service the source(s) - * of the interrupt accordingly. - */ - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->num_of_data_sources) { - if (fhandler->intr_mask & - intr[fhandler->intr_reg_num]) { - synaptics_rmi4_report_touch(rmi4_data, - fhandler); - } - } - } - } - - mutex_lock(&exp_data.mutex); - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) { - if (!exp_fhandler->insert && - !exp_fhandler->remove && - (exp_fhandler->exp_fn->attn != NULL)) - exp_fhandler->exp_fn->attn(rmi4_data, intr[0]); - } - } - mutex_unlock(&exp_data.mutex); - - return; -} - - /** - * synaptics_rmi4_irq() - * - * Called by the kernel when an interrupt occurs (when the sensor - * asserts the attention irq). - * - * This function is the ISR thread and handles the acquisition - * and the reporting of finger data when the presence of fingers - * is detected. - */ -static irqreturn_t synaptics_rmi4_irq(int irq, void *data) -{ - struct synaptics_rmi4_data *rmi4_data = data; - - if (IRQ_HANDLED == synaptics_filter_interrupt(data)) - return IRQ_HANDLED; - - if (!rmi4_data->touch_stopped) - synaptics_rmi4_sensor_report(rmi4_data); - - return IRQ_HANDLED; -} - - /** - * synaptics_rmi4_irq_enable() - * - * Called by synaptics_rmi4_probe() and the power management functions - * in this driver and also exported to other expansion Function modules - * such as rmi_dev. - * - * This function handles the enabling and disabling of the attention - * irq including the setting up of the ISR thread. - */ -static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - int retval = 0; - unsigned char intr_status[MAX_INTR_REGISTERS]; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - if (enable) { - if (rmi4_data->irq_enabled) - return retval; - - /* Clear interrupts first */ - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr + 1, - intr_status, - rmi4_data->num_of_intr_regs); - if (retval < 0) - return retval; - - retval = request_threaded_irq(rmi4_data->irq, NULL, - synaptics_rmi4_irq, bdata->irq_flags, - PLATFORM_DRIVER_NAME, rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create irq thread\n", - __func__); - return retval; - } - - rmi4_data->irq_enabled = true; - } else { - if (rmi4_data->irq_enabled) { - disable_irq(rmi4_data->irq); - free_irq(rmi4_data->irq, rmi4_data); - rmi4_data->irq_enabled = false; - } - } - - return retval; -} - -static void synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count) -{ - unsigned char ii; - unsigned char intr_offset; - - fhandler->intr_reg_num = (intr_count + 7) / 8; - if (fhandler->intr_reg_num != 0) - fhandler->intr_reg_num -= 1; - - /* Set an enable bit for each data source */ - intr_offset = intr_count % 8; - fhandler->intr_mask = 0; - for (ii = intr_offset; - ii < ((fd->intr_src_count & MASK_3BIT) + - intr_offset); - ii++) - fhandler->intr_mask |= 1 << ii; - - return; -} - -static int synaptics_rmi4_f01_init(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count) -{ - fhandler->fn_number = fd->fn_number; - fhandler->num_of_data_sources = fd->intr_src_count; - fhandler->data = NULL; - fhandler->extra = NULL; - - synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count); - - rmi4_data->f01_query_base_addr = fd->query_base_addr; - rmi4_data->f01_ctrl_base_addr = fd->ctrl_base_addr; - rmi4_data->f01_data_base_addr = fd->data_base_addr; - rmi4_data->f01_cmd_base_addr = fd->cmd_base_addr; - - return 0; -} - - /** - * synaptics_rmi4_f11_init() - * - * Called by synaptics_rmi4_query_device(). - * - * This funtion parses information from the Function 11 registers - * and determines the number of fingers supported, x and y data ranges, - * offset to the associated interrupt status register, interrupt bit - * mask, and gathers finger data acquisition capabilities from the query - * registers. - */ -static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count) -{ - int retval; - unsigned char abs_data_size; - unsigned char abs_data_blk_size; - unsigned char query[F11_STD_QUERY_LEN]; - unsigned char control[F11_STD_CTRL_LEN]; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - fhandler->fn_number = fd->fn_number; - fhandler->num_of_data_sources = fd->intr_src_count; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base, - query, - sizeof(query)); - if (retval < 0) - return retval; - - /* Maximum number of fingers supported */ - if ((query[1] & MASK_3BIT) <= 4) - fhandler->num_of_data_points = (query[1] & MASK_3BIT) + 1; - else if ((query[1] & MASK_3BIT) == 5) - fhandler->num_of_data_points = 10; - - rmi4_data->num_of_fingers = fhandler->num_of_data_points; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.ctrl_base, - control, - sizeof(control)); - if (retval < 0) - return retval; - - /* Maximum x and y */ - rmi4_data->sensor_max_x = ((control[6] & MASK_8BIT) << 0) | - ((control[7] & MASK_4BIT) << 8); - rmi4_data->sensor_max_y = ((control[8] & MASK_8BIT) << 0) | - ((control[9] & MASK_4BIT) << 8); - - if (bdata->panel_maxx && bdata->panel_maxy && - (rmi4_data->sensor_max_x != bdata->panel_maxx || - rmi4_data->sensor_max_y != bdata->panel_maxy)) { - if (bdata->panel_maxx > SYNA_F11_MAX || - bdata->panel_maxy > SYNA_F11_MAX) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid panel resolution\n", __func__); - return -EINVAL; - } - - rmi4_data->sensor_max_x = bdata->panel_maxx; - rmi4_data->sensor_max_y = bdata->panel_maxy; - control[6] = rmi4_data->sensor_max_x & MASK_8BIT; - control[7] = (rmi4_data->sensor_max_x >> 8) & MASK_4BIT; - control[8] = rmi4_data->sensor_max_y & MASK_8BIT; - control[9] = (rmi4_data->sensor_max_y >> 8) & MASK_4BIT; - - retval = synaptics_rmi4_reg_write(rmi4_data, - fhandler->full_addr.ctrl_base, - control, - sizeof(control)); - if (retval < 0) - return retval; - } - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Function %02x max x = %d max y = %d\n", - __func__, fhandler->fn_number, - rmi4_data->sensor_max_x, - rmi4_data->sensor_max_y); - - rmi4_data->max_touch_width = MAX_F11_TOUCH_WIDTH; - - synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count); - - abs_data_size = query[5] & MASK_2BIT; - abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0)); - fhandler->size_of_data_register_block = abs_data_blk_size; - fhandler->data = NULL; - fhandler->extra = NULL; - - return retval; -} - -static int synaptics_rmi4_f12_set_enables(struct synaptics_rmi4_data *rmi4_data, - unsigned short ctrl28) -{ - int retval; - static unsigned short ctrl_28_address; - - if (ctrl28) - ctrl_28_address = ctrl28; - - retval = synaptics_rmi4_reg_write(rmi4_data, - ctrl_28_address, - &rmi4_data->report_enable, - sizeof(rmi4_data->report_enable)); - if (retval < 0) - return retval; - - return retval; -} - - /** - * synaptics_rmi4_f12_init() - * - * Called by synaptics_rmi4_query_device(). - * - * This funtion parses information from the Function 12 registers and - * determines the number of fingers supported, offset to the data1 - * register, x and y data ranges, offset to the associated interrupt - * status register, interrupt bit mask, and allocates memory resources - * for finger data acquisition. - */ -static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count) -{ - int retval; - unsigned char size_of_2d_data; - unsigned char size_of_query8; - unsigned char ctrl_8_offset; - unsigned char ctrl_23_offset; - unsigned char ctrl_28_offset; - unsigned char num_of_fingers; - struct synaptics_rmi4_f12_extra_data *extra_data; - struct synaptics_rmi4_f12_query_5 query_5; - struct synaptics_rmi4_f12_query_8 query_8; - struct synaptics_rmi4_f12_ctrl_8 ctrl_8; - struct synaptics_rmi4_f12_ctrl_23 ctrl_23; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - fhandler->fn_number = fd->fn_number; - fhandler->num_of_data_sources = fd->intr_src_count; - fhandler->extra = kmalloc(sizeof(*extra_data), GFP_KERNEL); - extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra; - size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data); - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + 5, - query_5.data, - sizeof(query_5.data)); - if (retval < 0) - return retval; - - ctrl_8_offset = query_5.ctrl0_is_present + - query_5.ctrl1_is_present + - query_5.ctrl2_is_present + - query_5.ctrl3_is_present + - query_5.ctrl4_is_present + - query_5.ctrl5_is_present + - query_5.ctrl6_is_present + - query_5.ctrl7_is_present; - - ctrl_23_offset = ctrl_8_offset + - query_5.ctrl8_is_present + - query_5.ctrl9_is_present + - query_5.ctrl10_is_present + - query_5.ctrl11_is_present + - query_5.ctrl12_is_present + - query_5.ctrl13_is_present + - query_5.ctrl14_is_present + - query_5.ctrl15_is_present + - query_5.ctrl16_is_present + - query_5.ctrl17_is_present + - query_5.ctrl18_is_present + - query_5.ctrl19_is_present + - query_5.ctrl20_is_present + - query_5.ctrl21_is_present + - query_5.ctrl22_is_present; - - ctrl_28_offset = ctrl_23_offset + - query_5.ctrl23_is_present + - query_5.ctrl24_is_present + - query_5.ctrl25_is_present + - query_5.ctrl26_is_present + - query_5.ctrl27_is_present; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_23_offset, - ctrl_23.data, - sizeof(ctrl_23.data)); - if (retval < 0) - return retval; - - /* Maximum number of fingers supported */ - fhandler->num_of_data_points = min(ctrl_23.max_reported_objects, - (unsigned char)F12_FINGERS_TO_SUPPORT); - - num_of_fingers = fhandler->num_of_data_points; - rmi4_data->num_of_fingers = num_of_fingers; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + 7, - &size_of_query8, - sizeof(size_of_query8)); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + 8, - query_8.data, - size_of_query8); - if (retval < 0) - return retval; - - /* Determine the presence of the Data0 register */ - extra_data->data1_offset = query_8.data0_is_present; - - if ((size_of_query8 >= 3) && (query_8.data15_is_present)) { - extra_data->data15_offset = query_8.data0_is_present + - query_8.data1_is_present + - query_8.data2_is_present + - query_8.data3_is_present + - query_8.data4_is_present + - query_8.data5_is_present + - query_8.data6_is_present + - query_8.data7_is_present + - query_8.data8_is_present + - query_8.data9_is_present + - query_8.data10_is_present + - query_8.data11_is_present + - query_8.data12_is_present + - query_8.data13_is_present + - query_8.data14_is_present; - extra_data->data15_size = (num_of_fingers + 7) / 8; - } else { - extra_data->data15_size = 0; - } - - rmi4_data->report_enable = RPT_DEFAULT; -#ifdef REPORT_2D_Z - rmi4_data->report_enable |= RPT_Z; -#endif -#ifdef REPORT_2D_W - rmi4_data->report_enable |= (RPT_WX | RPT_WY); -#endif - - retval = synaptics_rmi4_f12_set_enables(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_28_offset); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_8_offset, - ctrl_8.data, - sizeof(ctrl_8.data)); - if (retval < 0) - return retval; - - /* Maximum x and y */ - rmi4_data->sensor_max_x = - ((unsigned short)ctrl_8.max_x_coord_lsb << 0) | - ((unsigned short)ctrl_8.max_x_coord_msb << 8); - rmi4_data->sensor_max_y = - ((unsigned short)ctrl_8.max_y_coord_lsb << 0) | - ((unsigned short)ctrl_8.max_y_coord_msb << 8); - - if (bdata->panel_maxx && bdata->panel_maxy && - (rmi4_data->sensor_max_x != bdata->panel_maxx || - rmi4_data->sensor_max_y != bdata->panel_maxy)) { - if (bdata->panel_maxx > SYNA_F12_MAX || - bdata->panel_maxy > SYNA_F12_MAX) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid panel resolution\n", __func__); - return -EINVAL; - } - - rmi4_data->sensor_max_x = bdata->panel_maxx; - rmi4_data->sensor_max_y = bdata->panel_maxy; - ctrl_8.max_x_coord_lsb = rmi4_data->sensor_max_x & MASK_8BIT; - ctrl_8.max_x_coord_msb = (rmi4_data->sensor_max_x >> 8) & - MASK_4BIT; - ctrl_8.max_y_coord_lsb = rmi4_data->sensor_max_y & MASK_8BIT; - ctrl_8.max_y_coord_msb = (rmi4_data->sensor_max_y >> 8) & - MASK_4BIT; - - retval = synaptics_rmi4_reg_write(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_8_offset, - ctrl_8.data, - sizeof(ctrl_8.data)); - if (retval < 0) - return retval; - } - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Function %02x max x = %d max y = %d\n", - __func__, fhandler->fn_number, - rmi4_data->sensor_max_x, - rmi4_data->sensor_max_y); - - rmi4_data->num_of_rx = ctrl_8.num_of_rx; - rmi4_data->num_of_tx = ctrl_8.num_of_tx; - rmi4_data->max_touch_width = max(rmi4_data->num_of_rx, - rmi4_data->num_of_tx); - - synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count); - - /* Allocate memory for finger data storage space */ - fhandler->data_size = num_of_fingers * size_of_2d_data; - fhandler->data = kmalloc(fhandler->data_size, GFP_KERNEL); - - return retval; -} - -static int synaptics_rmi4_f1a_alloc_mem(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - struct synaptics_rmi4_f1a_handle *f1a; - - f1a = kzalloc(sizeof(*f1a), GFP_KERNEL); - if (!f1a) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for function handle\n", - __func__); - return -ENOMEM; - } - - fhandler->data = (void *)f1a; - fhandler->extra = NULL; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base, - f1a->button_query.data, - sizeof(f1a->button_query.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read query registers\n", - __func__); - return retval; - } - - f1a->max_count = f1a->button_query.max_button_count + 1; - - f1a->button_control.txrx_map = kzalloc(f1a->max_count * 2, GFP_KERNEL); - if (!f1a->button_control.txrx_map) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for tx rx mapping\n", - __func__); - return -ENOMEM; - } - - f1a->button_bitmask_size = (f1a->max_count + 7) / 8; - - f1a->button_data_buffer = kcalloc(f1a->button_bitmask_size, - sizeof(*(f1a->button_data_buffer)), GFP_KERNEL); - if (!f1a->button_data_buffer) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for data buffer\n", - __func__); - return -ENOMEM; - } - - f1a->button_map = kcalloc(f1a->max_count, - sizeof(*(f1a->button_map)), GFP_KERNEL); - if (!f1a->button_map) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for button map\n", - __func__); - return -ENOMEM; - } - - return 0; -} - -static int synaptics_rmi4_f1a_button_map(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - unsigned char ii; - unsigned char mapping_offset = 0; - struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - mapping_offset = f1a->button_query.has_general_control + - f1a->button_query.has_interrupt_enable + - f1a->button_query.has_multibutton_select; - - if (f1a->button_query.has_tx_rx_map) { - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.ctrl_base + mapping_offset, - f1a->button_control.txrx_map, - sizeof(f1a->button_control.txrx_map)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read tx rx mapping\n", - __func__); - return retval; - } - - rmi4_data->button_txrx_mapping = f1a->button_control.txrx_map; - } - - if (!bdata->cap_button_map) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: cap_button_map is NULL in board file\n", - __func__); - } else if (!bdata->cap_button_map->map) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Button map is missing in board file\n", - __func__); - } else { - if (bdata->cap_button_map->nbuttons != f1a->max_count) { - f1a->valid_button_count = min(f1a->max_count, - bdata->cap_button_map->nbuttons); - } else { - f1a->valid_button_count = f1a->max_count; - } - - for (ii = 0; ii < f1a->valid_button_count; ii++) - f1a->button_map[ii] = bdata->cap_button_map->map[ii]; - } - - return 0; -} - -static void synaptics_rmi4_f1a_kfree(struct synaptics_rmi4_fn *fhandler) -{ - struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; - - if (f1a) { - kfree(f1a->button_control.txrx_map); - kfree(f1a->button_data_buffer); - kfree(f1a->button_map); - kfree(f1a); - fhandler->data = NULL; - } - - return; -} - -static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count) -{ - int retval; - - fhandler->fn_number = fd->fn_number; - fhandler->num_of_data_sources = fd->intr_src_count; - - synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count); - - retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler); - if (retval < 0) - goto error_exit; - - retval = synaptics_rmi4_f1a_button_map(rmi4_data, fhandler); - if (retval < 0) - goto error_exit; - - rmi4_data->button_0d_enabled = 1; - - return 0; - -error_exit: - synaptics_rmi4_f1a_kfree(fhandler); - - return retval; -} - -static void synaptics_rmi4_empty_fn_list(struct synaptics_rmi4_data *rmi4_data) -{ - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_fn *fhandler_temp; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry_safe(fhandler, - fhandler_temp, - &rmi->support_fn_list, - link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) { - synaptics_rmi4_f1a_kfree(fhandler); - } else { - kfree(fhandler->extra); - kfree(fhandler->data); - } - list_del(&fhandler->link); - kfree(fhandler); - } - } - INIT_LIST_HEAD(&rmi->support_fn_list); - - return; -} - -static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data, - bool *was_in_bl_mode) -{ - int retval; - int timeout = CHECK_STATUS_TIMEOUT_MS; - unsigned char command = 0x01; - unsigned char intr_status; - struct synaptics_rmi4_f01_device_status status; - - /* Do a device reset first */ - retval = synaptics_rmi4_reg_write(rmi4_data, - rmi4_data->f01_cmd_base_addr, - &command, - sizeof(command)); - if (retval < 0) - return retval; - - msleep(rmi4_data->hw_if->board_data->reset_delay_ms); - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr, - status.data, - sizeof(status.data)); - if (retval < 0) - return retval; - - while (status.status_code == STATUS_CRC_IN_PROGRESS) { - if (timeout > 0) - msleep(20); - else - return -1; - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr, - status.data, - sizeof(status.data)); - if (retval < 0) - return retval; - - timeout -= 20; - } - - if (timeout != CHECK_STATUS_TIMEOUT_MS) - *was_in_bl_mode = true; - - if (status.flash_prog == 1) { - rmi4_data->flash_prog_mode = true; - pr_notice("%s: In flash prog mode, status = 0x%02x\n", - __func__, - status.status_code); - } else { - rmi4_data->flash_prog_mode = false; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr + 1, - &intr_status, - sizeof(intr_status)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read interrupt status\n", - __func__); - return retval; - } - - return 0; -} - -static void synaptics_rmi4_set_configured(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char device_ctrl; - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - &device_ctrl, - sizeof(device_ctrl)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set configured\n", - __func__); - return; - } - - rmi4_data->no_sleep_setting = device_ctrl & NO_SLEEP_ON; - device_ctrl |= CONFIGURED; - - retval = synaptics_rmi4_reg_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - &device_ctrl, - sizeof(device_ctrl)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set configured\n", - __func__); - } - - return; -} - -static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler, - struct synaptics_rmi4_fn_desc *rmi_fd, int page_number) -{ - *fhandler = kmalloc(sizeof(**fhandler), GFP_KERNEL); - if (!(*fhandler)) - return -ENOMEM; - - (*fhandler)->full_addr.data_base = - (rmi_fd->data_base_addr | - (page_number << 8)); - (*fhandler)->full_addr.ctrl_base = - (rmi_fd->ctrl_base_addr | - (page_number << 8)); - (*fhandler)->full_addr.cmd_base = - (rmi_fd->cmd_base_addr | - (page_number << 8)); - (*fhandler)->full_addr.query_base = - (rmi_fd->query_base_addr | - (page_number << 8)); - - return 0; -} - - /** - * synaptics_rmi4_query_device() - * - * Called by synaptics_rmi4_probe(). - * - * This funtion scans the page description table, records the offsets - * to the register types of Function $01, sets up the function handlers - * for Function $11 and Function $12, determines the number of interrupt - * sources from the sensor, adds valid Functions with data inputs to the - * Function linked list, parses information from the query registers of - * Function $01, and enables the interrupt sources from the valid Functions - * with data inputs. - */ -static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char ii; - unsigned char page_number; - unsigned char intr_count; - unsigned char f01_query[F01_STD_QUERY_LEN]; - unsigned short pdt_entry_addr; - unsigned short intr_addr; - bool f01found; - bool was_in_bl_mode; - struct synaptics_rmi4_fn_desc rmi_fd; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_device_info *rmi; - unsigned char pkg_id[PACKAGE_ID_SIZE]; - - rmi = &(rmi4_data->rmi4_mod_info); - -rescan_pdt: - f01found = false; - was_in_bl_mode = false; - intr_count = 0; - INIT_LIST_HEAD(&rmi->support_fn_list); - - /* Scan the page description tables of the pages to service */ - for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) { - for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END; - pdt_entry_addr -= PDT_ENTRY_SIZE) { - pdt_entry_addr |= (page_number << 8); - - retval = synaptics_rmi4_reg_read(rmi4_data, - pdt_entry_addr, - (unsigned char *)&rmi_fd, - sizeof(rmi_fd)); - if (retval < 0) - return retval; - - pdt_entry_addr &= ~(MASK_8BIT << 8); - - fhandler = NULL; - - if (rmi_fd.fn_number == 0) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Reached end of PDT\n", - __func__); - break; - } - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: F%02x found (page %d)\n", - __func__, rmi_fd.fn_number, - page_number); - - switch (rmi_fd.fn_number) { - case SYNAPTICS_RMI4_F01: - if (rmi_fd.intr_src_count == 0) - break; - - f01found = true; - - retval = synaptics_rmi4_alloc_fh(&fhandler, - &rmi_fd, page_number); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc for F%d\n", - __func__, - rmi_fd.fn_number); - return retval; - } - - retval = synaptics_rmi4_f01_init(rmi4_data, - fhandler, &rmi_fd, intr_count); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_check_status(rmi4_data, - &was_in_bl_mode); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to check status\n", - __func__); - return retval; - } - - if (was_in_bl_mode) { - kfree(fhandler); - fhandler = NULL; - goto rescan_pdt; - } - - if (rmi4_data->flash_prog_mode) - goto flash_prog_mode; - - break; - case SYNAPTICS_RMI4_F11: - if (rmi_fd.intr_src_count == 0) - break; - - retval = synaptics_rmi4_alloc_fh(&fhandler, - &rmi_fd, page_number); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc for F%d\n", - __func__, - rmi_fd.fn_number); - return retval; - } - - retval = synaptics_rmi4_f11_init(rmi4_data, - fhandler, &rmi_fd, intr_count); - if (retval < 0) - return retval; - break; - case SYNAPTICS_RMI4_F12: - if (rmi_fd.intr_src_count == 0) - break; - - retval = synaptics_rmi4_alloc_fh(&fhandler, - &rmi_fd, page_number); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc for F%d\n", - __func__, - rmi_fd.fn_number); - return retval; - } - - retval = synaptics_rmi4_f12_init(rmi4_data, - fhandler, &rmi_fd, intr_count); - if (retval < 0) - return retval; - break; - case SYNAPTICS_RMI4_F1A: - if (rmi_fd.intr_src_count == 0) - break; - - retval = synaptics_rmi4_alloc_fh(&fhandler, - &rmi_fd, page_number); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc for F%d\n", - __func__, - rmi_fd.fn_number); - return retval; - } - - retval = synaptics_rmi4_f1a_init(rmi4_data, - fhandler, &rmi_fd, intr_count); - if (retval < 0) { -#ifdef IGNORE_FN_INIT_FAILURE - kfree(fhandler); - fhandler = NULL; -#else - return retval; -#endif - } - break; - } - - /* Accumulate the interrupt count */ - intr_count += (rmi_fd.intr_src_count & MASK_3BIT); - - if (fhandler && rmi_fd.intr_src_count) { - list_add_tail(&fhandler->link, - &rmi->support_fn_list); - } - } - } - - if (!f01found) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F01\n", - __func__); - return -EINVAL; - } - -flash_prog_mode: - rmi4_data->num_of_intr_regs = (intr_count + 7) / 8; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Number of interrupt registers = %d\n", - __func__, rmi4_data->num_of_intr_regs); - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_query_base_addr, - f01_query, - sizeof(f01_query)); - if (retval < 0) - return retval; - - /* RMI Version 4.0 currently supported */ - rmi->version_major = 4; - rmi->version_minor = 0; - - rmi->manufacturer_id = f01_query[0]; - rmi->product_props = f01_query[1]; - rmi->product_info[0] = f01_query[2] & MASK_7BIT; - rmi->product_info[1] = f01_query[3] & MASK_7BIT; - rmi->date_code[0] = f01_query[4] & MASK_5BIT; - rmi->date_code[1] = f01_query[5] & MASK_4BIT; - rmi->date_code[2] = f01_query[6] & MASK_5BIT; - rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) | - (f01_query[8] & MASK_7BIT); - rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) | - (f01_query[10] & MASK_7BIT); - memcpy(rmi->product_id_string, &f01_query[11], 10); - - if (rmi->manufacturer_id != 1) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Non-Synaptics device found, manufacturer ID = %d\n", - __func__, rmi->manufacturer_id); - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_query_base_addr + F01_PACKAGE_ID_OFFSET, - pkg_id, sizeof(pkg_id)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read device package id (code %d)\n", - __func__, retval); - return retval; - } - - rmi->package_id = (pkg_id[1] << 8) | pkg_id[0]; - rmi->package_id_rev = (pkg_id[3] << 8) | pkg_id[2]; - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET, - rmi->build_id, - sizeof(rmi->build_id)); - if (retval < 0) - return retval; - - rmi4_data->firmware_id = (unsigned int)rmi->build_id[0] + - (unsigned int)rmi->build_id[1] * 0x100 + - (unsigned int)rmi->build_id[2] * 0x10000; - - memset(rmi4_data->intr_mask, 0x00, sizeof(rmi4_data->intr_mask)); - - /* - * Map out the interrupt bit masks for the interrupt sources - * from the registered function handlers. - */ - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->num_of_data_sources) { - rmi4_data->intr_mask[fhandler->intr_reg_num] |= - fhandler->intr_mask; - } - } - } - - /* Enable the interrupt sources */ - for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) { - if (rmi4_data->intr_mask[ii] != 0x00) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Interrupt enable mask %d = 0x%02x\n", - __func__, ii, rmi4_data->intr_mask[ii]); - intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii; - retval = synaptics_rmi4_reg_write(rmi4_data, - intr_addr, - &(rmi4_data->intr_mask[ii]), - sizeof(rmi4_data->intr_mask[ii])); - if (retval < 0) - return retval; - } - } - - synaptics_rmi4_set_configured(rmi4_data); - - return 0; -} - -static void synaptics_rmi4_set_params(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char ii; - struct synaptics_rmi4_f1a_handle *f1a; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_device_info *rmi; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - rmi = &(rmi4_data->rmi4_mod_info); - - if (bdata->disp_maxx && bdata->disp_maxy) { - input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_X, - 0, bdata->disp_maxx, 0, 0); - input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_Y, - 0, bdata->disp_maxy, 0, 0); - } else { - input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_X, - 0, rmi4_data->sensor_max_x, 0, 0); - input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_Y, - 0, rmi4_data->sensor_max_y, 0, 0); - } - -#ifdef REPORT_2D_W - input_set_abs_params(rmi4_data->input_dev, - ABS_MT_TOUCH_MAJOR, 0, - rmi4_data->max_touch_width, 0, 0); - input_set_abs_params(rmi4_data->input_dev, - ABS_MT_TOUCH_MINOR, 0, - rmi4_data->max_touch_width, 0, 0); -#endif - -#ifdef TYPE_B_PROTOCOL - input_mt_init_slots(rmi4_data->input_dev, - rmi4_data->num_of_fingers, 0); -#endif - - f1a = NULL; - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) - f1a = fhandler->data; - } - } - - if (f1a) { - for (ii = 0; ii < f1a->valid_button_count; ii++) { - set_bit(f1a->button_map[ii], - rmi4_data->input_dev->keybit); - input_set_capability(rmi4_data->input_dev, - EV_KEY, f1a->button_map[ii]); - } - } - - return; -} - -static int synaptics_dsx_virtual_keys_init(struct device *dev, - struct synaptics_dsx_board_data *rmi4_pdata) -{ - int width, height, center_x, center_y; - int x1 = 0, x2 = 0, i, c = 0, rc = 0, border; - - vkey_buf = devm_kzalloc(dev, MAX_BUF_SIZE, GFP_KERNEL); - if (!vkey_buf) { - dev_err(dev, "Failed to allocate memory\n"); - return -ENOMEM; - } - - border = (rmi4_pdata->panel_maxx - rmi4_pdata->disp_maxx) * 2; - width = ((rmi4_pdata->disp_maxx - - (border * (rmi4_pdata->virtual_key_map->nkeys - 1))) - / rmi4_pdata->virtual_key_map->nkeys); - height = (rmi4_pdata->panel_maxy - rmi4_pdata->disp_maxy); - center_y = rmi4_pdata->disp_maxy + (height / 2); - height = height * HEIGHT_SCALE_NUM / HEIGHT_SCALE_DENOM; - - x2 -= border * BORDER_ADJUST_NUM / BORDER_ADJUST_DENOM; - - for (i = 0; i < rmi4_pdata->virtual_key_map->nkeys; i++) { - x1 = x2 + border; - x2 = x2 + border + width; - center_x = x1 + (x2 - x1) / 2; - c += snprintf(vkey_buf + c, MAX_BUF_SIZE - c, - "%s:%d:%d:%d:%d:%d\n", VKEY_VER_CODE, - rmi4_pdata->virtual_key_map->map[i], - center_x, center_y, width, height); - } - - vkey_buf[c] = '\0'; - - vkey_kobj = kobject_create_and_add("board_properties", NULL); - if (!vkey_kobj) { - dev_err(dev, "unable to create kobject\n"); - return -ENOMEM; - } - - rc = sysfs_create_group(vkey_kobj, &vkey_grp); - if (rc) { - dev_err(dev, "failed to create attributes\n"); - kobject_put(vkey_kobj); - } - - return rc; -} - -static int synaptics_dsx_get_virtual_keys(struct device *dev, - struct property *prop, char *name, - struct synaptics_dsx_board_data *rmi4_pdata, - struct device_node *np) -{ - u32 num_keys; - int rc; - - num_keys = prop->length / sizeof(u32); - - rmi4_pdata->virtual_key_map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->virtual_key_map), - GFP_KERNEL); - if (!rmi4_pdata->virtual_key_map) - return -ENOMEM; - - rmi4_pdata->virtual_key_map->map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->virtual_key_map->map) * - num_keys, GFP_KERNEL); - if (!rmi4_pdata->virtual_key_map->map) - return -ENOMEM; - - rc = of_property_read_u32_array(np, name, - rmi4_pdata->virtual_key_map->map, - num_keys); - if (rc) { - dev_err(dev, "Failed to read key codes\n"); - return -EINVAL; - } - rmi4_pdata->virtual_key_map->nkeys = num_keys; - - return 0; -} - -static int synaptics_dsx_get_button_map(struct device *dev, - struct property *prop, char *name, - struct synaptics_dsx_board_data *rmi4_pdata, - struct device_node *np) -{ - int rc, i; - u32 num_buttons; - u32 button_map[MAX_NUMBER_OF_BUTTONS]; - - num_buttons = prop->length / sizeof(u32); - - rmi4_pdata->cap_button_map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->cap_button_map), - GFP_KERNEL); - if (!rmi4_pdata->cap_button_map) - return -ENOMEM; - - rmi4_pdata->cap_button_map->map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->cap_button_map->map) * - num_buttons, GFP_KERNEL); - if (!rmi4_pdata->cap_button_map->map) - return -ENOMEM; - - if (num_buttons <= MAX_NUMBER_OF_BUTTONS) { - rc = of_property_read_u32_array(np, - name, button_map, num_buttons); - if (rc) { - dev_err(dev, "Unable to read key codes\n"); - return rc; - } - for (i = 0; i < num_buttons; i++) - rmi4_pdata->cap_button_map->map[i] = - button_map[i]; - rmi4_pdata->cap_button_map->nbuttons = num_buttons; - } else { - return -EINVAL; - } - - return 0; -} - -static int synaptics_rmi4_parse_dt_children(struct device *dev, - struct synaptics_dsx_board_data *rmi4_pdata, - struct synaptics_rmi4_data *rmi4_data) -{ - struct synaptics_rmi4_device_info *rmi = &rmi4_data->rmi4_mod_info; - struct device_node *node = dev->of_node, *child = NULL; - int rc = 0; - struct synaptics_rmi4_fn *fhandler = NULL; - struct property *prop; - - for_each_child_of_node(node, child) { - rc = of_property_read_u32(child, "synaptics,package-id", - &rmi4_pdata->package_id); - if (rc && (rc != -EINVAL)) { - dev_err(dev, "Unable to read package_id\n"); - return rc; - } else if (rc == -EINVAL) { - rmi4_pdata->package_id = 0x00; - } - - if (rmi4_pdata->package_id && (rmi4_pdata->package_id != - rmi->package_id)) { - dev_err(dev, - "%s: Synaptics package id don't match %d %d\n", - __func__, - rmi4_pdata->package_id, rmi->package_id); - - /* Iterate over next child if package does not match */ - continue; - } - - rc = synaptics_dsx_get_dt_coords(dev, - "synaptics,display-coords", rmi4_pdata, child); - if (rc && (rc != -EINVAL)) - return rc; - - rc = synaptics_dsx_get_dt_coords(dev, - "synaptics,panel-coords", rmi4_pdata, child); - if (rc && (rc != -EINVAL)) - return rc; - - prop = of_find_property(child, "synaptics,button-map", NULL); - if (prop) { - rc = synaptics_dsx_get_button_map(dev, prop, - "synaptics,button-map", rmi4_pdata, child); - if (rc < 0) { - dev_err(dev, "Unable to read button map\n"); - return rc; - } - - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, - &rmi->support_fn_list, link) { - if (fhandler->fn_number == - SYNAPTICS_RMI4_F1A) - break; - } - } - - if (fhandler && fhandler->fn_number == - SYNAPTICS_RMI4_F1A) { - rc = synaptics_rmi4_f1a_button_map(rmi4_data, - fhandler); - if (rc < 0) { - dev_err(dev, - "Fail to register F1A %d\n", - rc); - return rc; - } - } - } - - prop = of_find_property(child, "synaptics,key-codes", NULL); - if (prop) { - rc = synaptics_dsx_get_virtual_keys(dev, prop, - "synaptics,key-codes", rmi4_pdata, child); - if (!rc) { - synaptics_dsx_virtual_keys_init(dev, - rmi4_pdata); - } else { - dev_err(dev, - "Unable to read virtual key codes\n"); - return rc; - } - } - - break; - } - - return 0; -} - -static int synaptics_rmi4_set_input_dev(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - int temp; - - rmi4_data->input_dev = input_allocate_device(); - if (rmi4_data->input_dev == NULL) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate input device\n", - __func__); - retval = -ENOMEM; - goto err_input_device; - } - - retval = synaptics_rmi4_query_device(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to query device\n", - __func__); - goto err_query_device; - } - - if (rmi4_data->hw_if->board_data->detect_device) { - retval = synaptics_rmi4_parse_dt_children( - rmi4_data->pdev->dev.parent, - rmi4_data->hw_if->board_data, - rmi4_data); - if (retval < 0) - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to parse device tree property\n", - __func__); - } - - rmi4_data->input_dev->name = PLATFORM_DRIVER_NAME; - rmi4_data->input_dev->phys = INPUT_PHYS_NAME; - rmi4_data->input_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; - rmi4_data->input_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; - rmi4_data->input_dev->dev.parent = rmi4_data->pdev->dev.parent; - input_set_drvdata(rmi4_data->input_dev, rmi4_data); - - set_bit(EV_SYN, rmi4_data->input_dev->evbit); - set_bit(EV_KEY, rmi4_data->input_dev->evbit); - set_bit(EV_ABS, rmi4_data->input_dev->evbit); - set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit); - set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit); -#ifdef INPUT_PROP_DIRECT - set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit); -#endif - - if (rmi4_data->hw_if->board_data->swap_axes) { - temp = rmi4_data->sensor_max_x; - rmi4_data->sensor_max_x = rmi4_data->sensor_max_y; - rmi4_data->sensor_max_y = temp; - } - - synaptics_rmi4_set_params(rmi4_data); - - retval = input_register_device(rmi4_data->input_dev); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to register input device\n", - __func__); - goto err_register_input; - } - - return 0; - -err_register_input: -err_query_device: - synaptics_rmi4_empty_fn_list(rmi4_data); - input_free_device(rmi4_data->input_dev); - -err_input_device: - return retval; -} - -static int synaptics_rmi4_set_gpio(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - int power_on; - int reset_on; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - power_on = bdata->power_on_state; - reset_on = bdata->reset_on_state; - - retval = bdata->gpio_config( - bdata->irq_gpio, - true, 0, 0); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to configure attention GPIO\n", - __func__); - goto err_gpio_irq; - } - - if (bdata->power_gpio >= 0) { - retval = bdata->gpio_config( - bdata->power_gpio, - true, 1, !power_on); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to configure power GPIO\n", - __func__); - goto err_gpio_power; - } - } - - if (bdata->reset_gpio >= 0) { - retval = bdata->gpio_config( - bdata->reset_gpio, - true, 1, !reset_on); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to configure reset GPIO\n", - __func__); - goto err_gpio_reset; - } - } - - if (bdata->power_gpio >= 0) { - gpio_set_value(bdata->power_gpio, power_on); - msleep(bdata->power_delay_ms); - } - - if (bdata->reset_gpio >= 0) { - gpio_set_value(bdata->reset_gpio, reset_on); - msleep(bdata->reset_active_ms); - gpio_set_value(bdata->reset_gpio, !reset_on); - msleep(bdata->reset_delay_ms); - } - - return 0; - -err_gpio_reset: - if (bdata->power_gpio >= 0) { - bdata->gpio_config( - bdata->power_gpio, - false, 0, 0); - } - -err_gpio_power: - bdata->gpio_config( - bdata->irq_gpio, - false, 0, 0); - -err_gpio_irq: - return retval; -} - -static int synaptics_dsx_pinctrl_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - - /* Get pinctrl if target uses pinctrl */ - rmi4_data->ts_pinctrl = devm_pinctrl_get((rmi4_data->pdev->dev.parent)); - if (IS_ERR_OR_NULL(rmi4_data->ts_pinctrl)) { - dev_dbg(rmi4_data->pdev->dev.parent, - "Target does not use pinctrl\n"); - retval = PTR_ERR(rmi4_data->ts_pinctrl); - rmi4_data->ts_pinctrl = NULL; - return retval; - } - - rmi4_data->gpio_state_active - = pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_active"); - if (IS_ERR_OR_NULL(rmi4_data->gpio_state_active)) { - dev_dbg(rmi4_data->pdev->dev.parent, - "Can not get ts default pinstate\n"); - retval = PTR_ERR(rmi4_data->gpio_state_active); - rmi4_data->ts_pinctrl = NULL; - return retval; - } - - rmi4_data->gpio_state_suspend - = pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_suspend"); - if (IS_ERR_OR_NULL(rmi4_data->gpio_state_suspend)) { - dev_dbg(rmi4_data->pdev->dev.parent, - "Can not get ts sleep pinstate\n"); - retval = PTR_ERR(rmi4_data->gpio_state_suspend); - rmi4_data->ts_pinctrl = NULL; - return retval; - } - - return 0; -} - -static int synpatics_dsx_pinctrl_select(struct synaptics_rmi4_data *rmi4_data, - bool on) -{ - struct pinctrl_state *pins_state; - int ret; - - pins_state = on ? rmi4_data->gpio_state_active - : rmi4_data->gpio_state_suspend; - if (!IS_ERR_OR_NULL(pins_state)) { - ret = pinctrl_select_state(rmi4_data->ts_pinctrl, pins_state); - if (ret) { - dev_err(rmi4_data->pdev->dev.parent, - "can not set %s pins\n", - on ? "pmx_ts_active" : "pmx_ts_suspend"); - return ret; - } - } else - dev_err(rmi4_data->pdev->dev.parent, - "not a valid '%s' pinstate\n", - on ? "pmx_ts_active" : "pmx_ts_suspend"); - - return 0; -} - -static int synaptics_dsx_gpio_configure(struct synaptics_rmi4_data *rmi4_data, - bool on) -{ - int retval = 0; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - if (on) { - if (gpio_is_valid(bdata->irq_gpio)) { - /* configure touchscreen irq gpio */ - retval = gpio_request(bdata->irq_gpio, - "rmi4_irq_gpio"); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "unable to request gpio [%d]\n", - bdata->irq_gpio); - goto err_irq_gpio_req; - } - retval = gpio_direction_input(bdata->irq_gpio); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "unable to set dir for gpio[%d]\n", - bdata->irq_gpio); - goto err_irq_gpio_dir; - } - } else { - dev_err(rmi4_data->pdev->dev.parent, - "irq gpio not provided\n"); - goto err_irq_gpio_req; - } - - if (gpio_is_valid(bdata->reset_gpio)) { - /* configure touchscreen reset out gpio */ - retval = gpio_request(bdata->reset_gpio, - "rmi4_reset_gpio"); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "unable to request gpio [%d]\n", - bdata->reset_gpio); - goto err_irq_gpio_dir; - } - - retval = gpio_direction_output(bdata->reset_gpio, 1); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "unable to set dir for gpio [%d]\n", - bdata->reset_gpio); - goto err_reset_gpio_dir; - } - - gpio_set_value(bdata->reset_gpio, 1); - msleep(bdata->reset_delay_ms); - } - - return 0; - } else { - if (bdata->disable_gpios) { - if (gpio_is_valid(bdata->irq_gpio)) - gpio_free(bdata->irq_gpio); - if (gpio_is_valid(bdata->reset_gpio)) { - /* - * This is intended to save leakage current - * only. Even if the call(gpio_direction_input) - * fails, only leakage current will be more but - * functionality will not be affected. - */ - retval = gpio_direction_input( - bdata->reset_gpio); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "unable to set direction for gpio " - "[%d]\n", bdata->irq_gpio); - } - gpio_free(bdata->reset_gpio); - } - } - - return 0; - } - -err_reset_gpio_dir: - if (gpio_is_valid(bdata->reset_gpio)) - gpio_free(bdata->reset_gpio); -err_irq_gpio_dir: - if (gpio_is_valid(bdata->irq_gpio)) - gpio_free(bdata->irq_gpio); -err_irq_gpio_req: - return retval; -} - -static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char ii; - -#ifdef TYPE_B_PROTOCOL - for (ii = 0; ii < rmi4_data->num_of_fingers; ii++) { - input_mt_slot(rmi4_data->input_dev, ii); - input_mt_report_slot_state(rmi4_data->input_dev, - MT_TOOL_FINGER, 0); - } -#endif - input_report_key(rmi4_data->input_dev, - BTN_TOUCH, 0); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, 0); -#ifndef TYPE_B_PROTOCOL - input_mt_sync(rmi4_data->input_dev); -#endif - input_sync(rmi4_data->input_dev); - - rmi4_data->fingers_on_2d = false; - - return 0; -} - -static int synaptics_rmi4_reinit_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char ii; - unsigned short intr_addr; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - mutex_lock(&(rmi4_data->rmi4_reset_mutex)); - - synaptics_rmi4_free_fingers(rmi4_data); - - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F12) { - synaptics_rmi4_f12_set_enables(rmi4_data, 0); - break; - } - } - } - - for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) { - if (rmi4_data->intr_mask[ii] != 0x00) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Interrupt enable mask %d = 0x%02x\n", - __func__, ii, rmi4_data->intr_mask[ii]); - intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii; - retval = synaptics_rmi4_reg_write(rmi4_data, - intr_addr, - &(rmi4_data->intr_mask[ii]), - sizeof(rmi4_data->intr_mask[ii])); - if (retval < 0) - goto exit; - } - } - - mutex_lock(&exp_data.mutex); - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) - if (exp_fhandler->exp_fn->reinit != NULL) - exp_fhandler->exp_fn->reinit(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - synaptics_rmi4_set_configured(rmi4_data); - - retval = synaptics_rmi4_query_device(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to query device\n", - __func__); - } - - - retval = 0; - -exit: - mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); - return retval; -} - -static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - int temp; - unsigned char command = 0x01; - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - - mutex_lock(&(rmi4_data->rmi4_reset_mutex)); - - rmi4_data->touch_stopped = true; - - retval = synaptics_rmi4_reg_write(rmi4_data, - rmi4_data->f01_cmd_base_addr, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue reset command, error = %d\n", - __func__, retval); - mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); - return retval; - } - - msleep(rmi4_data->hw_if->board_data->reset_delay_ms); - - synaptics_rmi4_free_fingers(rmi4_data); - - synaptics_rmi4_empty_fn_list(rmi4_data); - - retval = synaptics_rmi4_query_device(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to query device\n", - __func__); - mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); - return retval; - } - - if (rmi4_data->hw_if->board_data->swap_axes) { - temp = rmi4_data->sensor_max_x; - rmi4_data->sensor_max_x = rmi4_data->sensor_max_y; - rmi4_data->sensor_max_y = temp; - } - - synaptics_rmi4_set_params(rmi4_data); - - mutex_lock(&exp_data.mutex); - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) - if (exp_fhandler->exp_fn->reset != NULL) - exp_fhandler->exp_fn->reset(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - rmi4_data->touch_stopped = false; - - mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); - - return 0; -} - -/** -* synaptics_rmi4_exp_fn_work() -* -* Called by the kernel at the scheduled time. -* -* This function is a work thread that checks for the insertion and -* removal of other expansion Function modules such as rmi_dev and calls -* their initialization and removal callback functions accordingly. -*/ -static void synaptics_rmi4_exp_fn_work(struct work_struct *work) -{ - int retval; - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct synaptics_rmi4_exp_fhandler *exp_fhandler_temp; - struct synaptics_rmi4_data *rmi4_data = exp_data.rmi4_data; - - mutex_lock(&exp_data.mutex); - if (!list_empty(&exp_data.list)) { - list_for_each_entry_safe(exp_fhandler, - exp_fhandler_temp, - &exp_data.list, - link) { - if ((exp_fhandler->exp_fn->init != NULL) && - exp_fhandler->insert) { - retval = exp_fhandler->exp_fn->init(rmi4_data); - if (retval < 0) { - list_del(&exp_fhandler->link); - kfree(exp_fhandler); - } else { - exp_fhandler->insert = false; - } - } else if ((exp_fhandler->exp_fn->remove != NULL) && - exp_fhandler->remove) { - exp_fhandler->exp_fn->remove(rmi4_data); - list_del(&exp_fhandler->link); - kfree(exp_fhandler); - } - } - } - mutex_unlock(&exp_data.mutex); - - return; -} - -/** -* synaptics_rmi4_dsx_new_function() -* -* Called by other expansion Function modules in their module init and -* module exit functions. -* -* This function is used by other expansion Function modules such as -* rmi_dev to register themselves with the driver by providing their -* initialization and removal callback function pointers so that they -* can be inserted or removed dynamically at module init and exit times, -* respectively. -*/ -void synaptics_rmi4_dsx_new_function(struct synaptics_rmi4_exp_fn *exp_fn, - bool insert) -{ - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - - if (!exp_data.initialized) { - mutex_init(&exp_data.mutex); - INIT_LIST_HEAD(&exp_data.list); - exp_data.initialized = true; - } - - mutex_lock(&exp_data.mutex); - if (insert) { - exp_fhandler = kzalloc(sizeof(*exp_fhandler), GFP_KERNEL); - if (!exp_fhandler) { - pr_err("%s: Failed to alloc mem for expansion function\n", - __func__); - goto exit; - } - exp_fhandler->exp_fn = exp_fn; - exp_fhandler->insert = true; - exp_fhandler->remove = false; - list_add_tail(&exp_fhandler->link, &exp_data.list); - } else if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) { - if (exp_fhandler->exp_fn->fn_type == exp_fn->fn_type) { - exp_fhandler->insert = false; - exp_fhandler->remove = true; - goto exit; - } - } - } - -exit: - mutex_unlock(&exp_data.mutex); - - if (exp_data.queue_work) { - queue_delayed_work(exp_data.workqueue, - &exp_data.work, - msecs_to_jiffies(EXP_FN_WORK_DELAY_MS)); - } - - return; -} -EXPORT_SYMBOL(synaptics_rmi4_dsx_new_function); - -static int synaptics_dsx_regulator_configure(struct synaptics_rmi4_data - *rmi4_data) -{ - int retval; - rmi4_data->regulator_vdd = regulator_get(rmi4_data->pdev->dev.parent, - "vdd"); - if (IS_ERR(rmi4_data->regulator_vdd)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to get regulator vdd\n", - __func__); - retval = PTR_ERR(rmi4_data->regulator_vdd); - return retval; - } - rmi4_data->regulator_avdd = regulator_get(rmi4_data->pdev->dev.parent, - "avdd"); - if (IS_ERR(rmi4_data->regulator_avdd)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to get regulator avdd\n", - __func__); - retval = PTR_ERR(rmi4_data->regulator_avdd); - regulator_put(rmi4_data->regulator_vdd); - return retval; - } - - return 0; -}; - -static int synaptics_dsx_regulator_enable(struct synaptics_rmi4_data - *rmi4_data, bool on) -{ - int retval; - - if (on) { - retval = regulator_enable(rmi4_data->regulator_vdd); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to enable regulator vdd\n", - __func__); - return retval; - } - retval = regulator_enable(rmi4_data->regulator_avdd); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to enable regulator avdd\n", - __func__); - regulator_disable(rmi4_data->regulator_vdd); - return retval; - } - msleep(rmi4_data->hw_if->board_data->power_delay_ms); - } else { - regulator_disable(rmi4_data->regulator_vdd); - regulator_disable(rmi4_data->regulator_avdd); - } - - return 0; -} - - /** - * synaptics_rmi4_probe() - * - * Called by the kernel when an association with an I2C device of the - * same name is made (after doing i2c_add_driver). - * - * This funtion allocates and initializes the resources for the driver - * as an input driver, turns on the power to the sensor, queries the - * sensor for its supported Functions and characteristics, registers - * the driver to the input subsystem, sets up the interrupt, handles - * the registration of the early_suspend and late_resume functions, - * and creates a work queue for detection of other expansion Function - * modules. - */ -static int synaptics_rmi4_probe(struct platform_device *pdev) -{ - int retval, len; - unsigned char attr_count; - struct synaptics_rmi4_data *rmi4_data; - const struct synaptics_dsx_hw_interface *hw_if; - const struct synaptics_dsx_board_data *bdata; - struct dentry *temp; - - hw_if = pdev->dev.platform_data; - if (!hw_if) { - dev_err(&pdev->dev, - "%s: No hardware interface found\n", - __func__); - return -EINVAL; - } - - bdata = hw_if->board_data; - if (!bdata) { - dev_err(&pdev->dev, - "%s: No board data found\n", - __func__); - return -EINVAL; - } - - rmi4_data = kzalloc(sizeof(*rmi4_data), GFP_KERNEL); - if (!rmi4_data) { - dev_err(&pdev->dev, - "%s: Failed to alloc mem for rmi4_data\n", - __func__); - return -ENOMEM; - } - - rmi4_data->pdev = pdev; - rmi4_data->current_page = MASK_8BIT; - rmi4_data->hw_if = hw_if; - rmi4_data->touch_stopped = false; - rmi4_data->sensor_sleep = false; - rmi4_data->irq_enabled = false; - rmi4_data->fw_updating = false; - rmi4_data->fingers_on_2d = false; - - rmi4_data->irq_enable = synaptics_rmi4_irq_enable; - rmi4_data->reset_device = synaptics_rmi4_reset_device; - - mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex)); - mutex_init(&(rmi4_data->rmi4_reset_mutex)); - - retval = synaptics_dsx_regulator_configure(rmi4_data); - if (retval) { - dev_err(&pdev->dev, - "%s: regulator configuration failed\n", __func__); - goto err_regulator_configure; - } - retval = synaptics_dsx_regulator_enable(rmi4_data, true); - if (retval) { - dev_err(&pdev->dev, - "%s: regulator enable failed\n", __func__); - goto err_regulator_enable; - } - - platform_set_drvdata(pdev, rmi4_data); - - if (bdata->gpio_config) { - retval = synaptics_rmi4_set_gpio(rmi4_data); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to set up GPIO's\n", - __func__); - goto err_set_gpio; - } - } else { - retval = synaptics_dsx_pinctrl_init(rmi4_data); - if (!retval && rmi4_data->ts_pinctrl) { - retval = synpatics_dsx_pinctrl_select(rmi4_data, true); - if (retval < 0) - goto err_set_gpio; - } - - retval = synaptics_dsx_gpio_configure(rmi4_data, true); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to set up GPIO's\n", - __func__); - goto err_config_gpio; - } - } - - if (bdata->fw_name) { - len = strlen(bdata->fw_name); - if (len > SYNA_FW_NAME_MAX_LEN - 1) { - dev_err(&pdev->dev, "Invalid firmware name\n"); - goto err_set_input_dev; - } - - strlcpy(rmi4_data->fw_name, bdata->fw_name, len + 1); - } - - retval = synaptics_rmi4_set_input_dev(rmi4_data); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to set up input device\n", - __func__); - goto err_set_input_dev; - } - -#ifdef CONFIG_FB - rmi4_data->fb_notif.notifier_call = fb_notifier_callback; - - retval = fb_register_client(&rmi4_data->fb_notif); - if (retval) - dev_err(rmi4_data->pdev->dev.parent, - "Unable to register fb_notifier: %d\n", retval); -#elif defined(CONFIG_HAS_EARLYSUSPEND) - rmi4_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - rmi4_data->early_suspend.suspend = synaptics_rmi4_early_suspend; - rmi4_data->early_suspend.resume = synaptics_rmi4_late_resume; - register_early_suspend(&rmi4_data->early_suspend); -#endif - - rmi4_data->irq = gpio_to_irq(bdata->irq_gpio); - - retval = synaptics_rmi4_irq_enable(rmi4_data, true); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to enable attention interrupt\n", - __func__); - goto err_enable_irq; - } - - if (!exp_data.initialized) { - mutex_init(&exp_data.mutex); - INIT_LIST_HEAD(&exp_data.list); - exp_data.initialized = true; - } - - exp_data.workqueue = create_singlethread_workqueue("dsx_exp_workqueue"); - INIT_DELAYED_WORK(&exp_data.work, synaptics_rmi4_exp_fn_work); - exp_data.rmi4_data = rmi4_data; - exp_data.queue_work = true; - queue_delayed_work(exp_data.workqueue, - &exp_data.work, - msecs_to_jiffies(EXP_FN_WORK_DELAY_MS)); - - rmi4_data->dir = debugfs_create_dir(DEBUGFS_DIR_NAME, NULL); - if (rmi4_data->dir == NULL || IS_ERR(rmi4_data->dir)) { - retval = rmi4_data->dir ? PTR_ERR(rmi4_data->dir) : -EIO; - dev_err(&pdev->dev, - "%s: Failed to create debugfs directory, rc = %d\n", - __func__, retval); - goto err_create_debugfs_dir; - } - - temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, rmi4_data->dir, - rmi4_data, &debug_suspend_fops); - if (temp == NULL || IS_ERR(temp)) { - retval = temp ? PTR_ERR(temp) : -EIO; - dev_err(&pdev->dev, - "%s: Failed to create suspend debugfs file, rc = %d\n", - __func__, retval); - goto err_create_debugfs_file; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to create sysfs attributes\n", - __func__); - goto err_sysfs; - } - } - - synaptics_secure_touch_init(rmi4_data); - synaptics_secure_touch_stop(rmi4_data, 1); - - return retval; - -err_sysfs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } -err_create_debugfs_file: - debugfs_remove_recursive(rmi4_data->dir); -err_create_debugfs_dir: - cancel_delayed_work_sync(&exp_data.work); - flush_workqueue(exp_data.workqueue); - destroy_workqueue(exp_data.workqueue); - - synaptics_rmi4_irq_enable(rmi4_data, false); - free_irq(rmi4_data->irq, rmi4_data); - -err_enable_irq: -#if defined(CONFIG_FB) - fb_unregister_client(&rmi4_data->fb_notif); -#elif defined(CONFIG_HAS_EARLYSUSPEND) - unregister_early_suspend(&rmi4_data->early_suspend); -#endif - - synaptics_rmi4_empty_fn_list(rmi4_data); - input_unregister_device(rmi4_data->input_dev); - rmi4_data->input_dev = NULL; - -err_set_input_dev: - if (bdata->gpio_config) { - bdata->gpio_config( - bdata->irq_gpio, - false, 0, 0); - - if (bdata->reset_gpio >= 0) { - bdata->gpio_config( - bdata->reset_gpio, - false, 0, 0); - } - - if (bdata->power_gpio >= 0) { - bdata->gpio_config( - bdata->power_gpio, - false, 0, 0); - } - } else { - synaptics_dsx_gpio_configure(rmi4_data, false); -err_config_gpio: - if (rmi4_data->ts_pinctrl) - synpatics_dsx_pinctrl_select(rmi4_data, false); - } - -err_set_gpio: - regulator_disable(rmi4_data->regulator_vdd); - regulator_disable(rmi4_data->regulator_avdd); -err_regulator_enable: - regulator_put(rmi4_data->regulator_vdd); - regulator_put(rmi4_data->regulator_avdd); -err_regulator_configure: - kfree(rmi4_data); - - return retval; -} - - /** - * synaptics_rmi4_remove() - * - * Called by the kernel when the association with an I2C device of the - * same name is broken (when the driver is unloaded). - * - * This funtion terminates the work queue, stops sensor data acquisition, - * frees the interrupt, unregisters the driver from the input subsystem, - * turns off the power to the sensor, and frees other allocated resources. - */ -static int synaptics_rmi4_remove(struct platform_device *pdev) -{ - unsigned char attr_count; - struct synaptics_rmi4_data *rmi4_data = platform_get_drvdata(pdev); - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - sysfs_remove_group(vkey_kobj, &vkey_grp); - kobject_put(vkey_kobj); - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - debugfs_remove_recursive(rmi4_data->dir); - cancel_delayed_work_sync(&exp_data.work); - flush_workqueue(exp_data.workqueue); - destroy_workqueue(exp_data.workqueue); - - synaptics_rmi4_irq_enable(rmi4_data, false); - -#if defined(CONFIG_FB) - fb_unregister_client(&rmi4_data->fb_notif); -#elif defined(CONFIG_HAS_EARLYSUSPEND) - unregister_early_suspend(&rmi4_data->early_suspend); -#endif - - synaptics_rmi4_empty_fn_list(rmi4_data); - input_unregister_device(rmi4_data->input_dev); - rmi4_data->input_dev = NULL; - - if (bdata->gpio_config) { - bdata->gpio_config( - bdata->irq_gpio, - false, 0, 0); - - if (bdata->reset_gpio >= 0) { - bdata->gpio_config( - bdata->reset_gpio, - false, 0, 0); - } - - if (bdata->power_gpio >= 0) { - bdata->gpio_config( - bdata->power_gpio, - false, 0, 0); - } - } else { - synaptics_dsx_gpio_configure(rmi4_data, false); - if (rmi4_data->ts_pinctrl) - synpatics_dsx_pinctrl_select(rmi4_data, false); - } - - if (rmi4_data->regulator_vdd) { - regulator_disable(rmi4_data->regulator_vdd); - regulator_put(rmi4_data->regulator_vdd); - } - - if (rmi4_data->regulator_avdd) { - regulator_disable(rmi4_data->regulator_avdd); - regulator_put(rmi4_data->regulator_avdd); - } - - kfree(rmi4_data); - - return 0; -} - -#ifdef CONFIG_PM - /** - * synaptics_rmi4_sensor_sleep() - * - * Called by synaptics_rmi4_early_suspend() and synaptics_rmi4_suspend(). - * - * This function stops finger data acquisition and puts the sensor to sleep. - */ -static void synaptics_rmi4_sensor_sleep(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char device_ctrl; - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - &device_ctrl, - sizeof(device_ctrl)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to enter sleep mode\n", - __func__); - rmi4_data->sensor_sleep = false; - return; - } - - device_ctrl = (device_ctrl & ~MASK_3BIT); - device_ctrl = (device_ctrl | NO_SLEEP_OFF | SENSOR_SLEEP); - - retval = synaptics_rmi4_reg_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - &device_ctrl, - sizeof(device_ctrl)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to enter sleep mode\n", - __func__); - rmi4_data->sensor_sleep = false; - return; - } else { - rmi4_data->sensor_sleep = true; - } - - return; -} - - /** - * synaptics_rmi4_sensor_wake() - * - * Called by synaptics_rmi4_resume() and synaptics_rmi4_late_resume(). - * - * This function wakes the sensor from sleep. - */ -static void synaptics_rmi4_sensor_wake(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char device_ctrl; - unsigned char no_sleep_setting = rmi4_data->no_sleep_setting; - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - &device_ctrl, - sizeof(device_ctrl)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wake from sleep mode\n", - __func__); - rmi4_data->sensor_sleep = true; - return; - } - - device_ctrl = (device_ctrl & ~MASK_3BIT); - device_ctrl = (device_ctrl | no_sleep_setting | NORMAL_OPERATION); - - retval = synaptics_rmi4_reg_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - &device_ctrl, - sizeof(device_ctrl)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wake from sleep mode\n", - __func__); - rmi4_data->sensor_sleep = true; - return; - } else { - rmi4_data->sensor_sleep = false; - } - - return; -} - -#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 synaptics_rmi4_data *rmi4_data = - container_of(self, struct synaptics_rmi4_data, fb_notif); - - if (evdata && evdata->data && rmi4_data) { - if (event == FB_EARLY_EVENT_BLANK) - synaptics_secure_touch_stop(rmi4_data, 0); - else if (event == FB_EVENT_BLANK) { - blank = evdata->data; - if (*blank == FB_BLANK_UNBLANK) - synaptics_rmi4_resume( - &(rmi4_data->input_dev->dev)); - else if (*blank == FB_BLANK_POWERDOWN) - synaptics_rmi4_suspend( - &(rmi4_data->input_dev->dev)); - } - } - - return 0; -} -#elif defined(CONFIG_HAS_EARLYSUSPEND) - /** - * synaptics_rmi4_early_suspend() - * - * Called by the kernel during the early suspend phase when the system - * enters suspend. - * - * This function calls synaptics_rmi4_sensor_sleep() to stop finger - * data acquisition and put the sensor to sleep. - */ -static void synaptics_rmi4_early_suspend(struct early_suspend *h) -{ - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct synaptics_rmi4_data *rmi4_data = - container_of(h, struct synaptics_rmi4_data, - early_suspend); - - if (rmi4_data->stay_awake) { - rmi4_data->staying_awake = true; - return; - } else { - rmi4_data->staying_awake = false; - } - - synaptics_secure_touch_stop(rmi4_data, 0); - - rmi4_data->touch_stopped = true; - synaptics_rmi4_irq_enable(rmi4_data, false); - synaptics_rmi4_sensor_sleep(rmi4_data); - synaptics_rmi4_free_fingers(rmi4_data); - - mutex_lock(&exp_data.mutex); - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) - if (exp_fhandler->exp_fn->early_suspend != NULL) - exp_fhandler->exp_fn->early_suspend(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - if (rmi4_data->full_pm_cycle) - synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev)); - - return; -} - - /** - * synaptics_rmi4_late_resume() - * - * Called by the kernel during the late resume phase when the system - * wakes up from suspend. - * - * This function goes through the sensor wake process if the system wakes - * up from early suspend (without going into suspend). - */ -static void synaptics_rmi4_late_resume(struct early_suspend *h) -{ - int retval; - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct synaptics_rmi4_data *rmi4_data = - container_of(h, struct synaptics_rmi4_data, - early_suspend); - - if (rmi4_data->staying_awake) - return; - - synaptics_secure_touch_stop(rmi4_data, 0); - - if (rmi4_data->full_pm_cycle) - synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); - - if (rmi4_data->sensor_sleep == true) { - synaptics_rmi4_sensor_wake(rmi4_data); - synaptics_rmi4_irq_enable(rmi4_data, true); - retval = synaptics_rmi4_reinit_device(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to reinit device\n", - __func__); - } - } - - mutex_lock(&exp_data.mutex); - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) - if (exp_fhandler->exp_fn->late_resume != NULL) - exp_fhandler->exp_fn->late_resume(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - rmi4_data->touch_stopped = false; - - return; -} -#endif - - /** - * synaptics_rmi4_suspend() - * - * Called by the kernel during the suspend phase when the system - * enters suspend. - * - * This function stops finger data acquisition and puts the sensor to - * sleep (if not already done so during the early suspend phase), - * disables the interrupt, and turns off the power to the sensor. - */ -static int synaptics_rmi4_suspend(struct device *dev) -{ - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - int retval; - - if (rmi4_data->stay_awake) { - rmi4_data->staying_awake = true; - return 0; - } else { - rmi4_data->staying_awake = false; - } - - if (rmi4_data->suspended) { - dev_info(dev, "Already in suspend state\n"); - return 0; - } - - synaptics_secure_touch_stop(rmi4_data, 1); - - if (!rmi4_data->fw_updating) { - if (!rmi4_data->sensor_sleep) { - rmi4_data->touch_stopped = true; - synaptics_rmi4_irq_enable(rmi4_data, false); - synaptics_rmi4_sensor_sleep(rmi4_data); - synaptics_rmi4_free_fingers(rmi4_data); - } - - mutex_lock(&exp_data.mutex); - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) - if (exp_fhandler->exp_fn->suspend != NULL) - exp_fhandler->exp_fn->suspend(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - retval = synaptics_dsx_regulator_enable(rmi4_data, false); - if (retval < 0) { - dev_err(dev, "failed to enter low power mode\n"); - goto err_lpm_regulator; - } - } else { - dev_err(dev, - "Firmware updating, cannot go into suspend mode\n"); - return 0; - } - - if (bdata->disable_gpios) { - if (rmi4_data->ts_pinctrl) { - retval = synpatics_dsx_pinctrl_select(rmi4_data, - false); - if (retval < 0) { - dev_err(dev, "Cannot get idle pinctrl state\n"); - goto err_pinctrl_select_suspend; - } - } - - retval = synaptics_dsx_gpio_configure(rmi4_data, false); - if (retval < 0) { - dev_err(dev, "failed to put gpios in suspend state\n"); - goto err_gpio_configure; - } - } - - rmi4_data->suspended = true; - - return 0; - -err_gpio_configure: - if (rmi4_data->ts_pinctrl) { - retval = synpatics_dsx_pinctrl_select(rmi4_data, true); - if (retval < 0) - dev_err(dev, "Cannot get default pinctrl state\n"); - } -err_pinctrl_select_suspend: - synaptics_dsx_regulator_enable(rmi4_data, true); -err_lpm_regulator: - if (rmi4_data->sensor_sleep) { - synaptics_rmi4_sensor_wake(rmi4_data); - synaptics_rmi4_irq_enable(rmi4_data, true); - rmi4_data->touch_stopped = false; - } - - return retval; -} - - /** - * synaptics_rmi4_resume() - * - * Called by the kernel during the resume phase when the system - * wakes up from suspend. - * - * This function turns on the power to the sensor, wakes the sensor - * from sleep, enables the interrupt, and starts finger data - * acquisition. - */ -static int synaptics_rmi4_resume(struct device *dev) -{ - int retval; - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - if (rmi4_data->staying_awake) - return 0; - - if (!rmi4_data->suspended) - return 0; - - synaptics_secure_touch_stop(rmi4_data, 1); - - synaptics_dsx_regulator_enable(rmi4_data, true); - - if (bdata->disable_gpios) { - if (rmi4_data->ts_pinctrl) { - retval = synpatics_dsx_pinctrl_select(rmi4_data, true); - if (retval < 0) - dev_err(dev, "Cannot get default pinctrl state\n"); - } - - retval = synaptics_dsx_gpio_configure(rmi4_data, true); - if (retval < 0) - dev_err(dev, "Failed to put gpios in active state\n"); - } - - synaptics_rmi4_sensor_wake(rmi4_data); - synaptics_rmi4_irq_enable(rmi4_data, true); - retval = synaptics_rmi4_reinit_device(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to reinit device\n", - __func__); - return retval; - } - - mutex_lock(&exp_data.mutex); - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) - if (exp_fhandler->exp_fn->resume != NULL) - exp_fhandler->exp_fn->resume(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - rmi4_data->touch_stopped = false; - rmi4_data->suspended = false; - - return 0; -} - -static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = { - .suspend = synaptics_rmi4_suspend, - .resume = synaptics_rmi4_resume, -}; -#else -static int synaptics_rmi4_suspend(struct device *dev) -{ - dev_err(dev, "PM not supported\n"); - return -EINVAL; -} - -static int synaptics_rmi4_resume(struct device *dev) -{ - dev_err(dev, "PM not supported\n"); - return -EINVAL; -} -#endif - -static struct platform_driver synaptics_rmi4_driver = { - .driver = { - .name = PLATFORM_DRIVER_NAME, - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &synaptics_rmi4_dev_pm_ops, -#endif - }, - .probe = synaptics_rmi4_probe, - .remove = synaptics_rmi4_remove, -}; - - /** - * synaptics_rmi4_init() - * - * Called by the kernel during do_initcalls (if built-in) - * or when the driver is loaded (if a module). - * - * This function registers the driver to the I2C subsystem. - * - */ -static int __init synaptics_rmi4_init(void) -{ - int retval; - - retval = synaptics_rmi4_bus_init(); - if (retval) - return retval; - - return platform_driver_register(&synaptics_rmi4_driver); -} - - /** - * synaptics_rmi4_exit() - * - * Called by the kernel when the driver is unloaded. - * - * This funtion unregisters the driver from the I2C subsystem. - * - */ -static void __exit synaptics_rmi4_exit(void) -{ - platform_driver_unregister(&synaptics_rmi4_driver); - - synaptics_rmi4_bus_exit(); - - return; -} - -module_init(synaptics_rmi4_init); -module_exit(synaptics_rmi4_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX I2C Touch Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.h b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.h deleted file mode 100644 index 47bc322cd35e..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * Copyright (c) 2014, 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. - */ -#ifndef _SYNAPTICS_DSX_RMI4_H_ -#define _SYNAPTICS_DSX_RMI4_H_ - -#define SYNAPTICS_DS4 (1 << 0) -#define SYNAPTICS_DS5 (1 << 1) -#define SYNAPTICS_DSX_DRIVER_PRODUCT (SYNAPTICS_DS4 | SYNAPTICS_DS5) -#define SYNAPTICS_DSX_DRIVER_VERSION 0x2001 - -#include <linux/version.h> -#include <linux/debugfs.h> - -#if defined(CONFIG_FB) -#include <linux/notifier.h> -#include <linux/fb.h> -#elif defined(CONFIG_HAS_EARLYSUSPEND) -#include <linux/earlysuspend.h> -#endif -#if defined(CONFIG_SECURE_TOUCH) -#include <linux/completion.h> -#include <linux/atomic.h> -#endif - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)) -#define KERNEL_ABOVE_2_6_38 -#endif - -#ifdef KERNEL_ABOVE_2_6_38 -#define sstrtoul(...) kstrtoul(__VA_ARGS__) -#else -#define sstrtoul(...) strict_strtoul(__VA_ARGS__) -#endif - -#define PDT_PROPS (0X00EF) -#define PDT_START (0x00E9) -#define PDT_END (0x00D0) -#define PDT_ENTRY_SIZE (0x0006) -#define PAGES_TO_SERVICE (10) -#define PAGE_SELECT_LEN (2) -#define ADDRESS_WORD_LEN (2) - -#define SYNAPTICS_RMI4_F01 (0x01) -#define SYNAPTICS_RMI4_F11 (0x11) -#define SYNAPTICS_RMI4_F12 (0x12) -#define SYNAPTICS_RMI4_F1A (0x1a) -#define SYNAPTICS_RMI4_F34 (0x34) -#define SYNAPTICS_RMI4_F51 (0x51) -#define SYNAPTICS_RMI4_F54 (0x54) -#define SYNAPTICS_RMI4_F55 (0x55) - -#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2 -#define SYNAPTICS_RMI4_DATE_CODE_SIZE 3 -#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10 -#define SYNAPTICS_RMI4_BUILD_ID_SIZE 3 - -#define F01_PACKAGE_ID_OFFSET 17 -#define PACKAGE_ID_SIZE 4 - -#define F12_FINGERS_TO_SUPPORT 10 -#define F12_NO_OBJECT_STATUS 0x00 -#define F12_FINGER_STATUS 0x01 -#define F12_STYLUS_STATUS 0x02 -#define F12_PALM_STATUS 0x03 -#define F12_HOVERING_FINGER_STATUS 0x05 -#define F12_GLOVED_FINGER_STATUS 0x06 - -#define MAX_NUMBER_OF_BUTTONS 4 -#define MAX_INTR_REGISTERS 4 - -#define MASK_16BIT 0xFFFF -#define MASK_8BIT 0xFF -#define MASK_7BIT 0x7F -#define MASK_6BIT 0x3F -#define MASK_5BIT 0x1F -#define MASK_4BIT 0x0F -#define MASK_3BIT 0x07 -#define MASK_2BIT 0x03 -#define MASK_1BIT 0x01 - -#define SYNA_FW_NAME_MAX_LEN 50 - -enum exp_fn { - RMI_DEV = 0, - RMI_F54, - RMI_FW_UPDATER, - RMI_PROXIMITY, - RMI_ACTIVE_PEN, - RMI_LAST, -}; - -struct synaptics_dsx_hw_interface { - struct synaptics_dsx_board_data *board_data; - const struct synaptics_dsx_bus_access *bus_access; -}; - -/* - * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT - * @query_base_addr: base address for query registers - * @cmd_base_addr: base address for command registers - * @ctrl_base_addr: base address for control registers - * @data_base_addr: base address for data registers - * @intr_src_count: number of interrupt sources - * @fn_number: function number - */ -struct synaptics_rmi4_fn_desc { - unsigned char query_base_addr; - unsigned char cmd_base_addr; - unsigned char ctrl_base_addr; - unsigned char data_base_addr; - unsigned char intr_src_count; - unsigned char fn_number; -}; - -/* - * synaptics_rmi4_fn_full_addr - full 16-bit base addresses - * @query_base: 16-bit base address for query registers - * @cmd_base: 16-bit base address for data registers - * @ctrl_base: 16-bit base address for command registers - * @data_base: 16-bit base address for control registers - */ -struct synaptics_rmi4_fn_full_addr { - unsigned short query_base; - unsigned short cmd_base; - unsigned short ctrl_base; - unsigned short data_base; -}; - -struct synaptics_rmi4_f12_extra_data { - unsigned char data1_offset; - unsigned char data15_offset; - unsigned char data15_size; - unsigned char data15_data[(F12_FINGERS_TO_SUPPORT + 7) / 8]; -}; - -/* - * struct synaptics_rmi4_fn - function handler data structure - * @fn_number: function number - * @num_of_data_sources: number of data sources - * @num_of_data_points: maximum number of fingers supported - * @size_of_data_register_block: data register block size - * @intr_reg_num: index to associated interrupt register - * @intr_mask: interrupt mask - * @full_addr: full 16-bit base addresses of function registers - * @link: linked list for function handlers - * @data_size: size of private data - * @data: pointer to private data - */ -struct synaptics_rmi4_fn { - unsigned char fn_number; - unsigned char num_of_data_sources; - unsigned char num_of_data_points; - unsigned char size_of_data_register_block; - unsigned char intr_reg_num; - unsigned char intr_mask; - struct synaptics_rmi4_fn_full_addr full_addr; - struct list_head link; - int data_size; - void *data; - void *extra; -}; - -/* - * struct synaptics_rmi4_device_info - device information - * @version_major: rmi protocol major version number - * @version_minor: rmi protocol minor version number - * @manufacturer_id: manufacturer id - * @product_props: product properties information - * @product_info: product info array - * @date_code: device manufacture date - * @tester_id: tester id array - * @serial_number: device serial number - * @product_id_string: device product id - * @support_fn_list: linked list for function handlers - */ -struct synaptics_rmi4_device_info { - unsigned int version_major; - unsigned int version_minor; - unsigned char manufacturer_id; - unsigned char product_props; - unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; - unsigned char date_code[SYNAPTICS_RMI4_DATE_CODE_SIZE]; - unsigned short tester_id; - unsigned short serial_number; - unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; - unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE]; - struct list_head support_fn_list; - unsigned int package_id; - unsigned int package_id_rev; -}; - -/* - * struct synaptics_rmi4_data - rmi4 device instance data - * @pdev: pointer to platform device - * @input_dev: pointer to associated input device - * @hw_if: pointer to hardware interface data - * @rmi4_mod_info: device information - * @regulator_vdd: pointer to associated vdd regulator - * @regulator_add: pointer to associated avdd regulator - * @rmi4_io_ctrl_mutex: mutex for i2c i/o control - * @early_suspend: instance to support early suspend power management - * @current_page: current page in sensor to acess - * @button_0d_enabled: flag for 0d button support - * @full_pm_cycle: flag for full power management cycle in early suspend stage - * @num_of_intr_regs: number of interrupt registers - * @f01_query_base_addr: query base address for f01 - * @f01_cmd_base_addr: command base address for f01 - * @f01_ctrl_base_addr: control base address for f01 - * @f01_data_base_addr: data base address for f01 - * @irq: attention interrupt - * @sensor_max_x: sensor maximum x value - * @sensor_max_y: sensor maximum y value - * @irq_enabled: flag for indicating interrupt enable status - * @fingers_on_2d: flag to indicate presence of fingers in 2d area - * @sensor_sleep: flag to indicate sleep state of sensor - * @wait: wait queue for touch data polling in interrupt thread - * @irq_enable: pointer to irq enable function - */ -struct synaptics_rmi4_data { - struct platform_device *pdev; - struct input_dev *input_dev; - const struct synaptics_dsx_hw_interface *hw_if; - struct synaptics_rmi4_device_info rmi4_mod_info; - struct regulator *regulator_vdd; - struct regulator *regulator_avdd; - struct mutex rmi4_reset_mutex; - struct mutex rmi4_io_ctrl_mutex; -#if defined(CONFIG_FB) - struct notifier_block fb_notif; -#elif defined(CONFIG_HAS_EARLYSUSPEND) - struct early_suspend early_suspend; -#endif - struct dentry *dir; - unsigned char current_page; - unsigned char button_0d_enabled; - unsigned char full_pm_cycle; - unsigned char num_of_rx; - unsigned char num_of_tx; - unsigned char num_of_fingers; - unsigned char max_touch_width; - unsigned char report_enable; - unsigned char no_sleep_setting; - unsigned char intr_mask[MAX_INTR_REGISTERS]; - unsigned char *button_txrx_mapping; - unsigned short num_of_intr_regs; - unsigned short f01_query_base_addr; - unsigned short f01_cmd_base_addr; - unsigned short f01_ctrl_base_addr; - unsigned short f01_data_base_addr; - unsigned int firmware_id; - int irq; - int sensor_max_x; - int sensor_max_y; - bool flash_prog_mode; - bool irq_enabled; - bool touch_stopped; - bool fingers_on_2d; - bool sensor_sleep; - bool stay_awake; - bool staying_awake; - bool fw_updating; - int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable); - int (*reset_device)(struct synaptics_rmi4_data *rmi4_data); - - struct pinctrl *ts_pinctrl; - struct pinctrl_state *gpio_state_active; - struct pinctrl_state *gpio_state_suspend; - char fw_name[SYNA_FW_NAME_MAX_LEN]; - bool suspended; -#if defined(CONFIG_SECURE_TOUCH) - atomic_t st_enabled; - atomic_t st_pending_irqs; - struct completion st_powerdown; - struct completion st_irq_processed; -#endif -}; - -struct synaptics_dsx_bus_access { - unsigned char type; - int (*read)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, - unsigned char *data, unsigned short length); - int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, - unsigned char *data, unsigned short length); -#if defined(CONFIG_SECURE_TOUCH) - int (*get)(struct synaptics_rmi4_data *rmi4_data); - void (*put)(struct synaptics_rmi4_data *rmi4_data); -#endif -}; - -struct synaptics_rmi4_exp_fn { - enum exp_fn fn_type; - int (*init)(struct synaptics_rmi4_data *rmi4_data); - void (*remove)(struct synaptics_rmi4_data *rmi4_data); - void (*reset)(struct synaptics_rmi4_data *rmi4_data); - void (*reinit)(struct synaptics_rmi4_data *rmi4_data); - void (*early_suspend)(struct synaptics_rmi4_data *rmi4_data); - void (*suspend)(struct synaptics_rmi4_data *rmi4_data); - void (*resume)(struct synaptics_rmi4_data *rmi4_data); - void (*late_resume)(struct synaptics_rmi4_data *rmi4_data); - void (*attn)(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask); -}; - -int synaptics_rmi4_bus_init(void); - -void synaptics_rmi4_bus_exit(void); - -void synaptics_rmi4_dsx_new_function(struct synaptics_rmi4_exp_fn *exp_fn_mod, - bool insert); - -int synaptics_dsx_fw_updater(unsigned char *fw_data); - -int synaptics_dsx_get_dt_coords(struct device *dev, char *name, - struct synaptics_dsx_board_data *pdata, - struct device_node *node); - -static inline int synaptics_rmi4_reg_read( - struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, - unsigned char *data, - unsigned short len) -{ - return rmi4_data->hw_if->bus_access->read(rmi4_data, addr, data, len); -} - -static inline int synaptics_rmi4_reg_write( - struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, - unsigned char *data, - unsigned short len) -{ - return rmi4_data->hw_if->bus_access->write(rmi4_data, addr, data, len); -} - -#if defined(CONFIG_SECURE_TOUCH) -static inline int synaptics_rmi4_bus_get(struct synaptics_rmi4_data *rmi4_data) -{ - return rmi4_data->hw_if->bus_access->get(rmi4_data); -} -static inline void synaptics_rmi4_bus_put(struct synaptics_rmi4_data *rmi4_data) -{ - rmi4_data->hw_if->bus_access->put(rmi4_data); -} -#endif - -static inline ssize_t synaptics_rmi4_store_error(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - dev_warn(dev, "%s Attempted to write to read-only attribute %s\n", - __func__, attr->attr.name); - return -EPERM; -} - -static inline void batohs(unsigned short *dest, unsigned char *src) -{ - *dest = src[1] * 0x100 + src[0]; -} - -static inline void hstoba(unsigned char *dest, unsigned short src) -{ - dest[0] = src % 0x100; - dest[1] = src / 0x100; -} -#endif diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c deleted file mode 100644 index 2d0b69b46256..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c +++ /dev/null @@ -1,1978 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/firmware.h> -#include <linux/platform_device.h> -#include <linux/input/synaptics_dsx_v2.h> -#include "synaptics_dsx_core.h" - -#define STARTUP_FW_UPDATE_DELAY_MS 1000 /* ms */ -#define FORCE_UPDATE false -#define DO_LOCKDOWN false - -#define MAX_IMAGE_NAME_LEN 256 -#define MAX_FIRMWARE_ID_LEN 10 - -#define LOCKDOWN_OFFSET 0xb0 -#define FW_IMAGE_OFFSET 0x100 - -#define BOOTLOADER_ID_OFFSET 0 -#define BLOCK_NUMBER_OFFSET 0 - -#define V5_PROPERTIES_OFFSET 2 -#define V5_BLOCK_SIZE_OFFSET 3 -#define V5_BLOCK_COUNT_OFFSET 5 -#define V5_BLOCK_DATA_OFFSET 2 - -#define V6_PROPERTIES_OFFSET 1 -#define V6_BLOCK_SIZE_OFFSET 2 -#define V6_BLOCK_COUNT_OFFSET 3 -#define V6_BLOCK_DATA_OFFSET 1 -#define V6_FLASH_COMMAND_OFFSET 2 -#define V6_FLASH_STATUS_OFFSET 3 - -#define LOCKDOWN_BLOCK_COUNT 5 - -#define REG_MAP (1 << 0) -#define UNLOCKED (1 << 1) -#define HAS_CONFIG_ID (1 << 2) -#define HAS_PERM_CONFIG (1 << 3) -#define HAS_BL_CONFIG (1 << 4) -#define HAS_DISP_CONFIG (1 << 5) -#define HAS_CTRL1 (1 << 6) - -#define UI_CONFIG_AREA 0x00 -#define PERM_CONFIG_AREA 0x01 -#define BL_CONFIG_AREA 0x02 -#define DISP_CONFIG_AREA 0x03 - -#define CMD_WRITE_FW_BLOCK 0x2 -#define CMD_ERASE_ALL 0x3 -#define CMD_WRITE_LOCKDOWN_BLOCK 0x4 -#define CMD_READ_CONFIG_BLOCK 0x5 -#define CMD_WRITE_CONFIG_BLOCK 0x6 -#define CMD_ERASE_CONFIG 0x7 -#define CMD_ERASE_BL_CONFIG 0x9 -#define CMD_ERASE_DISP_CONFIG 0xa -#define CMD_ENABLE_FLASH_PROG 0xf - -#define SLEEP_MODE_NORMAL (0x00) -#define SLEEP_MODE_SENSOR_SLEEP (0x01) -#define SLEEP_MODE_RESERVED0 (0x02) -#define SLEEP_MODE_RESERVED1 (0x03) - -#define ENABLE_WAIT_MS (1 * 1000) -#define WRITE_WAIT_MS (3 * 1000) -#define ERASE_WAIT_MS (5 * 1000) - -#define MIN_SLEEP_TIME_US 50 -#define MAX_SLEEP_TIME_US 100 - -static ssize_t fwu_sysfs_show_image(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t fwu_sysfs_store_image(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t fwu_sysfs_force_reflash_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t fwu_sysfs_write_config_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t fwu_sysfs_read_config_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t fwu_sysfs_config_area_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t fwu_sysfs_image_name_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_image_name_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t fwu_sysfs_image_size_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t fwu_sysfs_block_size_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_config_id_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_package_id_show(struct device *dev, - struct device_attribute *attr, char *buf); - -enum bl_version { - V5 = 5, - V6 = 6, -}; - -enum flash_area { - NONE, - UI_FIRMWARE, - CONFIG_AREA, -}; - -enum update_mode { - NORMAL = 1, - FORCE = 2, - LOCKDOWN = 8, -}; - -struct image_header { - /* 0x00 - 0x0f */ - unsigned char checksum[4]; - unsigned char reserved_04; - unsigned char reserved_05; - unsigned char options_firmware_id:1; - unsigned char options_contain_bootloader:1; - unsigned char options_reserved:6; - unsigned char bootloader_version; - unsigned char firmware_size[4]; - unsigned char config_size[4]; - /* 0x10 - 0x1f */ - unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE]; - unsigned char package_id[2]; - unsigned char package_id_revision[2]; - unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; - /* 0x20 - 0x2f */ - unsigned char reserved_20_2f[16]; - /* 0x30 - 0x3f */ - unsigned char ds_id[16]; - /* 0x40 - 0x4f */ - unsigned char ds_info[10]; - unsigned char reserved_4a_4f[6]; - /* 0x50 - 0x53 */ - unsigned char firmware_id[4]; -}; - -struct image_header_data { - bool contains_firmware_id; - unsigned int firmware_id; - unsigned int checksum; - unsigned int firmware_size; - unsigned int config_size; - unsigned char bootloader_version; - unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; - unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; -}; - -struct pdt_properties { - union { - struct { - unsigned char reserved_1:6; - unsigned char has_bsr:1; - unsigned char reserved_2:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f01_device_status { - union { - struct { - unsigned char status_code:4; - unsigned char reserved:2; - unsigned char flash_prog:1; - unsigned char unconfigured:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f01_device_control { - union { - struct { - unsigned char sleep_mode:2; - unsigned char nosleep:1; - unsigned char reserved:2; - unsigned char charger_connected:1; - unsigned char report_rate:1; - unsigned char configured:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_fwu_handle { - enum bl_version bl_version; - bool initialized; - bool program_enabled; - bool has_perm_config; - bool has_bl_config; - bool has_disp_config; - bool force_update; - bool in_flash_prog_mode; - bool do_lockdown; - unsigned int data_pos; - unsigned int image_size; - unsigned char *image_name; - unsigned char *ext_data_source; - unsigned char *read_config_buf; - unsigned char intr_mask; - unsigned char command; - unsigned char bootloader_id[2]; - unsigned char flash_properties; - unsigned char flash_status; - unsigned char productinfo1; - unsigned char productinfo2; - unsigned char properties_off; - unsigned char blk_size_off; - unsigned char blk_count_off; - unsigned char blk_data_off; - unsigned char flash_cmd_off; - unsigned char flash_status_off; - unsigned short block_size; - unsigned short fw_block_count; - unsigned short config_block_count; - unsigned short lockdown_block_count; - unsigned short perm_config_block_count; - unsigned short bl_config_block_count; - unsigned short disp_config_block_count; - unsigned short config_size; - unsigned short config_area; - char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; - const unsigned char *firmware_data; - const unsigned char *config_data; - const unsigned char *lockdown_data; - struct delayed_work fwu_work; - struct synaptics_rmi4_fn_desc f34_fd; - struct synaptics_rmi4_data *rmi4_data; -}; - -static struct bin_attribute dev_attr_data = { - .attr = { - .name = "data", - .mode = (S_IRUGO | S_IWUSR), - }, - .size = 0, - .read = fwu_sysfs_show_image, - .write = fwu_sysfs_store_image, -}; - - -static struct device_attribute attrs[] = { - __ATTR(force_update_fw, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_force_reflash_store), - __ATTR(update_fw, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_do_reflash_store), - __ATTR(writeconfig, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_write_config_store), - __ATTR(readconfig, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_read_config_store), - __ATTR(configarea, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_config_area_store), - __ATTR(fw_name, S_IRUGO | S_IWUSR | S_IWGRP, - fwu_sysfs_image_name_show, - fwu_sysfs_image_name_store), - __ATTR(imagesize, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_image_size_store), - __ATTR(blocksize, S_IRUGO, - fwu_sysfs_block_size_show, - synaptics_rmi4_store_error), - __ATTR(fwblockcount, S_IRUGO, - fwu_sysfs_firmware_block_count_show, - synaptics_rmi4_store_error), - __ATTR(configblockcount, S_IRUGO, - fwu_sysfs_configuration_block_count_show, - synaptics_rmi4_store_error), - __ATTR(permconfigblockcount, S_IRUGO, - fwu_sysfs_perm_config_block_count_show, - synaptics_rmi4_store_error), - __ATTR(blconfigblockcount, S_IRUGO, - fwu_sysfs_bl_config_block_count_show, - synaptics_rmi4_store_error), - __ATTR(dispconfigblockcount, S_IRUGO, - fwu_sysfs_disp_config_block_count_show, - synaptics_rmi4_store_error), - __ATTR(config_id, S_IRUGO, - fwu_sysfs_config_id_show, - synaptics_rmi4_store_error), - __ATTR(package_id, S_IRUGO, - fwu_sysfs_package_id_show, - synaptics_rmi4_store_error), -}; - -static struct synaptics_rmi4_fwu_handle *fwu; - -DECLARE_COMPLETION(fwu_dsx_remove_complete); - -static unsigned int extract_uint_le(const unsigned char *ptr) -{ - return (unsigned int)ptr[0] + - (unsigned int)ptr[1] * 0x100 + - (unsigned int)ptr[2] * 0x10000 + - (unsigned int)ptr[3] * 0x1000000; -} - -static unsigned int extract_uint_be(const unsigned char *ptr) -{ - return (unsigned int)ptr[3] + - (unsigned int)ptr[2] * 0x100 + - (unsigned int)ptr[1] * 0x10000 + - (unsigned int)ptr[0] * 0x1000000; -} - -static void parse_header(struct image_header_data *header, - const unsigned char *fw_image) -{ - struct image_header *data = (struct image_header *)fw_image; - - header->checksum = extract_uint_le(data->checksum); - - header->bootloader_version = data->bootloader_version; - - header->firmware_size = extract_uint_le(data->firmware_size); - - header->config_size = extract_uint_le(data->config_size); - - memcpy(header->product_id, data->product_id, sizeof(data->product_id)); - header->product_id[sizeof(data->product_id)] = 0; - - memcpy(header->product_info, data->product_info, - sizeof(data->product_info)); - - header->contains_firmware_id = data->options_firmware_id; - if (header->contains_firmware_id) - header->firmware_id = extract_uint_le(data->firmware_id); - - return; -} - -static int fwu_read_f01_device_status(struct f01_device_status *status) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr, - status->data, - sizeof(status->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read F01 device status\n", - __func__); - return retval; - } - - return 0; -} - -static int fwu_read_f34_queries(void) -{ - int retval; - unsigned char count; - unsigned char buf[10]; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.query_base_addr + BOOTLOADER_ID_OFFSET, - fwu->bootloader_id, - sizeof(fwu->bootloader_id)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read bootloader ID\n", - __func__); - return retval; - } - - if (fwu->bootloader_id[1] == '5') { - fwu->bl_version = V5; - } else if (fwu->bootloader_id[1] == '6') { - fwu->bl_version = V6; - } else { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Unrecognized bootloader version\n", - __func__); - return -EINVAL; - } - - if (fwu->bl_version == V5) { - fwu->properties_off = V5_PROPERTIES_OFFSET; - fwu->blk_size_off = V5_BLOCK_SIZE_OFFSET; - fwu->blk_count_off = V5_BLOCK_COUNT_OFFSET; - fwu->blk_data_off = V5_BLOCK_DATA_OFFSET; - } else if (fwu->bl_version == V6) { - fwu->properties_off = V6_PROPERTIES_OFFSET; - fwu->blk_size_off = V6_BLOCK_SIZE_OFFSET; - fwu->blk_count_off = V6_BLOCK_COUNT_OFFSET; - fwu->blk_data_off = V6_BLOCK_DATA_OFFSET; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.query_base_addr + fwu->properties_off, - &fwu->flash_properties, - sizeof(fwu->flash_properties)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read flash properties\n", - __func__); - return retval; - } - - count = 4; - - if (fwu->flash_properties & HAS_PERM_CONFIG) { - fwu->has_perm_config = 1; - count += 2; - } - - if (fwu->flash_properties & HAS_BL_CONFIG) { - fwu->has_bl_config = 1; - count += 2; - } - - if (fwu->flash_properties & HAS_DISP_CONFIG) { - fwu->has_disp_config = 1; - count += 2; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.query_base_addr + fwu->blk_size_off, - buf, - 2); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read block size info\n", - __func__); - return retval; - } - - batohs(&fwu->block_size, &(buf[0])); - - if (fwu->bl_version == V5) { - fwu->flash_cmd_off = fwu->blk_data_off + fwu->block_size; - fwu->flash_status_off = fwu->flash_cmd_off; - } else if (fwu->bl_version == V6) { - fwu->flash_cmd_off = V6_FLASH_COMMAND_OFFSET; - fwu->flash_status_off = V6_FLASH_STATUS_OFFSET; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.query_base_addr + fwu->blk_count_off, - buf, - count); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read block count info\n", - __func__); - return retval; - } - - batohs(&fwu->fw_block_count, &(buf[0])); - batohs(&fwu->config_block_count, &(buf[2])); - - count = 4; - - if (fwu->has_perm_config) { - batohs(&fwu->perm_config_block_count, &(buf[count])); - count += 2; - } - - if (fwu->has_bl_config) { - batohs(&fwu->bl_config_block_count, &(buf[count])); - count += 2; - } - - if (fwu->has_disp_config) - batohs(&fwu->disp_config_block_count, &(buf[count])); - - return 0; -} - -static int fwu_read_f34_flash_status(void) -{ - int retval; - unsigned char status; - unsigned char command; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.data_base_addr + fwu->flash_status_off, - &status, - sizeof(status)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read flash status\n", - __func__); - return retval; - } - - fwu->program_enabled = status >> 7; - - if (fwu->bl_version == V5) - fwu->flash_status = (status >> 4) & MASK_3BIT; - else if (fwu->bl_version == V6) - fwu->flash_status = status & MASK_3BIT; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.data_base_addr + fwu->flash_cmd_off, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read flash command\n", - __func__); - return retval; - } - - fwu->command = command & MASK_4BIT; - - return 0; -} - -static int fwu_write_f34_command(unsigned char cmd) -{ - int retval; - unsigned char command = cmd & MASK_4BIT; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - fwu->command = cmd; - - retval = synaptics_rmi4_reg_write(rmi4_data, - fwu->f34_fd.data_base_addr + fwu->flash_cmd_off, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write command 0x%02x\n", - __func__, command); - return retval; - } - - return 0; -} - -static int fwu_wait_for_idle(int timeout_ms) -{ - int count = 0; - int timeout_count = ((timeout_ms * 1000) / MAX_SLEEP_TIME_US) + 1; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - do { - usleep_range(MIN_SLEEP_TIME_US, MAX_SLEEP_TIME_US); - - count++; - if (count == timeout_count) - fwu_read_f34_flash_status(); - - if ((fwu->command == 0x00) && (fwu->flash_status == 0x00)) - return 0; - } while (count < timeout_count); - - dev_err(rmi4_data->pdev->dev.parent, - "%s: Timed out waiting for idle status\n", - __func__); - - return -ETIMEDOUT; -} - -static enum flash_area fwu_go_nogo(struct image_header_data *header) -{ - int retval; - enum flash_area flash_area = NONE; - unsigned char index = 0; - unsigned char config_id[4]; - unsigned int device_config_id; - unsigned int image_config_id; - unsigned int device_fw_id; - unsigned long image_fw_id; - char *strptr; - char *firmware_id; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (fwu->force_update) { - flash_area = UI_FIRMWARE; - goto exit; - } - - /* Update both UI and config if device is in bootloader mode */ - if (fwu->in_flash_prog_mode) { - flash_area = UI_FIRMWARE; - goto exit; - } - - /* Get device firmware ID */ - device_fw_id = rmi4_data->firmware_id; - dev_info(rmi4_data->pdev->dev.parent, - "%s: Device firmware ID = %d\n", - __func__, device_fw_id); - - /* Get image firmware ID */ - if (header->contains_firmware_id) { - image_fw_id = header->firmware_id; - } else { - strptr = strstr(fwu->image_name, "PR"); - if (!strptr) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: No valid PR number (PRxxxxxxx) " - "found in image file name (%s)\n", - __func__, fwu->image_name); - flash_area = NONE; - goto exit; - } - - strptr += 2; - firmware_id = kzalloc(MAX_FIRMWARE_ID_LEN, GFP_KERNEL); - while (strptr[index] >= '0' && strptr[index] <= '9') { - firmware_id[index] = strptr[index]; - index++; - } - - retval = sstrtoul(firmware_id, 10, &image_fw_id); - kfree(firmware_id); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to obtain image firmware ID\n", - __func__); - flash_area = NONE; - goto exit; - } - } - dev_info(rmi4_data->pdev->dev.parent, - "%s: Image firmware ID = %d\n", - __func__, (unsigned int)image_fw_id); - - if (image_fw_id > device_fw_id) { - flash_area = UI_FIRMWARE; - goto exit; - } else if (image_fw_id < device_fw_id) { - dev_info(rmi4_data->pdev->dev.parent, - "%s: Image firmware ID older than device firmware ID\n", - __func__); - flash_area = NONE; - goto exit; - } - - /* Get device config ID */ - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.ctrl_base_addr, - config_id, - sizeof(config_id)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read device config ID\n", - __func__); - flash_area = NONE; - goto exit; - } - device_config_id = extract_uint_be(config_id); - dev_info(rmi4_data->pdev->dev.parent, - "%s: Device config ID = 0x%02x 0x%02x 0x%02x 0x%02x\n", - __func__, - config_id[0], - config_id[1], - config_id[2], - config_id[3]); - - /* Get image config ID */ - image_config_id = extract_uint_be(fwu->config_data); - dev_info(rmi4_data->pdev->dev.parent, - "%s: Image config ID = 0x%02x 0x%02x 0x%02x 0x%02x\n", - __func__, - fwu->config_data[0], - fwu->config_data[1], - fwu->config_data[2], - fwu->config_data[3]); - - if (image_config_id > device_config_id) { - flash_area = CONFIG_AREA; - goto exit; - } - - flash_area = NONE; - -exit: - if (flash_area == NONE) { - dev_info(rmi4_data->pdev->dev.parent, - "%s: No need to do reflash\n", - __func__); - } else { - dev_info(rmi4_data->pdev->dev.parent, - "%s: Updating %s\n", - __func__, - flash_area == UI_FIRMWARE ? - "UI firmware" : - "config only"); - } - - return flash_area; -} - -static int fwu_scan_pdt(void) -{ - int retval; - unsigned char ii; - unsigned char intr_count = 0; - unsigned char intr_off; - unsigned char intr_src; - unsigned short addr; - bool f01found = false; - bool f34found = false; - struct synaptics_rmi4_fn_desc rmi_fd; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) { - retval = synaptics_rmi4_reg_read(rmi4_data, - addr, - (unsigned char *)&rmi_fd, - sizeof(rmi_fd)); - if (retval < 0) - return retval; - - if (rmi_fd.fn_number) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Found F%02x\n", - __func__, rmi_fd.fn_number); - switch (rmi_fd.fn_number) { - case SYNAPTICS_RMI4_F01: - f01found = true; - - rmi4_data->f01_query_base_addr = - rmi_fd.query_base_addr; - rmi4_data->f01_ctrl_base_addr = - rmi_fd.ctrl_base_addr; - rmi4_data->f01_data_base_addr = - rmi_fd.data_base_addr; - rmi4_data->f01_cmd_base_addr = - rmi_fd.cmd_base_addr; - break; - case SYNAPTICS_RMI4_F34: - f34found = true; - fwu->f34_fd.query_base_addr = - rmi_fd.query_base_addr; - fwu->f34_fd.ctrl_base_addr = - rmi_fd.ctrl_base_addr; - fwu->f34_fd.data_base_addr = - rmi_fd.data_base_addr; - - fwu->intr_mask = 0; - intr_src = rmi_fd.intr_src_count; - intr_off = intr_count % 8; - for (ii = intr_off; - ii < ((intr_src & MASK_3BIT) + - intr_off); - ii++) { - fwu->intr_mask |= 1 << ii; - } - break; - } - } else { - break; - } - - intr_count += (rmi_fd.intr_src_count & MASK_3BIT); - } - - if (!f01found || !f34found) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find both F01 and F34\n", - __func__); - return -EINVAL; - } - - return 0; -} - -static int fwu_write_blocks(unsigned char *block_ptr, unsigned short block_cnt, - unsigned char command) -{ - int retval; - unsigned char block_offset[] = {0, 0}; - unsigned short block_num; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - unsigned int progress; - unsigned char command_str[10]; - - switch (command) { - case CMD_WRITE_CONFIG_BLOCK: - progress = 10; - strlcpy(command_str, "config", 10); - break; - case CMD_WRITE_FW_BLOCK: - progress = 100; - strlcpy(command_str, "firmware", 10); - break; - case CMD_WRITE_LOCKDOWN_BLOCK: - progress = 1; - strlcpy(command_str, "lockdown", 10); - break; - default: - progress = 1; - strlcpy(command_str, "unknown", 10); - break; - } - - block_offset[1] |= (fwu->config_area << 5); - - retval = synaptics_rmi4_reg_write(rmi4_data, - fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET, - block_offset, - sizeof(block_offset)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write to block number registers\n", - __func__); - return retval; - } - - for (block_num = 0; block_num < block_cnt; block_num++) { - if (block_num % progress == 0) - dev_info(rmi4_data->pdev->dev.parent, - "%s: update %s %3d / %3d\n", - __func__, command_str, block_num, block_cnt); - - retval = synaptics_rmi4_reg_write(rmi4_data, - fwu->f34_fd.data_base_addr + fwu->blk_data_off, - block_ptr, - fwu->block_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write block data (block %d)\n", - __func__, block_num); - return retval; - } - - retval = fwu_write_f34_command(command); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write command for block %d\n", - __func__, block_num); - return retval; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wait for idle status (block %d)\n", - __func__, block_num); - return retval; - } - - block_ptr += fwu->block_size; - } - - dev_info(rmi4_data->pdev->dev.parent, - "updated %d/%d blocks\n", block_num, block_cnt); - - return 0; -} - -static int fwu_write_firmware(void) -{ - return fwu_write_blocks((unsigned char *)fwu->firmware_data, - fwu->fw_block_count, CMD_WRITE_FW_BLOCK); -} - -static int fwu_write_configuration(void) -{ - return fwu_write_blocks((unsigned char *)fwu->config_data, - fwu->config_block_count, CMD_WRITE_CONFIG_BLOCK); -} - -static int fwu_write_lockdown(void) -{ - return fwu_write_blocks((unsigned char *)fwu->lockdown_data, - fwu->lockdown_block_count, CMD_WRITE_LOCKDOWN_BLOCK); -} - -static int fwu_write_bootloader_id(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = synaptics_rmi4_reg_write(rmi4_data, - fwu->f34_fd.data_base_addr + fwu->blk_data_off, - fwu->bootloader_id, - sizeof(fwu->bootloader_id)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write bootloader ID\n", - __func__); - return retval; - } - - return 0; -} - -static int fwu_enter_flash_prog(void) -{ - int retval; - struct f01_device_status f01_device_status; - struct f01_device_control f01_device_control; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_write_bootloader_id(); - if (retval < 0) - return retval; - - retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG); - if (retval < 0) - return retval; - - retval = fwu_wait_for_idle(ENABLE_WAIT_MS); - if (retval < 0) - return retval; - - if (!fwu->program_enabled) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Program enabled bit not set\n", - __func__); - return -EINVAL; - } - - retval = fwu_scan_pdt(); - if (retval < 0) - return retval; - - retval = fwu_read_f01_device_status(&f01_device_status); - if (retval < 0) - return retval; - - if (!f01_device_status.flash_prog) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Not in flash prog mode\n", - __func__); - return -EINVAL; - } - - retval = fwu_read_f34_queries(); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - f01_device_control.data, - sizeof(f01_device_control.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read F01 device control\n", - __func__); - return retval; - } - - f01_device_control.nosleep = true; - f01_device_control.sleep_mode = SLEEP_MODE_NORMAL; - - retval = synaptics_rmi4_reg_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - f01_device_control.data, - sizeof(f01_device_control.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write F01 device control\n", - __func__); - return retval; - } - - return retval; -} - -static int fwu_do_reflash(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_enter_flash_prog(); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Entered flash prog mode\n", - __func__); - - retval = fwu_write_bootloader_id(); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Bootloader ID written\n", - __func__); - - retval = fwu_write_f34_command(CMD_ERASE_ALL); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Erase all command written\n", - __func__); - - retval = fwu_wait_for_idle(ERASE_WAIT_MS); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Idle status detected\n", - __func__); - - if (fwu->firmware_data) { - retval = fwu_write_firmware(); - if (retval < 0) - return retval; - pr_notice("%s: Firmware programmed\n", __func__); - } - - if (fwu->config_data) { - retval = fwu_write_configuration(); - if (retval < 0) - return retval; - pr_notice("%s: Configuration programmed\n", __func__); - } - - return retval; -} - -static int fwu_do_write_config(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_enter_flash_prog(); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Entered flash prog mode\n", - __func__); - - if (fwu->config_area == PERM_CONFIG_AREA) { - fwu->config_block_count = fwu->perm_config_block_count; - goto write_config; - } - - retval = fwu_write_bootloader_id(); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Bootloader ID written\n", - __func__); - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_CONFIG); - break; - case BL_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG); - fwu->config_block_count = fwu->bl_config_block_count; - break; - case DISP_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG); - fwu->config_block_count = fwu->disp_config_block_count; - break; - } - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Erase command written\n", - __func__); - - retval = fwu_wait_for_idle(ERASE_WAIT_MS); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Idle status detected\n", - __func__); - -write_config: - retval = fwu_write_configuration(); - if (retval < 0) - return retval; - - pr_notice("%s: Config written\n", __func__); - - return retval; -} - -static int fwu_start_write_config(void) -{ - int retval; - unsigned short block_count; - struct image_header_data header; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - block_count = fwu->config_block_count; - break; - case PERM_CONFIG_AREA: - if (!fwu->has_perm_config) - return -EINVAL; - block_count = fwu->perm_config_block_count; - break; - case BL_CONFIG_AREA: - if (!fwu->has_bl_config) - return -EINVAL; - block_count = fwu->bl_config_block_count; - break; - case DISP_CONFIG_AREA: - if (!fwu->has_disp_config) - return -EINVAL; - block_count = fwu->disp_config_block_count; - break; - default: - return -EINVAL; - } - - if (fwu->ext_data_source) - fwu->config_data = fwu->ext_data_source; - else - return -EINVAL; - - fwu->config_size = fwu->block_size * block_count; - - /* Jump to the config area if given a packrat image */ - if ((fwu->config_area == UI_CONFIG_AREA) && - (fwu->config_size != fwu->image_size)) { - parse_header(&header, fwu->ext_data_source); - - if (header.config_size) { - fwu->config_data = fwu->ext_data_source + - FW_IMAGE_OFFSET + - header.firmware_size; - } else { - return -EINVAL; - } - } - - pr_notice("%s: Start of write config process\n", __func__); - - retval = fwu_do_write_config(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write config\n", - __func__); - } - - rmi4_data->reset_device(rmi4_data); - - pr_notice("%s: End of write config process\n", __func__); - - return retval; -} - -static int fwu_do_read_config(void) -{ - int retval; - unsigned char block_offset[] = {0, 0}; - unsigned short block_num; - unsigned short block_count; - unsigned short index = 0; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_enter_flash_prog(); - if (retval < 0) - goto exit; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Entered flash prog mode\n", - __func__); - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - block_count = fwu->config_block_count; - break; - case PERM_CONFIG_AREA: - if (!fwu->has_perm_config) { - retval = -EINVAL; - goto exit; - } - block_count = fwu->perm_config_block_count; - break; - case BL_CONFIG_AREA: - if (!fwu->has_bl_config) { - retval = -EINVAL; - goto exit; - } - block_count = fwu->bl_config_block_count; - break; - case DISP_CONFIG_AREA: - if (!fwu->has_disp_config) { - retval = -EINVAL; - goto exit; - } - block_count = fwu->disp_config_block_count; - break; - default: - retval = -EINVAL; - goto exit; - } - - fwu->config_size = fwu->block_size * block_count; - - kfree(fwu->read_config_buf); - fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL); - - block_offset[1] |= (fwu->config_area << 5); - - retval = synaptics_rmi4_reg_write(rmi4_data, - fwu->f34_fd.data_base_addr + BLOCK_NUMBER_OFFSET, - block_offset, - sizeof(block_offset)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write to block number registers\n", - __func__); - goto exit; - } - - for (block_num = 0; block_num < block_count; block_num++) { - retval = fwu_write_f34_command(CMD_READ_CONFIG_BLOCK); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write read config command\n", - __func__); - goto exit; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wait for idle status\n", - __func__); - goto exit; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.data_base_addr + fwu->blk_data_off, - &fwu->read_config_buf[index], - fwu->block_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read block data (block %d)\n", - __func__, block_num); - goto exit; - } - - index += fwu->block_size; - } - -exit: - rmi4_data->reset_device(rmi4_data); - - return retval; -} - -static int fwu_do_lockdown(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_enter_flash_prog(); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.query_base_addr + fwu->properties_off, - &fwu->flash_properties, - sizeof(fwu->flash_properties)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read flash properties\n", - __func__); - return retval; - } - - if ((fwu->flash_properties & UNLOCKED) == 0) { - dev_info(rmi4_data->pdev->dev.parent, - "%s: Device already locked down\n", - __func__); - return retval; - } - - retval = fwu_write_lockdown(); - if (retval < 0) - return retval; - - pr_notice("%s: Lockdown programmed\n", __func__); - - return retval; -} - -static int fwu_start_reflash(void) -{ - int retval = 0; - enum flash_area flash_area; - struct image_header_data header; - struct f01_device_status f01_device_status; - const unsigned char *fw_image; - const struct firmware *fw_entry = NULL; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (rmi4_data->sensor_sleep) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Sensor sleeping\n", - __func__); - return -ENODEV; - } - - rmi4_data->stay_awake = true; - - pr_notice("%s: Start of reflash process\n", __func__); - - if (fwu->ext_data_source) { - fw_image = fwu->ext_data_source; - } else { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Requesting firmware image %s\n", - __func__, fwu->image_name); - - retval = request_firmware(&fw_entry, fwu->image_name, - rmi4_data->pdev->dev.parent); - if (retval != 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Firmware image %s not available\n", - __func__, fwu->image_name); - retval = -EINVAL; - goto exit; - } - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Firmware image size = %zu\n", - __func__, fw_entry->size); - - fw_image = fw_entry->data; - } - - parse_header(&header, fw_image); - - if (fwu->bl_version != header.bootloader_version) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Bootloader version mismatch\n", - __func__); - retval = -EINVAL; - goto exit; - } - - retval = fwu_read_f01_device_status(&f01_device_status); - if (retval < 0) - goto exit; - - if (f01_device_status.flash_prog) { - dev_info(rmi4_data->pdev->dev.parent, - "%s: In flash prog mode\n", - __func__); - fwu->in_flash_prog_mode = true; - } else { - fwu->in_flash_prog_mode = false; - } - - if (fwu->do_lockdown) { - switch (fwu->bl_version) { - case V5: - case V6: - fwu->lockdown_data = fw_image + LOCKDOWN_OFFSET; - fwu->lockdown_block_count = LOCKDOWN_BLOCK_COUNT; - retval = fwu_do_lockdown(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do lockdown\n", - __func__); - } - default: - break; - } - } - - if (header.firmware_size) - fwu->firmware_data = fw_image + FW_IMAGE_OFFSET; - if (header.config_size) { - fwu->config_data = fw_image + FW_IMAGE_OFFSET + - header.firmware_size; - } - - flash_area = fwu_go_nogo(&header); - switch (flash_area) { - case UI_FIRMWARE: - retval = fwu_do_reflash(); - break; - case CONFIG_AREA: - retval = fwu_do_write_config(); - break; - case NONE: - default: - goto exit; - } - - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do reflash\n", - __func__); - } - -exit: - rmi4_data->reset_device(rmi4_data); - - if (fw_entry) - release_firmware(fw_entry); - - pr_notice("%s: End of reflash process\n", __func__); - - rmi4_data->stay_awake = false; - - return retval; -} - -int synaptics_dsx_fw_updater(unsigned char *fw_data) -{ - int retval; - - if (!fwu) - return -ENODEV; - - if (!fwu->initialized) - return -ENODEV; - - fwu->rmi4_data->fw_updating = true; - if (fwu->rmi4_data->suspended == true) { - fwu->rmi4_data->fw_updating = false; - dev_err(fwu->rmi4_data->pdev->dev.parent, - "Cannot start fw upgrade: Device is in suspend\n"); - return -EBUSY; - } - - fwu->ext_data_source = fw_data; - fwu->config_area = UI_CONFIG_AREA; - - retval = fwu_start_reflash(); - - fwu->rmi4_data->fw_updating = false; - - return retval; -} -EXPORT_SYMBOL(synaptics_dsx_fw_updater); - -static ssize_t fwu_sysfs_show_image(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (count < fwu->config_size) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Not enough space (%zu bytes) in buffer\n", - __func__, count); - return -EINVAL; - } - - memcpy(buf, fwu->read_config_buf, fwu->config_size); - - return fwu->config_size; -} - -static ssize_t fwu_sysfs_store_image(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]), - (const void *)buf, - count); - - fwu->data_pos += count; - - return count; -} - -static ssize_t fwu_sysfs_force_reflash_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) { - retval = -EINVAL; - goto exit; - } - - if (input != 1) { - retval = -EINVAL; - goto exit; - } - - if (LOCKDOWN) - fwu->do_lockdown = true; - - fwu->force_update = true; - retval = synaptics_dsx_fw_updater(fwu->ext_data_source); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do reflash\n", - __func__); - goto exit; - } - - retval = count; -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - fwu->force_update = FORCE_UPDATE; - fwu->do_lockdown = DO_LOCKDOWN; - return retval; -} - -static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) { - retval = -EINVAL; - goto exit; - } - - if (input & LOCKDOWN) { - fwu->do_lockdown = true; - input &= ~LOCKDOWN; - } - - if ((input != NORMAL) && (input != FORCE)) { - retval = -EINVAL; - goto exit; - } - - if (input == FORCE) - fwu->force_update = true; - - retval = synaptics_dsx_fw_updater(fwu->ext_data_source); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do reflash\n", - __func__); - goto exit; - } - - retval = count; - -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - fwu->force_update = FORCE_UPDATE; - fwu->do_lockdown = DO_LOCKDOWN; - return retval; -} - -static ssize_t fwu_sysfs_write_config_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) { - retval = -EINVAL; - goto exit; - } - - if (input != 1) { - retval = -EINVAL; - goto exit; - } - - retval = fwu_start_write_config(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write config\n", - __func__); - goto exit; - } - - retval = count; - -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - return retval; -} - -static ssize_t fwu_sysfs_read_config_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - retval = fwu_do_read_config(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read config\n", - __func__); - return retval; - } - - return count; -} - -static ssize_t fwu_sysfs_config_area_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long config_area; - - retval = sstrtoul(buf, 10, &config_area); - if (retval) - return retval; - - fwu->config_area = config_area; - - return count; -} - -static ssize_t fwu_sysfs_image_name_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - if (strnlen(fwu->rmi4_data->fw_name, SYNA_FW_NAME_MAX_LEN) > 0) - return snprintf(buf, PAGE_SIZE, "%s\n", - fwu->rmi4_data->fw_name); - else - return snprintf(buf, PAGE_SIZE, "No firmware name given\n"); -} - -static ssize_t fwu_sysfs_image_name_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - if (sscanf(buf, "%s", fwu->image_name) != 1) - return -EINVAL; - - return count; -} - -static ssize_t fwu_sysfs_image_size_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long size; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = sstrtoul(buf, 10, &size); - if (retval) - return retval; - - fwu->image_size = size; - fwu->data_pos = 0; - - kfree(fwu->ext_data_source); - fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL); - if (!fwu->ext_data_source) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for image data\n", - __func__); - return -ENOMEM; - } - - return count; -} - -static ssize_t fwu_sysfs_block_size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size); -} - -static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count); -} - -static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count); -} - -static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count); -} - -static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count); -} - -static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count); -} - -static ssize_t fwu_sysfs_config_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - unsigned char config_id[4]; - int retval; - - /* device config id */ - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.ctrl_base_addr, - config_id, - sizeof(config_id)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read device config ID\n", - __func__); - return retval; - } - - return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", - config_id[0], config_id[1], config_id[2], config_id[3]); -} - -static ssize_t fwu_sysfs_package_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned char package_id[PACKAGE_ID_SIZE]; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - /* read device package id */ - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_query_base_addr + F01_PACKAGE_ID_OFFSET, - package_id, - sizeof(package_id)); - - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read device package ID\n", - __func__); - return retval; - } - - return snprintf(buf, PAGE_SIZE, "%d rev %d\n", - (package_id[1] << 8) | package_id[0], - (package_id[3] << 8) | package_id[2]); -} - -static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask) -{ - if (!fwu) - return; - - if (fwu->intr_mask & intr_mask) - fwu_read_f34_flash_status(); - - return; -} - -static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char attr_count; - struct pdt_properties pdt_props; - - fwu = kzalloc(sizeof(*fwu), GFP_KERNEL); - if (!fwu) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for fwu\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - fwu->image_name = rmi4_data->fw_name; - - fwu->rmi4_data = rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - PDT_PROPS, - pdt_props.data, - sizeof(pdt_props.data)); - if (retval < 0) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Failed to read PDT properties, assuming 0x00\n", - __func__); - } else if (pdt_props.has_bsr) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Reflash for LTS not currently supported\n", - __func__); - retval = -ENODEV; - goto exit_free_fwu; - } - - retval = fwu_scan_pdt(); - if (retval < 0) - goto exit_free_fwu; - - fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0]; - fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1]; - memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string, - SYNAPTICS_RMI4_PRODUCT_ID_SIZE); - fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: F01 product info: 0x%04x 0x%04x\n", - __func__, fwu->productinfo1, fwu->productinfo2); - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: F01 product ID: %s\n", - __func__, fwu->product_id); - - retval = fwu_read_f34_queries(); - if (retval < 0) - goto exit_free_fwu; - - fwu->force_update = FORCE_UPDATE; - fwu->do_lockdown = DO_LOCKDOWN; - fwu->initialized = true; - - retval = sysfs_create_bin_file(&rmi4_data->input_dev->dev.kobj, - &dev_attr_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs bin file\n", - __func__); - goto exit_free_fwu; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs attributes\n", - __func__); - retval = -ENODEV; - goto exit_remove_attrs; - } - } - - return 0; - -exit_remove_attrs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data); - -exit_free_fwu: - kfree(fwu); - fwu = NULL; - -exit: - return retval; -} - -static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char attr_count; - - if (!fwu) - goto exit; - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data); - - kfree(fwu->read_config_buf); - kfree(fwu); - fwu = NULL; - -exit: - complete(&fwu_dsx_remove_complete); - - return; -} - -static struct synaptics_rmi4_exp_fn fwu_module = { - .fn_type = RMI_FW_UPDATER, - .init = synaptics_rmi4_fwu_init, - .remove = synaptics_rmi4_fwu_remove, - .reset = NULL, - .reinit = NULL, - .early_suspend = NULL, - .suspend = NULL, - .resume = NULL, - .late_resume = NULL, - .attn = synaptics_rmi4_fwu_attn, -}; - -static int __init rmi4_fw_update_module_init(void) -{ - synaptics_rmi4_dsx_new_function(&fwu_module, true); - - return 0; -} - -static void __exit rmi4_fw_update_module_exit(void) -{ - synaptics_rmi4_dsx_new_function(&fwu_module, false); - - wait_for_completion(&fwu_dsx_remove_complete); - - return; -} - -module_init(rmi4_fw_update_module_init); -module_exit(rmi4_fw_update_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX FW Update Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c deleted file mode 100755 index a035c496d0e6..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_i2c.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (c) 2014, The Linux Foundation. All rights reserved. - * - * Linux foundation chooses to take subject only to the GPLv2 license terms, - * and distributes only under these terms. - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/types.h> -#include <linux/platform_device.h> -#include <linux/input/synaptics_dsx_v2.h> -#include "synaptics_dsx_core.h" -#include <linux/of_gpio.h> -#include <linux/of_irq.h> -#if defined(CONFIG_SECURE_TOUCH) -#include <linux/pm_runtime.h> -#endif - -#define SYN_I2C_RETRY_TIMES 10 -#define RESET_DELAY 100 -#define DSX_COORDS_ARR_SIZE 4 - -static int synaptics_rmi4_i2c_set_page(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr) -{ - int retval; - unsigned char retry; - unsigned char buf[PAGE_SELECT_LEN]; - unsigned char page; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - - page = ((addr >> 8) & MASK_8BIT); - if (page != rmi4_data->current_page) { - buf[0] = MASK_8BIT; - buf[1] = page; - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - retval = i2c_master_send(i2c, buf, PAGE_SELECT_LEN); - if (retval != PAGE_SELECT_LEN) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - } else { - rmi4_data->current_page = page; - break; - } - } - } else { - retval = PAGE_SELECT_LEN; - } - - return retval; -} - -static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, unsigned char *data, unsigned short length) -{ - int retval; - unsigned char retry; - unsigned char buf; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - struct i2c_msg msg[] = { - { - .addr = i2c->addr, - .flags = 0, - .len = 1, - .buf = &buf, - }, - { - .addr = i2c->addr, - .flags = I2C_M_RD, - .len = length, - .buf = data, - }, - }; - - buf = addr & MASK_8BIT; - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - retval = synaptics_rmi4_i2c_set_page(rmi4_data, addr); - if (retval != PAGE_SELECT_LEN) { - retval = -EIO; - goto exit; - } - - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - if (i2c_transfer(i2c->adapter, msg, 2) == 2) { - retval = length; - break; - } - dev_err(rmi4_data->pdev->dev.parent, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - } - - if (retry == SYN_I2C_RETRY_TIMES) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: I2C read over retry limit\n", - __func__); - retval = -EIO; - } - -exit: - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - - return retval; -} - -static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, unsigned char *data, unsigned short length) -{ - int retval; - unsigned char retry; - unsigned char buf[length + 1]; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - struct i2c_msg msg[] = { - { - .addr = i2c->addr, - .flags = 0, - .len = length + 1, - .buf = buf, - } - }; - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - retval = synaptics_rmi4_i2c_set_page(rmi4_data, addr); - if (retval != PAGE_SELECT_LEN) { - retval = -EIO; - goto exit; - } - - buf[0] = addr & MASK_8BIT; - memcpy(&buf[1], &data[0], length); - - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - if (i2c_transfer(i2c->adapter, msg, 1) == 1) { - retval = length; - break; - } - dev_err(rmi4_data->pdev->dev.parent, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - } - - if (retry == SYN_I2C_RETRY_TIMES) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: I2C write over retry limit\n", - __func__); - retval = -EIO; - } - -exit: - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - - return retval; -} - -#if defined(CONFIG_SECURE_TOUCH) -static int synaptics_rmi4_i2c_get(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - retval = pm_runtime_get_sync(i2c->adapter->dev.parent); - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - - return retval; -} - -static void synaptics_rmi4_i2c_put(struct synaptics_rmi4_data *rmi4_data) -{ - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - pm_runtime_put_sync(i2c->adapter->dev.parent); - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); -} -#endif - -static struct synaptics_dsx_bus_access bus_access = { - .type = BUS_I2C, - .read = synaptics_rmi4_i2c_read, - .write = synaptics_rmi4_i2c_write, -#if defined(CONFIG_SECURE_TOUCH) - .get = synaptics_rmi4_i2c_get, - .put = synaptics_rmi4_i2c_put, -#endif -}; - -static struct synaptics_dsx_hw_interface hw_if; - -static struct platform_device *synaptics_dsx_i2c_device; - -static void synaptics_rmi4_i2c_dev_release(struct device *dev) -{ - kfree(synaptics_dsx_i2c_device); - - return; -} -#ifdef CONFIG_OF -int synaptics_dsx_get_dt_coords(struct device *dev, char *name, - struct synaptics_dsx_board_data *pdata, - struct device_node *node) -{ - u32 coords[DSX_COORDS_ARR_SIZE]; - struct property *prop; - struct device_node *np = (node == NULL) ? (dev->of_node) : (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 != DSX_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, "synaptics,panel-coords") == 0) { - pdata->panel_minx = coords[0]; - pdata->panel_miny = coords[1]; - pdata->panel_maxx = coords[2]; - pdata->panel_maxy = coords[3]; - } else if (strcmp(name, "synaptics,display-coords") == 0) { - pdata->disp_minx = coords[0]; - pdata->disp_miny = coords[1]; - pdata->disp_maxx = coords[2]; - pdata->disp_maxy = coords[3]; - } else { - dev_err(dev, "unsupported property %s\n", name); - return -EINVAL; - } - - return 0; -} - -static int synaptics_dsx_parse_dt(struct device *dev, - struct synaptics_dsx_board_data *rmi4_pdata) -{ - struct device_node *np = dev->of_node; - struct property *prop; - u32 temp_val, num_buttons; - u32 button_map[MAX_NUMBER_OF_BUTTONS]; - int rc, i; - - rmi4_pdata->x_flip = of_property_read_bool(np, "synaptics,x-flip"); - rmi4_pdata->y_flip = of_property_read_bool(np, "synaptics,y-flip"); - - rmi4_pdata->disable_gpios = of_property_read_bool(np, - "synaptics,disable-gpios"); - - rmi4_pdata->reset_delay_ms = RESET_DELAY; - rc = of_property_read_u32(np, "synaptics,reset-delay-ms", &temp_val); - if (!rc) - rmi4_pdata->reset_delay_ms = temp_val; - else if (rc != -EINVAL) { - dev_err(dev, "Unable to read reset delay\n"); - return rc; - } - - rmi4_pdata->fw_name = "PRXXX_fw.img"; - rc = of_property_read_string(np, "synaptics,fw-name", - &rmi4_pdata->fw_name); - if (rc && (rc != -EINVAL)) { - dev_err(dev, "Unable to read fw name\n"); - return rc; - } - - /* reset, irq gpio info */ - rmi4_pdata->reset_gpio = of_get_named_gpio_flags(np, - "synaptics,reset-gpio", 0, &rmi4_pdata->reset_flags); - rmi4_pdata->irq_gpio = of_get_named_gpio_flags(np, - "synaptics,irq-gpio", 0, &rmi4_pdata->irq_flags); - - rc = synaptics_dsx_get_dt_coords(dev, "synaptics,display-coords", - rmi4_pdata, NULL); - if (rc && (rc != -EINVAL)) - return rc; - - rc = synaptics_dsx_get_dt_coords(dev, "synaptics,panel-coords", - rmi4_pdata, NULL); - if (rc && (rc != -EINVAL)) - return rc; - - rmi4_pdata->detect_device = of_property_read_bool(np, - "synaptics,detect-device"); - - if (rmi4_pdata->detect_device) - return 0; - - prop = of_find_property(np, "synaptics,button-map", NULL); - if (prop) { - num_buttons = prop->length / sizeof(temp_val); - - rmi4_pdata->cap_button_map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->cap_button_map), - GFP_KERNEL); - if (!rmi4_pdata->cap_button_map) - return -ENOMEM; - - rmi4_pdata->cap_button_map->map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->cap_button_map->map) * - MAX_NUMBER_OF_BUTTONS, GFP_KERNEL); - if (!rmi4_pdata->cap_button_map->map) - return -ENOMEM; - - if (num_buttons <= MAX_NUMBER_OF_BUTTONS) { - rc = of_property_read_u32_array(np, - "synaptics,button-map", button_map, - num_buttons); - if (rc) { - dev_err(dev, "Unable to read key codes\n"); - return rc; - } - for (i = 0; i < num_buttons; i++) - rmi4_pdata->cap_button_map->map[i] = - button_map[i]; - rmi4_pdata->cap_button_map->nbuttons = - num_buttons; - } else { - return -EINVAL; - } - } - return 0; -} -#else -static inline int synaptics_dsx_parse_dt(struct device *dev, - struct synaptics_dsx_board_data *rmi4_pdata) -{ - return 0; -} -#endif - -static int synaptics_rmi4_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - int retval; - struct synaptics_dsx_board_data *platform_data; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, - "%s: SMBus byte data commands not supported by host\n", - __func__); - return -EIO; - } - - if (client->dev.of_node) { - platform_data = devm_kzalloc(&client->dev, - sizeof(struct synaptics_dsx_board_data), - GFP_KERNEL); - if (!platform_data) { - dev_err(&client->dev, "Failed to allocate memory\n"); - return -ENOMEM; - } - - retval = synaptics_dsx_parse_dt(&client->dev, platform_data); - if (retval) - return retval; - } else { - platform_data = client->dev.platform_data; - } - - if (!platform_data) { - dev_err(&client->dev, - "%s: No platform data found\n", - __func__); - return -EINVAL; - } - - synaptics_dsx_i2c_device = kzalloc( - sizeof(struct platform_device), - GFP_KERNEL); - if (!synaptics_dsx_i2c_device) { - dev_err(&client->dev, - "%s: Failed to allocate memory for synaptics_dsx_i2c_device\n", - __func__); - return -ENOMEM; - } - - hw_if.board_data = platform_data; - hw_if.bus_access = &bus_access; - - synaptics_dsx_i2c_device->name = PLATFORM_DRIVER_NAME; - synaptics_dsx_i2c_device->id = 0; - synaptics_dsx_i2c_device->num_resources = 0; - synaptics_dsx_i2c_device->dev.parent = &client->dev; - synaptics_dsx_i2c_device->dev.platform_data = &hw_if; - synaptics_dsx_i2c_device->dev.release = synaptics_rmi4_i2c_dev_release; - - retval = platform_device_register(synaptics_dsx_i2c_device); - if (retval) { - dev_err(&client->dev, - "%s: Failed to register platform device\n", - __func__); - return -ENODEV; - } - - return 0; -} - -static int synaptics_rmi4_i2c_remove(struct i2c_client *client) -{ - platform_device_unregister(synaptics_dsx_i2c_device); - - return 0; -} - -static const struct i2c_device_id synaptics_rmi4_id_table[] = { - {I2C_DRIVER_NAME, 0}, - {}, -}; -MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table); - -#ifdef CONFIG_OF -static struct of_device_id dsx_match_table[] = { - { .compatible = "synaptics,dsx",}, - { }, -}; -#else -#define dsx_match_table NULL -#endif - -static struct i2c_driver synaptics_rmi4_i2c_driver = { - .driver = { - .name = I2C_DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = dsx_match_table, - }, - .probe = synaptics_rmi4_i2c_probe, - .remove = synaptics_rmi4_i2c_remove, - .id_table = synaptics_rmi4_id_table, -}; - -int synaptics_rmi4_bus_init(void) -{ - return i2c_add_driver(&synaptics_rmi4_i2c_driver); -} -EXPORT_SYMBOL(synaptics_rmi4_bus_init); - -void synaptics_rmi4_bus_exit(void) -{ - i2c_del_driver(&synaptics_rmi4_i2c_driver); - - return; -} -EXPORT_SYMBOL(synaptics_rmi4_bus_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX I2C Bus Support Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_proximity.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_proximity.c deleted file mode 100755 index 99c05e6845c0..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_proximity.c +++ /dev/null @@ -1,671 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/platform_device.h> -#include <linux/input/synaptics_dsx_v2.h> -#include "synaptics_dsx_core.h" - -#define PROX_PHYS_NAME "synaptics_dsx/input1" - -#define HOVER_Z_MAX (255) - -#define HOVERING_FINGER_EN (1 << 4) - -static ssize_t synaptics_rmi4_hover_finger_en_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_hover_finger_en_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static struct device_attribute attrs[] = { - __ATTR(hover_finger_en, (S_IRUGO | S_IWUGO), - synaptics_rmi4_hover_finger_en_show, - synaptics_rmi4_hover_finger_en_store), -}; - -struct synaptics_rmi4_f12_query_5 { - union { - struct { - unsigned char size_of_query6; - struct { - unsigned char ctrl0_is_present:1; - unsigned char ctrl1_is_present:1; - unsigned char ctrl2_is_present:1; - unsigned char ctrl3_is_present:1; - unsigned char ctrl4_is_present:1; - unsigned char ctrl5_is_present:1; - unsigned char ctrl6_is_present:1; - unsigned char ctrl7_is_present:1; - } __packed; - struct { - unsigned char ctrl8_is_present:1; - unsigned char ctrl9_is_present:1; - unsigned char ctrl10_is_present:1; - unsigned char ctrl11_is_present:1; - unsigned char ctrl12_is_present:1; - unsigned char ctrl13_is_present:1; - unsigned char ctrl14_is_present:1; - unsigned char ctrl15_is_present:1; - } __packed; - struct { - unsigned char ctrl16_is_present:1; - unsigned char ctrl17_is_present:1; - unsigned char ctrl18_is_present:1; - unsigned char ctrl19_is_present:1; - unsigned char ctrl20_is_present:1; - unsigned char ctrl21_is_present:1; - unsigned char ctrl22_is_present:1; - unsigned char ctrl23_is_present:1; - } __packed; - }; - unsigned char data[4]; - }; -}; - -struct synaptics_rmi4_f12_query_8 { - union { - struct { - unsigned char size_of_query9; - struct { - unsigned char data0_is_present:1; - unsigned char data1_is_present:1; - unsigned char data2_is_present:1; - unsigned char data3_is_present:1; - unsigned char data4_is_present:1; - unsigned char data5_is_present:1; - unsigned char data6_is_present:1; - unsigned char data7_is_present:1; - } __packed; - }; - unsigned char data[2]; - }; -}; - -struct prox_finger_data { - union { - struct { - unsigned char object_type_and_status; - unsigned char x_lsb; - unsigned char x_msb; - unsigned char y_lsb; - unsigned char y_msb; - unsigned char z; - } __packed; - unsigned char proximity_data[6]; - }; -}; - -struct synaptics_rmi4_prox_handle { - bool hover_finger_present; - bool hover_finger_en; - unsigned char intr_mask; - unsigned short query_base_addr; - unsigned short control_base_addr; - unsigned short data_base_addr; - unsigned short command_base_addr; - unsigned short hover_finger_en_addr; - unsigned short hover_finger_data_addr; - struct input_dev *prox_dev; - struct prox_finger_data *finger_data; - struct synaptics_rmi4_data *rmi4_data; -}; - -static struct synaptics_rmi4_prox_handle *prox; - -DECLARE_COMPLETION(prox_remove_complete); - -static void prox_hover_finger_lift(void) -{ - input_report_key(prox->prox_dev, BTN_TOUCH, 0); - input_report_key(prox->prox_dev, BTN_TOOL_FINGER, 0); - input_sync(prox->prox_dev); - prox->hover_finger_present = false; - - return; -} - -static void prox_hover_finger_report(void) -{ - int retval; - int x; - int y; - int z; - struct prox_finger_data *data; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - data = prox->finger_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - prox->hover_finger_data_addr, - data->proximity_data, - sizeof(data->proximity_data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read hovering finger data\n", - __func__); - return; - } - - if (data->object_type_and_status != F12_HOVERING_FINGER_STATUS) { - if (prox->hover_finger_present) - prox_hover_finger_lift(); - - return; - } - - x = (data->x_msb << 8) | (data->x_lsb); - y = (data->y_msb << 8) | (data->y_lsb); - z = HOVER_Z_MAX - data->z; - - input_report_key(prox->prox_dev, BTN_TOUCH, 0); - input_report_key(prox->prox_dev, BTN_TOOL_FINGER, 1); - input_report_abs(prox->prox_dev, ABS_X, x); - input_report_abs(prox->prox_dev, ABS_Y, y); - input_report_abs(prox->prox_dev, ABS_DISTANCE, z); - - input_sync(prox->prox_dev); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: x = %d y = %d z = %d\n", - __func__, x, y, z); - - prox->hover_finger_present = true; - - return; -} - -static int prox_set_hover_finger_en(void) -{ - int retval; - unsigned char object_report_enable; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - prox->hover_finger_en_addr, - &object_report_enable, - sizeof(object_report_enable)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read from object report enable register\n", - __func__); - return retval; - } - - if (prox->hover_finger_en) - object_report_enable |= HOVERING_FINGER_EN; - else - object_report_enable &= ~HOVERING_FINGER_EN; - - retval = synaptics_rmi4_reg_write(rmi4_data, - prox->hover_finger_en_addr, - &object_report_enable, - sizeof(object_report_enable)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write to object report enable register\n", - __func__); - return retval; - } - - return 0; -} - -static void prox_set_params(void) -{ - input_set_abs_params(prox->prox_dev, ABS_X, 0, - prox->rmi4_data->sensor_max_x, 0, 0); - input_set_abs_params(prox->prox_dev, ABS_Y, 0, - prox->rmi4_data->sensor_max_y, 0, 0); - input_set_abs_params(prox->prox_dev, ABS_DISTANCE, 0, - HOVER_Z_MAX, 0, 0); - - return; -} - -static int prox_reg_init(void) -{ - int retval; - unsigned char ctrl_23_offset; - unsigned char data_1_offset; - struct synaptics_rmi4_f12_query_5 query_5; - struct synaptics_rmi4_f12_query_8 query_8; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - prox->query_base_addr + 5, - query_5.data, - sizeof(query_5.data)); - if (retval < 0) - return retval; - - ctrl_23_offset = query_5.ctrl0_is_present + - query_5.ctrl1_is_present + - query_5.ctrl2_is_present + - query_5.ctrl3_is_present + - query_5.ctrl4_is_present + - query_5.ctrl5_is_present + - query_5.ctrl6_is_present + - query_5.ctrl7_is_present + - query_5.ctrl8_is_present + - query_5.ctrl9_is_present + - query_5.ctrl10_is_present + - query_5.ctrl11_is_present + - query_5.ctrl12_is_present + - query_5.ctrl13_is_present + - query_5.ctrl14_is_present + - query_5.ctrl15_is_present + - query_5.ctrl16_is_present + - query_5.ctrl17_is_present + - query_5.ctrl18_is_present + - query_5.ctrl19_is_present + - query_5.ctrl20_is_present + - query_5.ctrl21_is_present + - query_5.ctrl22_is_present; - - prox->hover_finger_en_addr = prox->control_base_addr + ctrl_23_offset; - - retval = synaptics_rmi4_reg_read(rmi4_data, - prox->query_base_addr + 8, - query_8.data, - sizeof(query_8.data)); - if (retval < 0) - return retval; - - data_1_offset = query_8.data0_is_present; - prox->hover_finger_data_addr = prox->data_base_addr + data_1_offset; - - return retval; -} - -static int prox_scan_pdt(void) -{ - int retval; - unsigned char ii; - unsigned char page; - unsigned char intr_count = 0; - unsigned char intr_off; - unsigned char intr_src; - unsigned short addr; - struct synaptics_rmi4_fn_desc fd; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - for (page = 0; page < PAGES_TO_SERVICE; page++) { - for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) { - addr |= (page << 8); - - retval = synaptics_rmi4_reg_read(rmi4_data, - addr, - (unsigned char *)&fd, - sizeof(fd)); - if (retval < 0) - return retval; - - addr &= ~(MASK_8BIT << 8); - - if (fd.fn_number) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Found F%02x\n", - __func__, fd.fn_number); - switch (fd.fn_number) { - case SYNAPTICS_RMI4_F12: - goto f12_found; - break; - } - } else { - break; - } - - intr_count += (fd.intr_src_count & MASK_3BIT); - } - } - - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F12\n", - __func__); - return -EINVAL; - -f12_found: - prox->query_base_addr = fd.query_base_addr | (page << 8); - prox->control_base_addr = fd.ctrl_base_addr | (page << 8); - prox->data_base_addr = fd.data_base_addr | (page << 8); - prox->command_base_addr = fd.cmd_base_addr | (page << 8); - - retval = prox_reg_init(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to initialize proximity registers\n", - __func__); - return retval; - } - - prox->intr_mask = 0; - intr_src = fd.intr_src_count; - intr_off = intr_count % 8; - for (ii = intr_off; - ii < ((intr_src & MASK_3BIT) + - intr_off); - ii++) { - prox->intr_mask |= 1 << ii; - } - - rmi4_data->intr_mask[0] |= prox->intr_mask; - - addr = rmi4_data->f01_ctrl_base_addr + 1; - - retval = synaptics_rmi4_reg_write(rmi4_data, - addr, - &(rmi4_data->intr_mask[0]), - sizeof(rmi4_data->intr_mask[0])); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set interrupt enable bit\n", - __func__); - return retval; - } - - return 0; -} - -static ssize_t synaptics_rmi4_hover_finger_en_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - if (!prox) - return -ENODEV; - - return snprintf(buf, PAGE_SIZE, "%u\n", - prox->hover_finger_en); -} - -static ssize_t synaptics_rmi4_hover_finger_en_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - if (!prox) - return -ENODEV; - - if (sscanf(buf, "%x", &input) != 1) - return -EINVAL; - - if (input == 1) - prox->hover_finger_en = true; - else if (input == 0) - prox->hover_finger_en = false; - else - return -EINVAL; - - retval = prox_set_hover_finger_en(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to change hovering finger enable setting\n", - __func__); - return retval; - } - - return count; -} - -int synaptics_rmi4_prox_hover_finger_en(bool enable) -{ - int retval; - - if (!prox) - return -ENODEV; - - prox->hover_finger_en = enable; - - retval = prox_set_hover_finger_en(); - if (retval < 0) - return retval; - - return 0; -} -EXPORT_SYMBOL(synaptics_rmi4_prox_hover_finger_en); - -static void synaptics_rmi4_prox_attn(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask) -{ - if (!prox) - return; - - if (prox->intr_mask & intr_mask) - prox_hover_finger_report(); - - return; -} - -static int synaptics_rmi4_prox_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char attr_count; - - prox = kzalloc(sizeof(*prox), GFP_KERNEL); - if (!prox) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for prox\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - prox->finger_data = kzalloc(sizeof(*(prox->finger_data)), GFP_KERNEL); - if (!prox->finger_data) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for finger_data\n", - __func__); - retval = -ENOMEM; - goto exit_free_prox; - } - - prox->rmi4_data = rmi4_data; - - retval = prox_scan_pdt(); - if (retval < 0) - goto exit_free_finger_data; - - prox->hover_finger_en = true; - - retval = prox_set_hover_finger_en(); - if (retval < 0) - return retval; - - prox->prox_dev = input_allocate_device(); - if (prox->prox_dev == NULL) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate proximity device\n", - __func__); - retval = -ENOMEM; - goto exit_free_finger_data; - } - - prox->prox_dev->name = PLATFORM_DRIVER_NAME; - prox->prox_dev->phys = PROX_PHYS_NAME; - prox->prox_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; - prox->prox_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; - prox->prox_dev->dev.parent = rmi4_data->pdev->dev.parent; - input_set_drvdata(prox->prox_dev, rmi4_data); - - set_bit(EV_KEY, prox->prox_dev->evbit); - set_bit(EV_ABS, prox->prox_dev->evbit); - set_bit(BTN_TOUCH, prox->prox_dev->keybit); - set_bit(BTN_TOOL_FINGER, prox->prox_dev->keybit); -#ifdef INPUT_PROP_DIRECT - set_bit(INPUT_PROP_DIRECT, prox->prox_dev->propbit); -#endif - - prox_set_params(); - - retval = input_register_device(prox->prox_dev); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to register proximity device\n", - __func__); - goto exit_free_input_device; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs attributes\n", - __func__); - goto exit_free_sysfs; - } - } - - return 0; - -exit_free_sysfs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - input_unregister_device(prox->prox_dev); - prox->prox_dev = NULL; - -exit_free_input_device: - if (prox->prox_dev) - input_free_device(prox->prox_dev); - -exit_free_finger_data: - kfree(prox->finger_data); - -exit_free_prox: - kfree(prox); - prox = NULL; - -exit: - return retval; -} - -static void synaptics_rmi4_prox_remove(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char attr_count; - - if (!prox) - goto exit; - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - input_unregister_device(prox->prox_dev); - kfree(prox->finger_data); - kfree(prox); - prox = NULL; - -exit: - complete(&prox_remove_complete); - - return; -} - -static void synaptics_rmi4_prox_reset(struct synaptics_rmi4_data *rmi4_data) -{ - if (!prox) - return; - - prox_hover_finger_lift(); - - prox_scan_pdt(); - - prox_set_hover_finger_en(); - - prox_set_params(); - - return; -} - -static void synaptics_rmi4_prox_reinit(struct synaptics_rmi4_data *rmi4_data) -{ - if (!prox) - return; - - prox_hover_finger_lift(); - - prox_set_hover_finger_en(); - - return; -} - -static void synaptics_rmi4_prox_e_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - if (!prox) - return; - - prox_hover_finger_lift(); - - return; -} - -static void synaptics_rmi4_prox_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - if (!prox) - return; - - prox_hover_finger_lift(); - - return; -} - -static struct synaptics_rmi4_exp_fn proximity_module = { - .fn_type = RMI_PROXIMITY, - .init = synaptics_rmi4_prox_init, - .remove = synaptics_rmi4_prox_remove, - .reset = synaptics_rmi4_prox_reset, - .reinit = synaptics_rmi4_prox_reinit, - .early_suspend = synaptics_rmi4_prox_e_suspend, - .suspend = synaptics_rmi4_prox_suspend, - .resume = NULL, - .late_resume = NULL, - .attn = synaptics_rmi4_prox_attn, -}; - -static int __init rmi4_proximity_module_init(void) -{ - synaptics_rmi4_dsx_new_function(&proximity_module, true); - - return 0; -} - -static void __exit rmi4_proximity_module_exit(void) -{ - synaptics_rmi4_dsx_new_function(&proximity_module, false); - - wait_for_completion(&prox_remove_complete); - - return; -} - -module_init(rmi4_proximity_module_init); -module_exit(rmi4_proximity_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX Proximity Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c deleted file mode 100644 index 4c341ffb6094..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c +++ /dev/null @@ -1,781 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/gpio.h> -#include <linux/uaccess.h> -#include <linux/cdev.h> -#include <linux/platform_device.h> -#include <linux/input/synaptics_dsx_v2.h> -#include "synaptics_dsx_core.h" - -#define CHAR_DEVICE_NAME "rmi" -#define DEVICE_CLASS_NAME "rmidev" -#define SYSFS_FOLDER_NAME "rmidev" -#define DEV_NUMBER 1 -#define REG_ADDR_LIMIT 0xFFFF - -static ssize_t rmidev_sysfs_data_show(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t rmidev_sysfs_data_store(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t rmidev_sysfs_open_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_release_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, - struct device_attribute *attr, char *buf); - -struct rmidev_handle { - dev_t dev_no; - struct device dev; - struct synaptics_rmi4_data *rmi4_data; - struct kobject *sysfs_dir; - void *data; - bool irq_enabled; -}; - -struct rmidev_data { - int ref_count; - struct cdev main_dev; - struct class *device_class; - struct mutex file_mutex; - struct rmidev_handle *rmi_dev; -}; - -static struct bin_attribute attr_data = { - .attr = { - .name = "data", - .mode = (S_IRUGO | S_IWUSR), - }, - .size = 0, - .read = rmidev_sysfs_data_show, - .write = rmidev_sysfs_data_store, -}; - -static struct device_attribute attrs[] = { - __ATTR(open, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_open_store), - __ATTR(release, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_release_store), - __ATTR(attn_state, S_IRUGO, - rmidev_sysfs_attn_state_show, - synaptics_rmi4_store_error), -}; - -static int rmidev_major_num; - -static struct class *rmidev_device_class; - -static struct rmidev_handle *rmidev; - -DECLARE_COMPLETION(rmidev_remove_complete); - -static irqreturn_t rmidev_sysfs_irq(int irq, void *data) -{ - struct synaptics_rmi4_data *rmi4_data = data; - - sysfs_notify(&rmi4_data->input_dev->dev.kobj, - SYSFS_FOLDER_NAME, "attn_state"); - - return IRQ_HANDLED; -} - -static int rmidev_sysfs_irq_enable(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - int retval = 0; - unsigned char intr_status[MAX_INTR_REGISTERS]; - unsigned long irq_flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING; - - if (enable) { - if (rmidev->irq_enabled) - return retval; - - /* Clear interrupts first */ - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr + 1, - intr_status, - rmi4_data->num_of_intr_regs); - if (retval < 0) - return retval; - - retval = request_threaded_irq(rmi4_data->irq, NULL, - rmidev_sysfs_irq, irq_flags, - "synaptics_dsx_rmidev", rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create irq thread\n", - __func__); - return retval; - } - - rmidev->irq_enabled = true; - } else { - if (rmidev->irq_enabled) { - disable_irq(rmi4_data->irq); - free_irq(rmi4_data->irq, rmi4_data); - rmidev->irq_enabled = false; - } - } - - return retval; -} - -static ssize_t rmidev_sysfs_data_show(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - int retval; - unsigned int length = (unsigned int)count; - unsigned short address = (unsigned short)pos; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (length > (REG_ADDR_LIMIT - address)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Out of register map limit\n", - __func__); - return -EINVAL; - } - - if (length) { - retval = synaptics_rmi4_reg_read(rmi4_data, - address, - (unsigned char *)buf, - length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read data\n", - __func__); - return retval; - } - } else { - return -EINVAL; - } - - return length; -} - -static ssize_t rmidev_sysfs_data_store(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - int retval; - unsigned int length = (unsigned int)count; - unsigned short address = (unsigned short)pos; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (length > (REG_ADDR_LIMIT - address)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Out of register map limit\n", - __func__); - return -EINVAL; - } - - if (length) { - retval = synaptics_rmi4_reg_write(rmi4_data, - address, - (unsigned char *)buf, - length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write data\n", - __func__); - return retval; - } - } else { - return -EINVAL; - } - - return length; -} - -static ssize_t rmidev_sysfs_open_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - rmi4_data->irq_enable(rmi4_data, false); - rmidev_sysfs_irq_enable(rmi4_data, true); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt disabled\n", - __func__); - - return count; -} - -static ssize_t rmidev_sysfs_release_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - rmi4_data->reset_device(rmi4_data); - - rmidev_sysfs_irq_enable(rmi4_data, false); - rmi4_data->irq_enable(rmi4_data, true); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt enabled\n", - __func__); - - return count; -} - -static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int attn_state; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - attn_state = gpio_get_value(bdata->irq_gpio); - - return snprintf(buf, PAGE_SIZE, "%u\n", attn_state); -} - -/* - * rmidev_llseek - used to set up register address - * - * @filp: file structure for seek - * @off: offset - * if whence == SEEK_SET, - * high 16 bits: page address - * low 16 bits: register address - * if whence == SEEK_CUR, - * offset from current position - * if whence == SEEK_END, - * offset from end position (0xFFFF) - * @whence: SEEK_SET, SEEK_CUR, or SEEK_END - */ -static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence) -{ - loff_t newpos; - struct rmidev_data *dev_data = filp->private_data; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - mutex_lock(&(dev_data->file_mutex)); - - switch (whence) { - case SEEK_SET: - newpos = off; - break; - case SEEK_CUR: - newpos = filp->f_pos + off; - break; - case SEEK_END: - newpos = REG_ADDR_LIMIT + off; - break; - default: - newpos = -EINVAL; - goto clean_up; - } - - if (newpos < 0 || newpos > REG_ADDR_LIMIT) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: New position 0x%04x is invalid\n", - __func__, (unsigned int)newpos); - newpos = -EINVAL; - goto clean_up; - } - - filp->f_pos = newpos; - -clean_up: - mutex_unlock(&(dev_data->file_mutex)); - - return newpos; -} - -/* - * rmidev_read: - use to read data from rmi device - * - * @filp: file structure for read - * @buf: user space buffer pointer - * @count: number of bytes to read - * @f_pos: offset (starting register address) - */ -static ssize_t rmidev_read(struct file *filp, char __user *buf, - size_t count, loff_t *f_pos) -{ - ssize_t retval; - unsigned char tmpbuf[count + 1]; - struct rmidev_data *dev_data = filp->private_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - if (count == 0) - return 0; - - if (count > (REG_ADDR_LIMIT - *f_pos)) - count = REG_ADDR_LIMIT - *f_pos; - - mutex_lock(&(dev_data->file_mutex)); - - retval = synaptics_rmi4_reg_read(rmidev->rmi4_data, - *f_pos, - tmpbuf, - count); - if (retval < 0) - goto clean_up; - - if (copy_to_user(buf, tmpbuf, count)) - retval = -EFAULT; - else - *f_pos += retval; - -clean_up: - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -/* - * rmidev_write: - used to write data to rmi device - * - * @filep: file structure for write - * @buf: user space buffer pointer - * @count: number of bytes to write - * @f_pos: offset (starting register address) - */ -static ssize_t rmidev_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - ssize_t retval; - unsigned char tmpbuf[count + 1]; - struct rmidev_data *dev_data = filp->private_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - if (count == 0) - return 0; - - if (count > (REG_ADDR_LIMIT - *f_pos)) - count = REG_ADDR_LIMIT - *f_pos; - - if (copy_from_user(tmpbuf, buf, count)) - return -EFAULT; - - mutex_lock(&(dev_data->file_mutex)); - - retval = synaptics_rmi4_reg_write(rmidev->rmi4_data, - *f_pos, - tmpbuf, - count); - if (retval >= 0) - *f_pos += retval; - - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -/* - * rmidev_open: enable access to rmi device - * @inp: inode struture - * @filp: file structure - */ -static int rmidev_open(struct inode *inp, struct file *filp) -{ - int retval = 0; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - struct rmidev_data *dev_data = - container_of(inp->i_cdev, struct rmidev_data, main_dev); - - if (!dev_data) - return -EACCES; - - filp->private_data = dev_data; - - mutex_lock(&(dev_data->file_mutex)); - - rmi4_data->irq_enable(rmi4_data, false); - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt disabled\n", - __func__); - - if (dev_data->ref_count < 1) - dev_data->ref_count++; - else - retval = -EACCES; - - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -/* - * rmidev_release: - release access to rmi device - * @inp: inode structure - * @filp: file structure - */ -static int rmidev_release(struct inode *inp, struct file *filp) -{ - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - struct rmidev_data *dev_data = - container_of(inp->i_cdev, struct rmidev_data, main_dev); - - if (!dev_data) - return -EACCES; - - rmi4_data->reset_device(rmi4_data); - - mutex_lock(&(dev_data->file_mutex)); - - dev_data->ref_count--; - if (dev_data->ref_count < 0) - dev_data->ref_count = 0; - - rmi4_data->irq_enable(rmi4_data, true); - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt enabled\n", - __func__); - - mutex_unlock(&(dev_data->file_mutex)); - - return 0; -} - -static const struct file_operations rmidev_fops = { - .owner = THIS_MODULE, - .llseek = rmidev_llseek, - .read = rmidev_read, - .write = rmidev_write, - .open = rmidev_open, - .release = rmidev_release, -}; - -static void rmidev_device_cleanup(struct rmidev_data *dev_data) -{ - dev_t devno; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (dev_data) { - devno = dev_data->main_dev.dev; - - if (dev_data->device_class) - device_destroy(dev_data->device_class, devno); - - cdev_del(&dev_data->main_dev); - - unregister_chrdev_region(devno, 1); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: rmidev device removed\n", - __func__); - } - - return; -} - -static char *rmi_char_devnode(struct device *dev, umode_t *mode) -{ - if (!mode) - return NULL; - - *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - - return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev)); -} - -static int rmidev_create_device_class(void) -{ - rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME); - - if (IS_ERR(rmidev_device_class)) { - pr_err("%s: Failed to create /dev/%s\n", - __func__, CHAR_DEVICE_NAME); - return -ENODEV; - } - - rmidev_device_class->devnode = rmi_char_devnode; - - return 0; -} - -static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - dev_t dev_no; - unsigned char attr_count; - struct rmidev_data *dev_data; - struct device *device_ptr; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL); - if (!rmidev) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for rmidev\n", - __func__); - retval = -ENOMEM; - goto err_rmidev; - } - - rmidev->rmi4_data = rmi4_data; - - retval = rmidev_create_device_class(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create device class\n", - __func__); - goto err_device_class; - } - - if (rmidev_major_num) { - dev_no = MKDEV(rmidev_major_num, DEV_NUMBER); - retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME); - } else { - retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate char device region\n", - __func__); - goto err_device_region; - } - - rmidev_major_num = MAJOR(dev_no); - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Major number of rmidev = %d\n", - __func__, rmidev_major_num); - } - - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); - if (!dev_data) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for dev_data\n", - __func__); - retval = -ENOMEM; - goto err_dev_data; - } - - mutex_init(&dev_data->file_mutex); - dev_data->rmi_dev = rmidev; - rmidev->data = dev_data; - - cdev_init(&dev_data->main_dev, &rmidev_fops); - - retval = cdev_add(&dev_data->main_dev, dev_no, 1); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to add rmi char device\n", - __func__); - goto err_char_device; - } - - dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no)); - dev_data->device_class = rmidev_device_class; - - device_ptr = device_create(dev_data->device_class, NULL, dev_no, - NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no)); - if (IS_ERR(device_ptr)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create rmi char device\n", - __func__); - retval = -ENODEV; - goto err_char_device; - } - - retval = gpio_export(bdata->irq_gpio, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to export attention gpio\n", - __func__); - } else { - retval = gpio_export_link(&(rmi4_data->input_dev->dev), - "attn", bdata->irq_gpio); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s Failed to create gpio symlink\n", - __func__); - } else { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Exported attention gpio %d\n", - __func__, bdata->irq_gpio); - } - } - - rmidev->sysfs_dir = kobject_create_and_add(SYSFS_FOLDER_NAME, - &rmi4_data->input_dev->dev.kobj); - if (!rmidev->sysfs_dir) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs directory\n", - __func__); - retval = -ENODEV; - goto err_sysfs_dir; - } - - retval = sysfs_create_bin_file(rmidev->sysfs_dir, - &attr_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs bin file\n", - __func__); - goto err_sysfs_bin; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(rmidev->sysfs_dir, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs attributes\n", - __func__); - retval = -ENODEV; - goto err_sysfs_attrs; - } - } - - return 0; - -err_sysfs_attrs: - for (attr_count--; attr_count >= 0; attr_count--) - sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); - - sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data); - -err_sysfs_bin: - kobject_put(rmidev->sysfs_dir); - -err_sysfs_dir: -err_char_device: - rmidev_device_cleanup(dev_data); - kfree(dev_data); - -err_dev_data: - unregister_chrdev_region(dev_no, 1); - -err_device_region: - class_destroy(rmidev_device_class); - -err_device_class: - kfree(rmidev); - rmidev = NULL; - -err_rmidev: - return retval; -} - -static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char attr_count; - struct rmidev_data *dev_data; - - if (!rmidev) - goto exit; - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) - sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); - - sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data); - - kobject_put(rmidev->sysfs_dir); - - dev_data = rmidev->data; - if (dev_data) { - rmidev_device_cleanup(dev_data); - kfree(dev_data); - } - - unregister_chrdev_region(rmidev->dev_no, 1); - - class_destroy(rmidev_device_class); - - kfree(rmidev); - rmidev = NULL; - -exit: - complete(&rmidev_remove_complete); - - return; -} - -static struct synaptics_rmi4_exp_fn rmidev_module = { - .fn_type = RMI_DEV, - .init = rmidev_init_device, - .remove = rmidev_remove_device, - .reset = NULL, - .reinit = NULL, - .early_suspend = NULL, - .suspend = NULL, - .resume = NULL, - .late_resume = NULL, - .attn = NULL, -}; - -static int __init rmidev_module_init(void) -{ - synaptics_rmi4_dsx_new_function(&rmidev_module, true); - - return 0; -} - -static void __exit rmidev_module_exit(void) -{ - synaptics_rmi4_dsx_new_function(&rmidev_module, false); - - wait_for_completion(&rmidev_remove_complete); - - return; -} - -module_init(rmidev_module_init); -module_exit(rmidev_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX RMI Dev Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_spi.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_spi.c deleted file mode 100755 index dd797eef3be1..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_spi.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/spi/spi.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/types.h> -#include <linux/platform_device.h> -#include <linux/input/synaptics_dsx.h> -#include "synaptics_dsx_core.h" - -#define SPI_READ 0x80 -#define SPI_WRITE 0x00 - -static int synaptics_rmi4_spi_set_page(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr) -{ - int retval; - unsigned int index; - unsigned int xfer_count = PAGE_SELECT_LEN + 1; - unsigned char txbuf[xfer_count]; - unsigned char page; - struct spi_message msg; - struct spi_transfer xfers[xfer_count]; - struct spi_device *spi = to_spi_device(rmi4_data->pdev->dev.parent); - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - page = ((addr >> 8) & ~MASK_7BIT); - if (page != rmi4_data->current_page) { - spi_message_init(&msg); - - txbuf[0] = SPI_WRITE; - txbuf[1] = MASK_8BIT; - txbuf[2] = page; - - for (index = 0; index < xfer_count; index++) { - memset(&xfers[index], 0, sizeof(struct spi_transfer)); - xfers[index].len = 1; - xfers[index].delay_usecs = bdata->byte_delay_us; - xfers[index].tx_buf = &txbuf[index]; - spi_message_add_tail(&xfers[index], &msg); - } - - if (bdata->block_delay_us) - xfers[index - 1].delay_usecs = bdata->block_delay_us; - - retval = spi_sync(spi, &msg); - if (retval == 0) { - rmi4_data->current_page = page; - retval = PAGE_SELECT_LEN; - } else { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to complete SPI transfer, error = %d\n", - __func__, retval); - } - } else { - retval = PAGE_SELECT_LEN; - } - - return retval; -} - -static int synaptics_rmi4_spi_read(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, unsigned char *data, unsigned short length) -{ - int retval; - unsigned int index; - unsigned int xfer_count = length + ADDRESS_WORD_LEN; - unsigned char txbuf[ADDRESS_WORD_LEN]; - unsigned char *rxbuf = NULL; - struct spi_message msg; - struct spi_transfer *xfers = NULL; - struct spi_device *spi = to_spi_device(rmi4_data->pdev->dev.parent); - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - spi_message_init(&msg); - - xfers = kcalloc(xfer_count, sizeof(struct spi_transfer), GFP_KERNEL); - if (!xfers) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate memory for xfers\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - txbuf[0] = (addr >> 8) | SPI_READ; - txbuf[1] = addr & MASK_8BIT; - - rxbuf = kmalloc(length, GFP_KERNEL); - if (!rxbuf) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate memory for rxbuf\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - retval = synaptics_rmi4_spi_set_page(rmi4_data, addr); - if (retval != PAGE_SELECT_LEN) { - retval = -EIO; - goto exit; - } - - for (index = 0; index < xfer_count; index++) { - xfers[index].len = 1; - xfers[index].delay_usecs = bdata->byte_delay_us; - if (index < ADDRESS_WORD_LEN) - xfers[index].tx_buf = &txbuf[index]; - else - xfers[index].rx_buf = &rxbuf[index - ADDRESS_WORD_LEN]; - spi_message_add_tail(&xfers[index], &msg); - } - - if (bdata->block_delay_us) - xfers[index - 1].delay_usecs = bdata->block_delay_us; - - retval = spi_sync(spi, &msg); - if (retval == 0) { - retval = length; - memcpy(data, rxbuf, length); - } else { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to complete SPI transfer, error = %d\n", - __func__, retval); - } - - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - -exit: - kfree(rxbuf); - kfree(xfers); - - return retval; -} - -static int synaptics_rmi4_spi_write(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, unsigned char *data, unsigned short length) -{ - int retval; - unsigned int index; - unsigned int xfer_count = length + ADDRESS_WORD_LEN; - unsigned char *txbuf = NULL; - struct spi_message msg; - struct spi_transfer *xfers = NULL; - struct spi_device *spi = to_spi_device(rmi4_data->pdev->dev.parent); - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - spi_message_init(&msg); - - xfers = kcalloc(xfer_count, sizeof(struct spi_transfer), GFP_KERNEL); - if (!xfers) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate memory for xfers\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - txbuf = kmalloc(xfer_count, GFP_KERNEL); - if (!txbuf) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate memory for txbuf\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - txbuf[0] = (addr >> 8) & ~SPI_READ; - txbuf[1] = addr & MASK_8BIT; - memcpy(&txbuf[ADDRESS_WORD_LEN], data, length); - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - retval = synaptics_rmi4_spi_set_page(rmi4_data, addr); - if (retval != PAGE_SELECT_LEN) { - retval = -EIO; - goto exit; - } - - for (index = 0; index < xfer_count; index++) { - xfers[index].len = 1; - xfers[index].delay_usecs = bdata->byte_delay_us; - xfers[index].tx_buf = &txbuf[index]; - spi_message_add_tail(&xfers[index], &msg); - } - - if (bdata->block_delay_us) - xfers[index - 1].delay_usecs = bdata->block_delay_us; - - retval = spi_sync(spi, &msg); - if (retval == 0) { - retval = length; - } else { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to complete SPI transfer, error = %d\n", - __func__, retval); - } - - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - -exit: - kfree(txbuf); - kfree(xfers); - - return retval; -} - -static struct synaptics_dsx_bus_access bus_access = { - .type = BUS_SPI, - .read = synaptics_rmi4_spi_read, - .write = synaptics_rmi4_spi_write, -}; - -static struct synaptics_dsx_hw_interface hw_if; - -static struct platform_device *synaptics_dsx_spi_device; - -static void synaptics_rmi4_spi_dev_release(struct device *dev) -{ - kfree(synaptics_dsx_spi_device); - - return; -} - -static int synaptics_rmi4_spi_probe(struct spi_device *spi) -{ - int retval; - - if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) { - dev_err(&spi->dev, - "%s: Full duplex not supported by host\n", - __func__); - return -EIO; - } - - synaptics_dsx_spi_device = kzalloc( - sizeof(struct platform_device), - GFP_KERNEL); - if (!synaptics_dsx_spi_device) { - dev_err(&spi->dev, - "%s: Failed to allocate memory for synaptics_dsx_spi_device\n", - __func__); - return -ENOMEM; - } - - spi->bits_per_word = 8; - spi->mode = SPI_MODE_3; - - retval = spi_setup(spi); - if (retval < 0) { - dev_err(&spi->dev, - "%s: Failed to perform SPI setup\n", - __func__); - return retval; - } - - hw_if.board_data = spi->dev.platform_data; - hw_if.bus_access = &bus_access; - - synaptics_dsx_spi_device->name = PLATFORM_DRIVER_NAME; - synaptics_dsx_spi_device->id = 0; - synaptics_dsx_spi_device->num_resources = 0; - synaptics_dsx_spi_device->dev.parent = &spi->dev; - synaptics_dsx_spi_device->dev.platform_data = &hw_if; - synaptics_dsx_spi_device->dev.release = synaptics_rmi4_spi_dev_release; - - retval = platform_device_register(synaptics_dsx_spi_device); - if (retval) { - dev_err(&spi->dev, - "%s: Failed to register platform device\n", - __func__); - return -ENODEV; - } - - return 0; -} - -static int synaptics_rmi4_spi_remove(struct spi_device *spi) -{ - platform_device_unregister(synaptics_dsx_spi_device); - - return 0; -} - -static struct spi_driver synaptics_rmi4_spi_driver = { - .driver = { - .name = SPI_DRIVER_NAME, - .owner = THIS_MODULE, - }, - .probe = synaptics_rmi4_spi_probe, - .remove = __devexit_p(synaptics_rmi4_spi_remove), -}; - - -int synaptics_rmi4_bus_init(void) -{ - return spi_register_driver(&synaptics_rmi4_spi_driver); -} -EXPORT_SYMBOL(synaptics_rmi4_bus_init); - -void synaptics_rmi4_bus_exit(void) -{ - spi_unregister_driver(&synaptics_rmi4_spi_driver); - - return; -} -EXPORT_SYMBOL(synaptics_rmi4_bus_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX SPI Bus Support Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c deleted file mode 100644 index 911e4d7d4103..000000000000 --- a/drivers/input/touchscreen/synaptics_fw_update.c +++ /dev/null @@ -1,2306 +0,0 @@ -/* - * Synaptics RMI4 touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/firmware.h> -#include <linux/string.h> -#include <linux/input/synaptics_dsx.h> -#include "synaptics_i2c_rmi4.h" - -#define SHOW_PROGRESS -#define MAX_FIRMWARE_ID_LEN 10 -#define FORCE_UPDATE false -#define INSIDE_FIRMWARE_UPDATE - -#define FW_IMAGE_OFFSET 0x100 -/* 0 to ignore flash block check to speed up flash time */ -#define CHECK_FLASH_BLOCK_STATUS 1 - -#define REG_MAP (1 << 0) -#define UNLOCKED (1 << 1) -#define HAS_CONFIG_ID (1 << 2) -#define HAS_PERM_CONFIG (1 << 3) -#define HAS_BL_CONFIG (1 << 4) -#define HAS_DISP_CONFIG (1 << 5) -#define HAS_CTRL1 (1 << 6) - -#define RMI4_INFO_MAX_LEN 200 - -#define RMI4_STORE_TS_INFO(buf, id, rev, fw_ver) \ - snprintf(buf, RMI4_INFO_MAX_LEN, \ - "controller\t= synaptics\n" \ - "model\t\t= %d rev %d\n" \ - "fw_ver\t\t= %d\n", id, rev, fw_ver) - -enum falsh_config_area { - UI_CONFIG_AREA = 0x00, - PERM_CONFIG_AREA = 0x01, - BL_CONFIG_AREA = 0x02, - DISP_CONFIG_AREA = 0x03 -}; - -enum flash_command { - CMD_WRITE_FW_BLOCK = 0x2, - CMD_ERASE_ALL = 0x3, - CMD_WRITE_LOCKDOWN_BLOCK = 0x4, - CMD_READ_CONFIG_BLOCK = 0x5, - CMD_WRITE_CONFIG_BLOCK = 0x6, - CMD_ERASE_CONFIG = 0x7, - CMD_READ_SENSOR_ID = 0x8, - CMD_ERASE_BL_CONFIG = 0x9, - CMD_ERASE_DISP_CONFIG = 0xA, - CMD_ENABLE_FLASH_PROG = 0xF -}; - -enum flash_area { - NONE, - UI_FIRMWARE, - CONFIG_AREA, - MISMATCH -}; - -enum image_file_option { - OPTION_BUILD_INFO = 0, - OPTION_CONTAIN_BOOTLOADER = 1, -}; - -enum flash_offset { - OFFSET_BOOTLOADER_ID, - OFFSET_FLASH_PROPERTIES, - OFFSET_BLOCK_SIZE, - OFFSET_FW_BLOCK_COUNT, - OFFSET_BLOCK_NUMBER, - OFFSET_BLOCK_DATA, - OFFSET_FLASH_CONTROL, - OFFSET_FLASH_STATUS -}; - -enum flash_update_mode { - NORMAL = 1, - FORCE = 2, - LOCKDOWN = 8 -}; - -#define SLEEP_MODE_NORMAL (0x00) -#define SLEEP_MODE_SENSOR_SLEEP (0x01) -#define SLEEP_MODE_RESERVED0 (0x02) -#define SLEEP_MODE_RESERVED1 (0x03) - -#define ENABLE_WAIT_MS (1 * 1000) -#define WRITE_WAIT_MS (3 * 1000) -#define ERASE_WAIT_MS (5 * 1000) -#define RESET_WAIT_MS (500) - -#define SLEEP_TIME_US 100 - -static int fwu_wait_for_idle(int timeout_ms); - -struct image_header_data { - union { - struct { - /* 0x00-0x0F */ - unsigned char file_checksum[4]; - unsigned char reserved_04; - unsigned char reserved_05; - unsigned char options_firmware_id:1; - unsigned char options_contain_bootloader:1; - unsigned char options_reserved:6; - unsigned char bootloader_version; - unsigned char firmware_size[4]; - unsigned char config_size[4]; - /* 0x10-0x1F */ - unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE]; - unsigned char pkg_id_lsb; - unsigned char pkg_id_msb; - unsigned char pkg_id_rev_lsb; - unsigned char pkg_id_rev_msb; - unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; - /* 0x20-0x2F */ - unsigned char reserved_20_2f[0x10]; - /* 0x30-0x3F */ - unsigned char ds_firmware_id[0x10]; - /* 0x40-0x4F */ - unsigned char ds_customize_info[10]; - unsigned char reserved_4a_4f[6]; - /* 0x50-0x53*/ - unsigned char firmware_id[4]; - } __packed; - unsigned char data[0x54]; - }; -}; - -struct image_content { - bool is_contain_build_info; - unsigned int checksum; - unsigned int image_size; - unsigned int config_size; - unsigned char options; - unsigned char bootloader_version; - unsigned char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; - unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; - u16 package_id; - u16 package_revision_id; - unsigned int firmware_id; - const unsigned char *firmware_data; - const unsigned char *config_data; - const unsigned char *lockdown_data; - unsigned short lockdown_block_count; -}; - -struct pdt_properties { - union { - struct { - unsigned char reserved_1:6; - unsigned char has_bsr:1; - unsigned char reserved_2:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f01_device_status { - union { - struct { - unsigned char status_code:4; - unsigned char reserved:2; - unsigned char flash_prog:1; - unsigned char unconfigured:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f01_device_control { - union { - struct { - unsigned char sleep_mode:2; - unsigned char nosleep:1; - unsigned char reserved:2; - unsigned char charger_connected:1; - unsigned char report_rate:1; - unsigned char configured:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f34_flash_control { - union { - /* version 0 */ - struct { - unsigned char command_v0:4; - unsigned char status:3; - unsigned char program_enabled:1; - } __packed; - /* version 1 */ - struct { - unsigned char command_v1:6; - unsigned char reserved:2; - } __packed; - unsigned char data[1]; - }; -}; - -struct f34_flash_status { - union { - struct { - unsigned char status:6; - unsigned char reserved:1; - unsigned char program_enabled:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f34_flash_properties { - union { - struct { - unsigned char regmap:1; - unsigned char unlocked:1; - unsigned char has_configid:1; - unsigned char has_perm_config:1; - unsigned char has_bl_config:1; - unsigned char has_display_config:1; - unsigned char has_blob_config:1; - unsigned char reserved:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_fwu_handle { - bool initialized; - bool force_update; - bool do_lockdown; - bool interrupt_flag; - bool polling_mode; - char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; - unsigned int image_size; - unsigned int data_pos; - unsigned char intr_mask; - unsigned char bootloader_id[2]; - unsigned char productinfo1; - unsigned char productinfo2; - unsigned char *ext_data_source; - unsigned char *read_config_buf; - const unsigned char *firmware_data; - const unsigned char *config_data; - const unsigned char *lockdown_data; - unsigned short block_size; - unsigned short fw_block_count; - unsigned short config_block_count; - unsigned short lockdown_block_count; - unsigned short perm_config_block_count; - unsigned short bl_config_block_count; - unsigned short disp_config_block_count; - unsigned short config_size; - unsigned short config_area; - unsigned short addr_f01_interrupt_register; - const unsigned char *data_buffer; - struct synaptics_rmi4_fn_desc f01_fd; - struct synaptics_rmi4_fn_desc f34_fd; - struct synaptics_rmi4_exp_fn_ptr *fn_ptr; - struct synaptics_rmi4_data *rmi4_data; - struct f34_flash_properties flash_properties; - struct workqueue_struct *fwu_workqueue; - struct delayed_work fwu_work; - char image_name[NAME_BUFFER_SIZE]; - struct image_content image_content; - char *ts_info; -}; - -static struct synaptics_rmi4_fwu_handle *fwu; - -DECLARE_COMPLETION(fwu_remove_complete); - -static unsigned int extract_uint(const unsigned char *ptr) -{ - return (unsigned int)ptr[0] + - (unsigned int)ptr[1] * 0x100 + - (unsigned int)ptr[2] * 0x10000 + - (unsigned int)ptr[3] * 0x1000000; -} - -static unsigned int extract_uint_be(const unsigned char *ptr) -{ - return (unsigned int)ptr[3] + - (unsigned int)ptr[2] * 0x100 + - (unsigned int)ptr[1] * 0x10000 + - (unsigned int)ptr[0] * 0x1000000; -} - -static void synaptics_rmi4_update_debug_info(void) -{ - unsigned char pkg_id[4]; - unsigned int build_id; - struct synaptics_rmi4_device_info *rmi; - /* read device package id */ - fwu->fn_ptr->read(fwu->rmi4_data, - fwu->f01_fd.query_base_addr + 17, - pkg_id, - sizeof(pkg_id)); - rmi = &(fwu->rmi4_data->rmi4_mod_info); - - build_id = (unsigned int)rmi->build_id[0] + - (unsigned int)rmi->build_id[1] * 0x100 + - (unsigned int)rmi->build_id[2] * 0x10000; - - RMI4_STORE_TS_INFO(fwu->ts_info, pkg_id[1] << 8 | pkg_id[0], - pkg_id[3] << 8 | pkg_id[2], build_id); -} - -static void parse_header(void) -{ - struct image_content *img = &fwu->image_content; - struct image_header_data *data = - (struct image_header_data *)fwu->data_buffer; - img->checksum = extract_uint(data->file_checksum); - img->bootloader_version = data->bootloader_version; - img->image_size = extract_uint(data->firmware_size); - img->config_size = extract_uint(data->config_size); - memcpy(img->product_id, data->product_id, - sizeof(data->product_id)); - img->product_id[sizeof(data->product_id)] = 0; - - img->product_id[sizeof(data->product_info)] = 0; - memcpy(img->product_info, data->product_info, - sizeof(data->product_info)); - - img->is_contain_build_info = - (data->options_firmware_id == (1 << OPTION_BUILD_INFO)); - - if (img->is_contain_build_info) { - img->package_id = (data->pkg_id_msb << 8) | - data->pkg_id_lsb; - img->package_revision_id = (data->pkg_id_rev_msb << 8) | - data->pkg_id_rev_lsb; - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s Package ID %d Rev %d\n", __func__, - img->package_id, img->package_revision_id); - - img->firmware_id = extract_uint(data->firmware_id); - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s Firwmare build id %d\n", __func__, - img->firmware_id); - } - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "Firwmare size %d, config size %d\n", - img->image_size, - img->config_size); - - /* get UI firmware offset */ - if (img->image_size) - img->firmware_data = fwu->data_buffer + FW_IMAGE_OFFSET; - /* get config offset*/ - if (img->config_size) - img->config_data = fwu->data_buffer + FW_IMAGE_OFFSET + - img->image_size; - /* get lockdown offset*/ - switch (img->bootloader_version) { - case 3: - case 4: - img->lockdown_block_count = 4; - break; - case 5: - case 6: - img->lockdown_block_count = 5; - break; - default: - dev_warn(&fwu->rmi4_data->i2c_client->dev, - "%s: Not support lockdown in " \ - "bootloader version V%d\n", - __func__, img->bootloader_version); - img->lockdown_data = NULL; - } - - img->lockdown_data = fwu->data_buffer + - FW_IMAGE_OFFSET - - img->lockdown_block_count * fwu->block_size; - - fwu->lockdown_block_count = img->lockdown_block_count; - fwu->lockdown_data = img->lockdown_data; - fwu->config_data = img->config_data; - fwu->firmware_data = img->firmware_data; - return; -} - -static int fwu_read_f01_device_status(struct f01_device_status *status) -{ - int retval; - - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu->f01_fd.data_base_addr, - status->data, - sizeof(status->data)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to read F01 device status\n", - __func__); - return retval; - } - - return 0; -} - -static unsigned short fwu_get_address(enum flash_offset type) -{ - int offset; - unsigned short addr = 0; - struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client; - - switch (type) { - case OFFSET_BOOTLOADER_ID: - offset = 0; - addr = fwu->f34_fd.query_base_addr + offset; - break; - case OFFSET_FLASH_PROPERTIES: - offset = ((fwu->f34_fd.version == 0) ? 2 : 1); - addr = fwu->f34_fd.query_base_addr + offset; - break; - case OFFSET_BLOCK_SIZE: - offset = ((fwu->f34_fd.version == 0) ? 3 : 2); - addr = fwu->f34_fd.query_base_addr + offset; - break; - case OFFSET_FW_BLOCK_COUNT: - offset = ((fwu->f34_fd.version == 0) ? 5 : 3); - addr = fwu->f34_fd.query_base_addr + offset; - break; - case OFFSET_BLOCK_NUMBER: - offset = 0; - addr = fwu->f34_fd.data_base_addr + offset; - break; - case OFFSET_BLOCK_DATA: - offset = ((fwu->f34_fd.version == 0) ? 2 : 1); - addr = fwu->f34_fd.data_base_addr + offset; - break; - case OFFSET_FLASH_CONTROL: - offset = ((fwu->f34_fd.version == 0) ? - 2 + (fwu->block_size) : 2); - addr = fwu->f34_fd.data_base_addr + offset; - break; - case OFFSET_FLASH_STATUS: - if (fwu->f34_fd.version == 1) { - offset = 3; - addr = fwu->f34_fd.data_base_addr + offset; - } else if (fwu->f34_fd.version == 0) { - dev_warn(&i2c_client->dev, - "%s: F$34 version 0 does not contain " \ - "flash status register\n", - __func__); - } - break; - default: - dev_err(&i2c_client->dev, - "%s: Unknown flash offset (%d)\n", - __func__, type); - break; - } - return addr; -} - -static int fwu_read_f34_queries(void) -{ - int retval; - unsigned char count = 4; - unsigned char buf[10]; - struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client; - - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu_get_address(OFFSET_BOOTLOADER_ID), - fwu->bootloader_id, - sizeof(fwu->bootloader_id)); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to read bootloader ID\n", - __func__); - return retval; - } - - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu_get_address(OFFSET_FLASH_PROPERTIES), - fwu->flash_properties.data, - sizeof(fwu->flash_properties.data)); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to read flash properties\n", - __func__); - return retval; - } - - dev_info(&i2c_client->dev, "%s perm:%d, bl:%d, display:%d\n", - __func__, - fwu->flash_properties.has_perm_config, - fwu->flash_properties.has_bl_config, - fwu->flash_properties.has_display_config); - - if (fwu->flash_properties.has_perm_config) - count += 2; - - if (fwu->flash_properties.has_bl_config) - count += 2; - - if (fwu->flash_properties.has_display_config) - count += 2; - - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu_get_address(OFFSET_BLOCK_SIZE), - buf, - 2); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to read block size info\n", - __func__); - return retval; - } - - batohs(&fwu->block_size, &(buf[0])); - - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu_get_address(OFFSET_FW_BLOCK_COUNT), - buf, - count); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to read block count info\n", - __func__); - return retval; - } - - batohs(&fwu->fw_block_count, &(buf[0])); - batohs(&fwu->config_block_count, &(buf[2])); - - count = 4; - - if (fwu->flash_properties.has_perm_config) { - batohs(&fwu->perm_config_block_count, &(buf[count])); - count += 2; - } - - if (fwu->flash_properties.has_bl_config) { - batohs(&fwu->bl_config_block_count, &(buf[count])); - count += 2; - } - - if (fwu->flash_properties.has_display_config) - batohs(&fwu->disp_config_block_count, &(buf[count])); - - return 0; -} - -static int fwu_read_interrupt_status(void) -{ - int retval; - unsigned char interrupt_status; - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu->addr_f01_interrupt_register, - &interrupt_status, - sizeof(interrupt_status)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to read flash status\n", - __func__); - return retval; - } - return interrupt_status; -} - -static int fwu_read_f34_flash_status(unsigned char *status) -{ - int retval; - struct f34_flash_control flash_control; - struct f34_flash_status flash_status; - - if (fwu->f34_fd.version == 1) { - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu_get_address(OFFSET_FLASH_STATUS), - flash_status.data, - sizeof(flash_status.data)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to read flash status\n", - __func__); - return -EIO; - } - *status = flash_status.status; - } else { - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu_get_address(OFFSET_FLASH_CONTROL), - flash_control.data, - sizeof(flash_control.data)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to read flash status\n", - __func__); - return -EIO; - } - *status = flash_control.status; - } - return 0; -} - -static int fwu_reset_device(void) -{ - int retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Reset device\n", - __func__); - - retval = fwu->rmi4_data->reset_device(fwu->rmi4_data); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to reset core driver after reflash\n", - __func__); - return retval; - } - - fwu->polling_mode = false; - - return 0; -} - -static int fwu_write_f34_command(unsigned char cmd) -{ - int retval; - struct f34_flash_control flash_control; - - flash_control.data[0] = cmd; - fwu->interrupt_flag = false; - retval = fwu->fn_ptr->write(fwu->rmi4_data, - fwu_get_address(OFFSET_FLASH_CONTROL), - flash_control.data, - sizeof(flash_control.data)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to write command 0x%02x\n", - __func__, flash_control.data[0]); - return retval; - } - return 0; -} - -static int fwu_wait_for_idle(int timeout_ms) -{ - int count = 0; - int timeout_count = ((timeout_ms * 1000) / SLEEP_TIME_US) + 1; - do { - if (fwu->interrupt_flag) - return 0; - if (fwu->polling_mode) - if (fwu->intr_mask & fwu_read_interrupt_status()) - return 0; - usleep_range(SLEEP_TIME_US, SLEEP_TIME_US + 1); - } while (count++ < timeout_count); - - if (fwu->intr_mask & fwu_read_interrupt_status()) { - fwu->polling_mode = true; - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s: Switch to polling mode\n", - __func__); - return 0; - } - - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Timed out waiting for idle status\n", - __func__); - - return -ETIMEDOUT; -} - -static enum flash_area fwu_go_nogo(void) -{ - int retval = 0; - int index = 0; - int deviceFirmwareID; - int imageConfigID; - int deviceConfigID; - unsigned long imageFirmwareID; - unsigned char firmware_id[4]; - unsigned char config_id[4]; - unsigned char pkg_id[4]; - char *strptr; - char *imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL); - enum flash_area flash_area = NONE; - struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client; - struct f01_device_status f01_device_status; - struct image_content *img = &fwu->image_content; - - if (fwu->force_update) { - flash_area = UI_FIRMWARE; - goto exit; - } - - if (img->is_contain_build_info) { - /* if package id does not match, do not update firmware */ - fwu->fn_ptr->read(fwu->rmi4_data, - fwu->f01_fd.query_base_addr + 17, - pkg_id, - sizeof(pkg_id)); - - if (img->package_id != ((pkg_id[1] << 8) | pkg_id[0])) { - flash_area = MISMATCH; - goto exit; - } - if (img->package_revision_id != - ((pkg_id[3] << 8) | pkg_id[2])) { - flash_area = MISMATCH; - goto exit; - } - } - - /* check firmware size */ - if (fwu->fw_block_count*fwu->block_size != img->image_size) { - dev_err(&i2c_client->dev, - "%s: firmware size of device (%d) != .img (%d)\n", - __func__, - fwu->config_block_count * fwu->block_size, - img->image_size); - flash_area = NONE; - goto exit; - } - - /* check config size */ - if (fwu->config_block_count*fwu->block_size != img->config_size) { - dev_err(&i2c_client->dev, - "%s: config size of device (%d) != .img (%d)\n", - __func__, - fwu->config_block_count * fwu->block_size, - img->config_size); - flash_area = NONE; - goto exit; - } - - retval = fwu_read_f01_device_status(&f01_device_status); - if (retval < 0) { - flash_area = NONE; - goto exit; - } - - /* Force update firmware when device is in bootloader mode */ - if (f01_device_status.flash_prog) { - dev_info(&i2c_client->dev, - "%s: In flash prog mode\n", - __func__); - flash_area = UI_FIRMWARE; - goto exit; - } - - /* device firmware id */ - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu->f01_fd.query_base_addr + 18, - firmware_id, - sizeof(firmware_id)); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to read firmware ID (code %d).\n", - __func__, retval); - goto exit; - } - firmware_id[3] = 0; - deviceFirmwareID = extract_uint(firmware_id); - - /* .img firmware id */ - if (img->is_contain_build_info) { - dev_err(&i2c_client->dev, - "%s: Image option contains build info.\n", - __func__); - imageFirmwareID = img->firmware_id; - } else { - if (!fwu->image_name) { - dev_info(&i2c_client->dev, - "%s: Unknown image file name\n", - __func__); - flash_area = UI_FIRMWARE; - goto exit; - } - strptr = strnstr(fwu->image_name, "PR", - sizeof(fwu->image_name)); - if (!strptr) { - dev_err(&i2c_client->dev, - "No valid PR number (PRxxxxxxx)" \ - "found in image file name...\n"); - goto exit; - } - - strptr += 2; - while (strptr[index] >= '0' && strptr[index] <= '9') { - imagePR[index] = strptr[index]; - index++; - } - imagePR[index] = 0; - - retval = kstrtoul(imagePR, 10, &imageFirmwareID); - if (retval == -EINVAL) { - dev_err(&i2c_client->dev, - "invalid image firmware id...\n"); - goto exit; - } - } - - dev_dbg(&i2c_client->dev, - "Device firmware id %d, .img firmware id %d\n", - deviceFirmwareID, - (unsigned int)imageFirmwareID); - if (imageFirmwareID > deviceFirmwareID) { - flash_area = UI_FIRMWARE; - goto exit; - } else if (imageFirmwareID < deviceFirmwareID) { - flash_area = NONE; - dev_info(&i2c_client->dev, - "%s: Img fw is older than device fw. Skip fw update.\n", - __func__); - goto exit; - } - - /* device config id */ - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu->f34_fd.ctrl_base_addr, - config_id, - sizeof(config_id)); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to read config ID (code %d).\n", - __func__, retval); - flash_area = NONE; - goto exit; - } - deviceConfigID = extract_uint_be(config_id); - - dev_dbg(&i2c_client->dev, - "Device config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", - config_id[0], config_id[1], config_id[2], config_id[3]); - - /* .img config id */ - dev_dbg(&i2c_client->dev, - ".img config ID 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", - fwu->config_data[0], - fwu->config_data[1], - fwu->config_data[2], - fwu->config_data[3]); - imageConfigID = extract_uint_be(fwu->config_data); - - dev_dbg(&i2c_client->dev, - "%s: Device config ID %d, .img config ID %d\n", - __func__, deviceConfigID, imageConfigID); - - if (imageConfigID > deviceConfigID) { - flash_area = CONFIG_AREA; - goto exit; - } -exit: - kfree(imagePR); - if (flash_area == MISMATCH) - dev_info(&i2c_client->dev, - "%s: Package ID indicates mismatch of firmware and" \ - " controller compatibility\n", __func__); - else if (flash_area == NONE) - dev_info(&i2c_client->dev, - "%s: Nothing needs to be updated\n", __func__); - else - dev_info(&i2c_client->dev, - "%s: Update %s block\n", __func__, - flash_area == UI_FIRMWARE ? "UI FW" : "CONFIG"); - return flash_area; -} - -static int fwu_scan_pdt(void) -{ - int retval; - unsigned char ii; - unsigned char intr_count = 0; - unsigned char intr_off; - unsigned char intr_src; - unsigned short addr; - bool f01found = false; - bool f34found = false; - struct synaptics_rmi4_fn_desc rmi_fd; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, "Scan PDT\n"); - - for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) { - retval = fwu->fn_ptr->read(fwu->rmi4_data, - addr, - (unsigned char *)&rmi_fd, - sizeof(rmi_fd)); - if (retval < 0) - return retval; - - if (rmi_fd.fn_number) { - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Found F%02x\n", - __func__, rmi_fd.fn_number); - switch (rmi_fd.fn_number) { - case SYNAPTICS_RMI4_F01: - f01found = true; - fwu->f01_fd = rmi_fd; - fwu->addr_f01_interrupt_register = - fwu->f01_fd.data_base_addr + 1; - break; - case SYNAPTICS_RMI4_F34: - f34found = true; - fwu->f34_fd = rmi_fd; - fwu->intr_mask = 0; - intr_src = rmi_fd.intr_src_count; - intr_off = intr_count % 8; - for (ii = intr_off; - ii < ((intr_src & MASK_3BIT) + - intr_off); - ii++) - fwu->intr_mask |= 1 << ii; - break; - } - } else - break; - - intr_count += (rmi_fd.intr_src_count & MASK_3BIT); - } - - if (!f01found || !f34found) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to find both F01 and F34\n", - __func__); - return -EINVAL; - } - - fwu_read_interrupt_status(); - return 0; -} - -static int fwu_write_blocks(unsigned char *block_ptr, unsigned short block_cnt, - unsigned char command) -{ - int retval; - unsigned char flash_status; - unsigned char block_offset[] = {0, 0}; - unsigned short block_num; - unsigned short addr_block_data = fwu_get_address(OFFSET_BLOCK_DATA); - unsigned short addr_block_num = fwu_get_address(OFFSET_BLOCK_NUMBER); - struct i2c_client *i2c_client = fwu->rmi4_data->i2c_client; -#ifdef SHOW_PROGRESS - unsigned int progress; - unsigned char command_str[10]; - switch (command) { - case CMD_WRITE_CONFIG_BLOCK: - progress = 10; - strlcpy(command_str, "config", 10); - break; - case CMD_WRITE_FW_BLOCK: - progress = 100; - strlcpy(command_str, "firmware", 10); - break; - case CMD_WRITE_LOCKDOWN_BLOCK: - progress = 1; - strlcpy(command_str, "lockdown", 10); - break; - default: - progress = 1; - strlcpy(command_str, "unknown", 10); - break; - } -#endif - - dev_dbg(&i2c_client->dev, - "%s: Start to update %s blocks\n", - __func__, - command_str); - retval = fwu->fn_ptr->write(fwu->rmi4_data, - addr_block_num, - block_offset, - sizeof(block_offset)); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to write to block number registers\n", - __func__); - return retval; - } - - for (block_num = 0; block_num < block_cnt; block_num++) { -#ifdef SHOW_PROGRESS - if (block_num % progress == 0) - dev_info(&i2c_client->dev, - "%s: update %s %3d / %3d\n", - __func__, - command_str, - block_num, block_cnt); -#endif - retval = fwu->fn_ptr->write(fwu->rmi4_data, - addr_block_data, - block_ptr, - fwu->block_size); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to write block data (block %d)\n", - __func__, block_num); - return retval; - } - - retval = fwu_write_f34_command(command); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to write command for block %d\n", - __func__, block_num); - return retval; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to wait for idle status (block %d)\n", - __func__, block_num); - return retval; - } - - #if CHECK_FLASH_BLOCK_STATUS - retval = fwu_read_f34_flash_status(&flash_status); - if (retval < 0) { - dev_err(&i2c_client->dev, - "%s: Failed to read flash status (block %d)\n", - __func__, block_num); - return retval; - } - if (flash_status != 0x00) { - dev_err(&i2c_client->dev, - "%s: Flash block %d failed, status 0x%02X\n", - __func__, block_num, flash_status); - return -EINVAL; - } - #endif - block_ptr += fwu->block_size; - } -#ifdef SHOW_PROGRESS - dev_info(&i2c_client->dev, - "%s: update %s %3d / %3d\n", - __func__, - command_str, - block_cnt, block_cnt); -#endif - return 0; -} - -static int fwu_write_firmware(void) -{ - return fwu_write_blocks((unsigned char *)fwu->firmware_data, - fwu->fw_block_count, CMD_WRITE_FW_BLOCK); -} - -static int fwu_write_configuration(void) -{ - return fwu_write_blocks((unsigned char *)fwu->config_data, - fwu->config_block_count, CMD_WRITE_CONFIG_BLOCK); -} - -static int fwu_write_lockdown_block(void) -{ - return fwu_write_blocks((unsigned char *)fwu->lockdown_data, - fwu->lockdown_block_count, CMD_WRITE_LOCKDOWN_BLOCK); -} - -static int fwu_write_bootloader_id(void) -{ - int retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "Write bootloader ID 0x%02X 0x%02X\n", - fwu->bootloader_id[0], - fwu->bootloader_id[1]); - - retval = fwu->fn_ptr->write(fwu->rmi4_data, - fwu_get_address(OFFSET_BLOCK_DATA), - fwu->bootloader_id, - sizeof(fwu->bootloader_id)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to write bootloader ID\n", - __func__); - return retval; - } - - return 0; -} - -static int fwu_enter_flash_prog(bool force) -{ - int retval; - struct f01_device_status f01_device_status; - struct f01_device_control f01_device_control; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, "Enter bootloader mode\n"); - - retval = fwu_read_f01_device_status(&f01_device_status); - if (retval < 0) - return retval; - - if (force) { - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s: Force to enter flash prog mode\n", - __func__); - } else if (f01_device_status.flash_prog) { - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s: Already in flash prog mode\n", - __func__); - return 0; - } - - retval = fwu_write_bootloader_id(); - if (retval < 0) - return retval; - - retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG); - if (retval < 0) - return retval; - - retval = fwu_wait_for_idle(ENABLE_WAIT_MS); - if (retval < 0) - return retval; - - retval = fwu_scan_pdt(); - if (retval < 0) - return retval; - - retval = fwu_read_f01_device_status(&f01_device_status); - if (retval < 0) - return retval; - - if (!f01_device_status.flash_prog) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Not in flash prog mode\n", - __func__); - return -EINVAL; - } - - retval = fwu_read_f34_queries(); - if (retval < 0) - return retval; - - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu->f01_fd.ctrl_base_addr, - f01_device_control.data, - sizeof(f01_device_control.data)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to read F01 device control\n", - __func__); - return retval; - } - - f01_device_control.nosleep = true; - f01_device_control.sleep_mode = SLEEP_MODE_NORMAL; - - retval = fwu->fn_ptr->write(fwu->rmi4_data, - fwu->f01_fd.ctrl_base_addr, - f01_device_control.data, - sizeof(f01_device_control.data)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to write F01 device control\n", - __func__); - return retval; - } - fwu->polling_mode = false; - return retval; -} - -static int fwu_do_write_config(void) -{ - int retval; - - retval = fwu_enter_flash_prog(false); - if (retval < 0) - return retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Entered flash prog mode\n", - __func__); - - if (fwu->config_area == PERM_CONFIG_AREA) { - fwu->config_block_count = fwu->perm_config_block_count; - goto write_config; - } - - retval = fwu_write_bootloader_id(); - if (retval < 0) - return retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Bootloader ID written\n", - __func__); - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_CONFIG); - break; - case BL_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG); - fwu->config_block_count = fwu->bl_config_block_count; - break; - case DISP_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG); - fwu->config_block_count = fwu->disp_config_block_count; - break; - } - if (retval < 0) - return retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Erase command written\n", - __func__); - - retval = fwu_wait_for_idle(ERASE_WAIT_MS); - if (retval < 0) - return retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Idle status detected\n", - __func__); - -write_config: - retval = fwu_write_configuration(); - if (retval < 0) - return retval; - - pr_notice("%s: Config written\n", __func__); - - return retval; -} - -static int fwu_start_write_config(void) -{ - int retval; - int block_count; - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - block_count = fwu->config_block_count; - break; - case PERM_CONFIG_AREA: - if (!fwu->flash_properties.has_perm_config) - return -EINVAL; - block_count = fwu->perm_config_block_count; - break; - case BL_CONFIG_AREA: - if (!fwu->flash_properties.has_bl_config) - return -EINVAL; - block_count = fwu->bl_config_block_count; - break; - case DISP_CONFIG_AREA: - if (!fwu->flash_properties.has_display_config) - return -EINVAL; - block_count = fwu->disp_config_block_count; - break; - default: - return -EINVAL; - } - - if (fwu->image_size == block_count*fwu->block_size) { - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s: write config from config file\n", - __func__); - fwu->config_data = fwu->data_buffer; - } else { - parse_header(); - } - - pr_notice("%s: Start of write config process\n", __func__); - - retval = fwu_do_write_config(); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to write config\n", - __func__); - } - - fwu->rmi4_data->reset_device(fwu->rmi4_data); - - pr_notice("%s: End of write config process\n", __func__); - - return retval; -} - -static int fwu_do_write_lockdown(bool reset) -{ - int retval; - - pr_notice("%s: Start of lockdown process\n", __func__); - - retval = fwu_enter_flash_prog(false); - if (retval < 0) - return retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Entered flash prog mode\n", - __func__); - - if (fwu->flash_properties.unlocked == 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Device has been locked!\n", - __func__); - if (reset) - goto exit; - else - return -EINVAL; - } - - retval = fwu_write_lockdown_block(); - if (retval < 0) - return retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s:Lockdown device\n", - __func__); - -exit: - if (reset) - retval = fwu->rmi4_data->reset_device(fwu->rmi4_data); - else - retval = fwu_enter_flash_prog(true); - - if (retval < 0) - return retval; - - pr_notice("%s: End of lockdown process\n", __func__); - - return retval; -} - -static int fwu_start_write_lockdown(void) -{ - parse_header(); - return fwu_do_write_lockdown(true); -} - -static int fwu_do_read_config(void) -{ - int retval; - unsigned char block_offset[] = {0, 0}; - unsigned short block_num; - unsigned short block_count; - unsigned short index = 0; - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - block_count = fwu->config_block_count; - break; - case PERM_CONFIG_AREA: - if (!fwu->flash_properties.has_perm_config) { - retval = -EINVAL; - goto exit; - } - block_count = fwu->perm_config_block_count; - break; - case BL_CONFIG_AREA: - if (!fwu->flash_properties.has_bl_config) { - retval = -EINVAL; - goto exit; - } - block_count = fwu->bl_config_block_count; - break; - case DISP_CONFIG_AREA: - if (!fwu->flash_properties.has_display_config) { - retval = -EINVAL; - goto exit; - } - block_count = fwu->disp_config_block_count; - break; - default: - retval = -EINVAL; - goto exit; - } - - fwu->config_size = fwu->block_size * block_count; - - kfree(fwu->read_config_buf); - fwu->read_config_buf = kzalloc(fwu->config_size, GFP_KERNEL); - - block_offset[1] |= (fwu->config_area << 5); - - retval = fwu->fn_ptr->write(fwu->rmi4_data, - fwu_get_address(OFFSET_BLOCK_NUMBER), - block_offset, - sizeof(block_offset)); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to write to block number registers\n", - __func__); - goto exit; - } - - for (block_num = 0; block_num < block_count; block_num++) { - retval = fwu_write_f34_command(CMD_READ_CONFIG_BLOCK); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to write read config command\n", - __func__); - goto exit; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to wait for idle status\n", - __func__); - goto exit; - } - - retval = fwu->fn_ptr->read(fwu->rmi4_data, - fwu_get_address(OFFSET_BLOCK_DATA), - &fwu->read_config_buf[index], - fwu->block_size); - if (retval < 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to read block data (block %d)\n", - __func__, block_num); - goto exit; - } - - index += fwu->block_size; - } - -exit: - return retval; -} - -static int fwu_do_reflash(void) -{ - int retval; - unsigned char flash_status; - - if (fwu->do_lockdown) { - retval = fwu_do_write_lockdown(false); - if (retval < 0) - dev_warn(&fwu->rmi4_data->i2c_client->dev, - "%s: Skip lockdown process.\n", - __func__); - } - retval = fwu_enter_flash_prog(false); - if (retval < 0) - return retval; - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Entered flash prog mode\n", - __func__); - - retval = fwu_write_bootloader_id(); - if (retval < 0) - return retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Bootloader ID written\n", - __func__); - - retval = fwu_write_f34_command(CMD_ERASE_ALL); - if (retval < 0) - return retval; - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Erase all command written\n", - __func__); - - if (fwu->polling_mode) - msleep(100); - - retval = fwu_wait_for_idle(ERASE_WAIT_MS); - if (retval < 0) - return retval; - - retval = fwu_read_f34_flash_status(&flash_status); - if (retval < 0) - return retval; - if (flash_status != 0x00) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Erase all command failed, status 0x%02X\n", - __func__, flash_status); - return -EINVAL; - } - - if (fwu->firmware_data) { - retval = fwu_write_firmware(); - if (retval < 0) - return retval; - pr_notice("%s: Firmware programmed\n", __func__); - } - - if (fwu->config_data) { - retval = fwu_write_configuration(); - if (retval < 0) - return retval; - pr_notice("%s: Configuration programmed\n", __func__); - } - - return retval; -} - -static int fwu_start_reflash(void) -{ - int retval = 0; - const struct firmware *fw_entry = NULL; - struct f01_device_status f01_device_status; - enum flash_area flash_area; - - pr_notice("%s: Start of reflash process\n", __func__); - - if (fwu->ext_data_source) - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s Load .img file from commandline.\n", - __func__); - else { - if (strnlen(fwu->rmi4_data->fw_image_name, - NAME_BUFFER_SIZE) == 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "Firmware image name not given, "\ - "skipping update\n"); - return 0; - } - - if (strnlen(fwu->rmi4_data->fw_image_name, NAME_BUFFER_SIZE) == - NAME_BUFFER_SIZE) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "Firmware image name exceeds max length " \ - "(%d), skipping update\n", NAME_BUFFER_SIZE); - return 0; - } - - snprintf(fwu->image_name, NAME_BUFFER_SIZE, "%s", - fwu->rmi4_data->fw_image_name); - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s: Requesting firmware image %s\n", - __func__, fwu->image_name); - - retval = request_firmware(&fw_entry, - fwu->image_name, - &fwu->rmi4_data->i2c_client->dev); - if (retval != 0) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Firmware image %s not available\n", - __func__, - fwu->image_name); - return -EINVAL; - } - - dev_dbg(&fwu->rmi4_data->i2c_client->dev, - "%s: Firmware image size = %zu\n", - __func__, fw_entry->size); - - fwu->data_buffer = fw_entry->data; - } - - parse_header(); - flash_area = fwu_go_nogo(); - - if (fwu->rmi4_data->sensor_sleep) { - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Sensor sleeping\n", - __func__); - retval = -ENODEV; - goto exit; - } - fwu->rmi4_data->stay_awake = true; - - switch (flash_area) { - case NONE: - case MISMATCH: - retval = 0; - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s: No need to do reflash.\n", - __func__); - goto exit; - case UI_FIRMWARE: - retval = fwu_do_reflash(); - break; - case CONFIG_AREA: - retval = fwu_do_write_config(); - break; - default: - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Unknown flash area\n", - __func__); - retval = -EINVAL; - goto exit; - } - - if (retval < 0) - dev_err(&fwu->rmi4_data->i2c_client->dev, - "%s: Failed to do reflash\n", - __func__); - - /* reset device */ - fwu_reset_device(); - - /* check device status */ - retval = fwu_read_f01_device_status(&f01_device_status); - if (retval < 0) - goto exit; - - dev_info(&fwu->rmi4_data->i2c_client->dev, "Device is in %s mode\n", - f01_device_status.flash_prog == 1 ? "bootloader" : "UI"); - if (f01_device_status.flash_prog) - dev_info(&fwu->rmi4_data->i2c_client->dev, "Flash status %d\n", - f01_device_status.status_code); - - if (f01_device_status.flash_prog) { - dev_info(&fwu->rmi4_data->i2c_client->dev, - "%s: Device is in flash prog mode 0x%02X\n", - __func__, f01_device_status.status_code); - } - -exit: - if (fw_entry) - release_firmware(fw_entry); - - pr_notice("%s: End of reflash process\n", __func__); - fwu->rmi4_data->stay_awake = false; - return retval; -} - -int synaptics_fw_updater(void) -{ - int retval; - - if (!fwu) - return -ENODEV; - - if (!fwu->initialized) - return -ENODEV; - - fwu->rmi4_data->fw_updating = true; - if (fwu->rmi4_data->suspended == true) { - fwu->rmi4_data->fw_updating = false; - dev_err(&fwu->rmi4_data->i2c_client->dev, - "Cannot start fw upgrade while device is in suspend\n"); - return -EBUSY; - } - - fwu->config_area = UI_CONFIG_AREA; - - retval = fwu_start_reflash(); - fwu->rmi4_data->fw_updating = false; - - synaptics_rmi4_update_debug_info(); - - return retval; -} -EXPORT_SYMBOL(synaptics_fw_updater); - -static ssize_t fwu_sysfs_show_image(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (count < fwu->config_size) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Not enough space (%zu bytes) in buffer\n", - __func__, count); - return -EINVAL; - } - - memcpy(buf, fwu->read_config_buf, fwu->config_size); - - return fwu->config_size; -} - -static ssize_t fwu_sysfs_store_image(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]), - (const void *)buf, - count); - - fwu->data_buffer = fwu->ext_data_source; - fwu->data_pos += count; - - return count; -} - -static ssize_t fwu_sysfs_image_name_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - char *strptr; - - if (count >= NAME_BUFFER_SIZE) { - dev_err(&rmi4_data->i2c_client->dev, - "Input over %d characters long\n", NAME_BUFFER_SIZE); - return -EINVAL; - } - - strptr = strnstr(buf, ".img", - count); - if (!strptr) { - dev_err(&rmi4_data->i2c_client->dev, - "Input is not valid .img file\n"); - return -EINVAL; - } - - strlcpy(rmi4_data->fw_image_name, buf, count); - return count; -} - -static ssize_t fwu_sysfs_image_name_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - if (strnlen(fwu->rmi4_data->fw_image_name, NAME_BUFFER_SIZE) > 0) - return snprintf(buf, PAGE_SIZE, "%s\n", - fwu->rmi4_data->fw_image_name); - else - return snprintf(buf, PAGE_SIZE, "No firmware name given\n"); -} - -static ssize_t fwu_sysfs_force_reflash_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) { - retval = -EINVAL; - goto exit; - } - - if (input != 1) { - retval = -EINVAL; - goto exit; - } - if (LOCKDOWN) - fwu->do_lockdown = true; - - fwu->force_update = true; - retval = synaptics_fw_updater(); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to do reflash\n", - __func__); - goto exit; - } - - retval = count; - -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - fwu->force_update = FORCE_UPDATE; - fwu->do_lockdown = rmi4_data->board->do_lockdown; - return retval; -} - -static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) { - retval = -EINVAL; - goto exit; - } - - if (input & LOCKDOWN) { - fwu->do_lockdown = true; - input &= ~LOCKDOWN; - } - - if ((input != NORMAL) && (input != FORCE)) { - retval = -EINVAL; - goto exit; - } - - if (input == FORCE) - fwu->force_update = true; - - retval = synaptics_fw_updater(); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to do reflash\n", - __func__); - goto exit; - } - - retval = count; - -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - fwu->force_update = FORCE_UPDATE; - fwu->do_lockdown = rmi4_data->board->do_lockdown; - return retval; -} - -static ssize_t fwu_sysfs_write_lockdown_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) { - retval = -EINVAL; - goto exit; - } - - if (input != 1) { - retval = -EINVAL; - goto exit; - } - - retval = fwu_start_write_lockdown(); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to write lockdown block\n", - __func__); - goto exit; - } - - retval = count; - -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - fwu->force_update = FORCE_UPDATE; - fwu->do_lockdown = rmi4_data->board->do_lockdown; - return retval; -} - -static ssize_t fwu_sysfs_write_config_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) { - retval = -EINVAL; - goto exit; - } - - if (input != 1) { - retval = -EINVAL; - goto exit; - } - - retval = fwu_start_write_config(); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to write config\n", - __func__); - goto exit; - } - - retval = count; - -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - return retval; -} - -static ssize_t fwu_sysfs_read_config_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - retval = fwu_do_read_config(); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to read config\n", - __func__); - return retval; - } - - return count; -} - -static ssize_t fwu_sysfs_config_area_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned short config_area; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = kstrtou16(buf, 10, &config_area); - if (retval) - return retval; - - if (config_area < 0x00 || config_area > 0x03) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Incorrect value of config_area\n", - __func__); - return -EINVAL; - } - - fwu->config_area = config_area; - - return count; -} - -static ssize_t fwu_sysfs_image_size_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long size; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = kstrtoul(buf, 10, &size); - if (retval) - return retval; - - fwu->image_size = size; - fwu->data_pos = 0; - - kfree(fwu->ext_data_source); - fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL); - if (!fwu->ext_data_source) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for image data\n", - __func__); - return -ENOMEM; - } - - return count; -} - -static ssize_t fwu_sysfs_block_size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->block_size); -} - -static ssize_t fwu_sysfs_firmware_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->fw_block_count); -} - -static ssize_t fwu_sysfs_configuration_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->config_block_count); -} - -static ssize_t fwu_sysfs_perm_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->perm_config_block_count); -} - -static ssize_t fwu_sysfs_bl_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->bl_config_block_count); -} - -static ssize_t fwu_sysfs_disp_config_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->disp_config_block_count); -} - -static ssize_t fwu_sysfs_config_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned char config_id[4]; - /* device config id */ - fwu->fn_ptr->read(fwu->rmi4_data, - fwu->f34_fd.ctrl_base_addr, - config_id, - sizeof(config_id)); - - return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", - config_id[0], config_id[1], config_id[2], config_id[3]); -} - -static ssize_t fwu_sysfs_package_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned char pkg_id[4]; - /* read device package id */ - fwu->fn_ptr->read(fwu->rmi4_data, - fwu->f01_fd.query_base_addr + 17, - pkg_id, - sizeof(pkg_id)); - - return snprintf(buf, PAGE_SIZE, "%d rev %d\n", - (pkg_id[1] << 8) | pkg_id[0], - (pkg_id[3] << 8) | pkg_id[2]); -} - -static int synaptics_rmi4_debug_dump_info(struct seq_file *m, void *v) -{ - seq_printf(m, "%s\n", fwu->ts_info); - - return 0; -} - -static int debugfs_dump_info_open(struct inode *inode, struct file *file) -{ - return single_open(file, synaptics_rmi4_debug_dump_info, - inode->i_private); -} - -static const struct file_operations debug_dump_info_fops = { - .owner = THIS_MODULE, - .open = debugfs_dump_info_open, - .read = seq_read, - .release = single_release, -}; - -static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask) -{ - if (!fwu) - return; - - if (fwu->intr_mask & intr_mask) - fwu->interrupt_flag = true; - - return; -} - -static struct bin_attribute dev_attr_data = { - .attr = { - .name = "data", - .mode = (S_IRUGO | S_IWUSR | S_IWGRP), - }, - .size = 0, - .read = fwu_sysfs_show_image, - .write = fwu_sysfs_store_image, -}; - -static struct device_attribute attrs[] = { - __ATTR(fw_name, S_IRUGO | S_IWUSR | S_IWGRP, - fwu_sysfs_image_name_show, - fwu_sysfs_image_name_store), - __ATTR(force_update_fw, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_force_reflash_store), - __ATTR(update_fw, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_do_reflash_store), - __ATTR(writeconfig, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_write_config_store), - __ATTR(writelockdown, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_write_lockdown_store), - __ATTR(readconfig, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_read_config_store), - __ATTR(configarea, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_config_area_store), - __ATTR(imagesize, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_image_size_store), - __ATTR(blocksize, S_IRUGO, - fwu_sysfs_block_size_show, - synaptics_rmi4_store_error), - __ATTR(fwblockcount, S_IRUGO, - fwu_sysfs_firmware_block_count_show, - synaptics_rmi4_store_error), - __ATTR(configblockcount, S_IRUGO, - fwu_sysfs_configuration_block_count_show, - synaptics_rmi4_store_error), - __ATTR(permconfigblockcount, S_IRUGO, - fwu_sysfs_perm_config_block_count_show, - synaptics_rmi4_store_error), - __ATTR(blconfigblockcount, S_IRUGO, - fwu_sysfs_bl_config_block_count_show, - synaptics_rmi4_store_error), - __ATTR(dispconfigblockcount, S_IRUGO, - fwu_sysfs_disp_config_block_count_show, - synaptics_rmi4_store_error), - __ATTR(config_id, S_IRUGO, - fwu_sysfs_config_id_show, - synaptics_rmi4_store_error), - __ATTR(package_id, S_IRUGO, - fwu_sysfs_package_id_show, - synaptics_rmi4_store_error), -}; - - -static void synaptics_rmi4_fwu_work(struct work_struct *work) -{ - fwu_start_reflash(); -} - -static int synaptics_rmi4_fwu_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char attr_count; - struct pdt_properties pdt_props; - struct dentry *temp; - - fwu = kzalloc(sizeof(*fwu), GFP_KERNEL); - if (!fwu) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for fwu\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - fwu->fn_ptr = kzalloc(sizeof(*(fwu->fn_ptr)), GFP_KERNEL); - if (!fwu->fn_ptr) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for fn_ptr\n", - __func__); - retval = -ENOMEM; - goto exit_free_fwu; - } - - fwu->rmi4_data = rmi4_data; - fwu->fn_ptr->read = rmi4_data->i2c_read; - fwu->fn_ptr->write = rmi4_data->i2c_write; - fwu->fn_ptr->enable = rmi4_data->irq_enable; - - retval = fwu->fn_ptr->read(rmi4_data, - PDT_PROPS, - pdt_props.data, - sizeof(pdt_props.data)); - if (retval < 0) { - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Failed to read PDT properties, assuming 0x00\n", - __func__); - goto exit_free_mem; - } else if (pdt_props.has_bsr) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Reflash for LTS not currently supported\n", - __func__); - retval = -EINVAL; - goto exit_free_mem; - } - - retval = fwu_scan_pdt(); - if (retval < 0) - goto exit_free_mem; - - fwu->productinfo1 = rmi4_data->rmi4_mod_info.product_info[0]; - fwu->productinfo2 = rmi4_data->rmi4_mod_info.product_info[1]; - - memcpy(fwu->product_id, rmi4_data->rmi4_mod_info.product_id_string, - SYNAPTICS_RMI4_PRODUCT_ID_SIZE); - fwu->product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE] = 0; - - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: F01 product info: 0x%04x 0x%04x\n", - __func__, fwu->productinfo1, fwu->productinfo2); - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: F01 product ID: %s\n", - __func__, fwu->product_id); - - retval = fwu_read_f34_queries(); - if (retval < 0) - goto exit_free_mem; - - fwu->initialized = true; - fwu->force_update = FORCE_UPDATE; - fwu->do_lockdown = rmi4_data->board->do_lockdown; - fwu->initialized = true; - fwu->polling_mode = false; - - retval = sysfs_create_bin_file(&rmi4_data->i2c_client->dev.kobj, - &dev_attr_data); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to create sysfs bin file\n", - __func__); - goto exit_free_mem; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(&rmi4_data->i2c_client->dev.kobj, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to create sysfs attributes\n", - __func__); - retval = -ENODEV; - goto exit_remove_attrs; - } - } - - temp = debugfs_create_file("dump_info", S_IRUSR | S_IWUSR, - fwu->rmi4_data->dir, fwu->rmi4_data, - &debug_dump_info_fops); - if (temp == NULL || IS_ERR(temp)) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to create debugfs dump info file\n", - __func__); - retval = PTR_ERR(temp); - goto exit_remove_attrs; - } - - fwu->ts_info = kzalloc(RMI4_INFO_MAX_LEN, GFP_KERNEL); - if (!fwu->ts_info) { - dev_err(&rmi4_data->i2c_client->dev, "Not enough memory\n"); - goto exit_free_ts_info; - } - - synaptics_rmi4_update_debug_info(); - -#ifdef INSIDE_FIRMWARE_UPDATE - fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue"); - INIT_DELAYED_WORK(&fwu->fwu_work, synaptics_rmi4_fwu_work); - queue_delayed_work(fwu->fwu_workqueue, - &fwu->fwu_work, - msecs_to_jiffies(1000)); -#endif - - return 0; -exit_free_ts_info: - debugfs_remove(temp); -exit_remove_attrs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data); - -exit_free_mem: - kfree(fwu->fn_ptr); - -exit_free_fwu: - kfree(fwu); - fwu = NULL; - -exit: - return retval; -} - -static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char attr_count; - - sysfs_remove_bin_file(&rmi4_data->input_dev->dev.kobj, &dev_attr_data); - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - kfree(fwu->read_config_buf); - kfree(fwu->fn_ptr); - kfree(fwu); - - complete(&fwu_remove_complete); - - return; -} - -static int __init rmi4_fw_update_module_init(void) -{ - synaptics_rmi4_new_function(RMI_FW_UPDATER, true, - synaptics_rmi4_fwu_init, - synaptics_rmi4_fwu_remove, - synaptics_rmi4_fwu_attn); - return 0; -} - -static void __exit rmi4_fw_update_module_exit(void) -{ - synaptics_rmi4_new_function(RMI_FW_UPDATER, false, - synaptics_rmi4_fwu_init, - synaptics_rmi4_fwu_remove, - synaptics_rmi4_fwu_attn); - wait_for_completion(&fwu_remove_complete); - return; -} - -module_init(rmi4_fw_update_module_init); -module_exit(rmi4_fw_update_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("RMI4 FW Update Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c deleted file mode 100644 index a6d0dbf18c28..000000000000 --- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c +++ /dev/null @@ -1,4378 +0,0 @@ -/* - * Synaptics RMI4 touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * Copyright (c) 2013-2014, 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/gpio.h> -#include <linux/regulator/consumer.h> -#include <linux/pinctrl/consumer.h> -#include <linux/input/synaptics_dsx.h> -#include <linux/of_gpio.h> - -#if defined(CONFIG_SECURE_TOUCH) -#include <linux/pm_runtime.h> -#include <linux/errno.h> -#include <asm/system.h> -#endif - -#include "synaptics_i2c_rmi4.h" -#include <linux/input/mt.h> - -#define DRIVER_NAME "synaptics_rmi4_i2c" -#define INPUT_PHYS_NAME "synaptics_rmi4_i2c/input0" -#define DEBUGFS_DIR_NAME "ts_debug" - -#define RESET_DELAY 100 - -#define TYPE_B_PROTOCOL - -#define NO_0D_WHILE_2D -/* -#define REPORT_2D_Z -*/ -#define REPORT_2D_W - -#define RPT_TYPE (1 << 0) -#define RPT_X_LSB (1 << 1) -#define RPT_X_MSB (1 << 2) -#define RPT_Y_LSB (1 << 3) -#define RPT_Y_MSB (1 << 4) -#define RPT_Z (1 << 5) -#define RPT_WX (1 << 6) -#define RPT_WY (1 << 7) -#define RPT_DEFAULT (RPT_TYPE | RPT_X_LSB | RPT_X_MSB | RPT_Y_LSB | RPT_Y_MSB) - -#define EXP_FN_DET_INTERVAL 1000 /* ms */ -#define POLLING_PERIOD 1 /* ms */ -#define SYN_I2C_RETRY_TIMES 10 -#define MAX_ABS_MT_TOUCH_MAJOR 15 - -#define F01_STD_QUERY_LEN 21 -#define F01_PACKAGE_ID_OFFSET 17 -#define F01_BUID_ID_OFFSET 18 -#define F11_STD_QUERY_LEN 9 -#define F11_STD_CTRL_LEN 10 -#define F11_STD_DATA_LEN 12 - -#define NORMAL_OPERATION 0 -#define SENSOR_SLEEP 1 -#define NO_SLEEP_OFF 0 -#define NO_SLEEP_ON 1 - -enum device_status { - STATUS_NO_ERROR = 0x00, - STATUS_RESET_OCCURED = 0x01, - STATUS_INVALID_CONFIG = 0x02, - STATUS_DEVICE_FAILURE = 0x03, - STATUS_CONFIG_CRC_FAILURE = 0x04, - STATUS_FIRMWARE_CRC_FAILURE = 0x05, - STATUS_CRC_IN_PROGRESS = 0x06, - STATUS_UNCONFIGURED = 0x80 -}; - -#define DEVICE_CONFIGURED 0x1 - -#define RMI4_VTG_MIN_UV 2700000 -#define RMI4_VTG_MAX_UV 3300000 -#define RMI4_ACTIVE_LOAD_UA 15000 -#define RMI4_LPM_LOAD_UA 10 - -#define RMI4_I2C_VTG_MIN_UV 1800000 -#define RMI4_I2C_VTG_MAX_UV 1800000 -#define RMI4_I2C_LOAD_UA 10000 -#define RMI4_I2C_LPM_LOAD_UA 10 - -#define RMI4_GPIO_SLEEP_LOW_US 10000 -#define F12_FINGERS_TO_SUPPORT 10 -#define MAX_F11_TOUCH_WIDTH 15 - -#define RMI4_COORDS_ARR_SIZE 4 - -#define F11_MAX_X 4096 -#define F11_MAX_Y 4096 -#define F12_MAX_X 65536 -#define F12_MAX_Y 65536 - -static bool wake_report; - -static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, unsigned char *data, - unsigned short length); - -static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, unsigned char *data, - unsigned short length); - -static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data); - -static void synaptics_rmi4_sensor_wake(struct synaptics_rmi4_data *rmi4_data); - -static void __maybe_unused synaptics_rmi4_sensor_sleep( - struct synaptics_rmi4_data *rmi4_data); - -static int __maybe_unused synaptics_rmi4_regulator_lpm( - struct synaptics_rmi4_data *rmi4_data, bool on); - -static void __maybe_unused synaptics_rmi4_release_all( - struct synaptics_rmi4_data *rmi4_data); - -static int synaptics_rmi4_check_configuration(struct synaptics_rmi4_data - *rmi4_data); - -static int synaptics_rmi4_suspend(struct device *dev); - -static int synaptics_rmi4_resume(struct device *dev); - -static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -#if defined(CONFIG_FB) -static int fb_notifier_callback(struct notifier_block *self, - unsigned long event, void *data); -#elif defined(CONFIG_HAS_EARLYSUSPEND) -static void synaptics_rmi4_early_suspend(struct early_suspend *h); - -static void synaptics_rmi4_late_resume(struct early_suspend *h); -#endif - -static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_rmi4_flipx_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_flipx_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_rmi4_flipy_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_flipy_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static int synaptics_rmi4_capacitance_button_map( - struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler); - -static irqreturn_t synaptics_rmi4_irq(int irq, void *data); - -#if defined(CONFIG_SECURE_TOUCH) -static ssize_t synaptics_secure_touch_enable_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_secure_touch_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_secure_touch_show(struct device *dev, - struct device_attribute *attr, char *buf); -#endif - -struct synaptics_rmi4_f01_device_status { - union { - struct { - unsigned char status_code:4; - unsigned char reserved:2; - unsigned char flash_prog:1; - unsigned char unconfigured:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f01_device_control_0 { - union { - struct { - unsigned char sleep_mode:2; - unsigned char nosleep:1; - unsigned char reserved:2; - unsigned char charger_input:1; - unsigned char report_rate:1; - unsigned char configured:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f12_query_5 { - union { - struct { - unsigned char size_of_query6; - struct { - unsigned char ctrl0_is_present:1; - unsigned char ctrl1_is_present:1; - unsigned char ctrl2_is_present:1; - unsigned char ctrl3_is_present:1; - unsigned char ctrl4_is_present:1; - unsigned char ctrl5_is_present:1; - unsigned char ctrl6_is_present:1; - unsigned char ctrl7_is_present:1; - } __packed; - struct { - unsigned char ctrl8_is_present:1; - unsigned char ctrl9_is_present:1; - unsigned char ctrl10_is_present:1; - unsigned char ctrl11_is_present:1; - unsigned char ctrl12_is_present:1; - unsigned char ctrl13_is_present:1; - unsigned char ctrl14_is_present:1; - unsigned char ctrl15_is_present:1; - } __packed; - struct { - unsigned char ctrl16_is_present:1; - unsigned char ctrl17_is_present:1; - unsigned char ctrl18_is_present:1; - unsigned char ctrl19_is_present:1; - unsigned char ctrl20_is_present:1; - unsigned char ctrl21_is_present:1; - unsigned char ctrl22_is_present:1; - unsigned char ctrl23_is_present:1; - } __packed; - struct { - unsigned char ctrl24_is_present:1; - unsigned char ctrl25_is_present:1; - unsigned char ctrl26_is_present:1; - unsigned char ctrl27_is_present:1; - unsigned char ctrl28_is_present:1; - unsigned char ctrl29_is_present:1; - unsigned char ctrl30_is_present:1; - unsigned char ctrl31_is_present:1; - } __packed; - }; - unsigned char data[5]; - }; -}; - -struct synaptics_rmi4_f12_query_8 { - union { - struct { - unsigned char size_of_query9; - struct { - unsigned char data0_is_present:1; - unsigned char data1_is_present:1; - unsigned char data2_is_present:1; - unsigned char data3_is_present:1; - unsigned char data4_is_present:1; - unsigned char data5_is_present:1; - unsigned char data6_is_present:1; - unsigned char data7_is_present:1; - } __packed; - struct { - unsigned char data8_is_present:1; - unsigned char data9_is_present:1; - unsigned char data10_is_present:1; - unsigned char data11_is_present:1; - unsigned char data12_is_present:1; - unsigned char data13_is_present:1; - unsigned char data14_is_present:1; - unsigned char data15_is_present:1; - } __packed; - }; - unsigned char data[3]; - }; -}; - -struct synaptics_rmi4_f12_ctrl_8 { - union { - struct { - unsigned char max_x_coord_lsb; - unsigned char max_x_coord_msb; - unsigned char max_y_coord_lsb; - unsigned char max_y_coord_msb; - unsigned char rx_pitch_lsb; - unsigned char rx_pitch_msb; - unsigned char tx_pitch_lsb; - unsigned char tx_pitch_msb; - unsigned char low_rx_clip; - unsigned char high_rx_clip; - unsigned char low_tx_clip; - unsigned char high_tx_clip; - unsigned char num_of_rx; - unsigned char num_of_tx; - }; - unsigned char data[14]; - }; -}; - -struct synaptics_rmi4_f12_ctrl_23 { - union { - struct { - unsigned char obj_type_enable; - unsigned char max_reported_objects; - }; - unsigned char data[2]; - }; -}; - -struct synaptics_rmi4_f12_finger_data { - unsigned char object_type_and_status; - unsigned char x_lsb; - unsigned char x_msb; - unsigned char y_lsb; - unsigned char y_msb; -#ifdef REPORT_2D_Z - unsigned char z; -#endif -#ifdef REPORT_2D_W - unsigned char wx; - unsigned char wy; -#endif -}; - -struct synaptics_rmi4_f1a_query { - union { - struct { - unsigned char max_button_count:3; - unsigned char reserved:5; - unsigned char has_general_control:1; - unsigned char has_interrupt_enable:1; - unsigned char has_multibutton_select:1; - unsigned char has_tx_rx_map:1; - unsigned char has_perbutton_threshold:1; - unsigned char has_release_threshold:1; - unsigned char has_strongestbtn_hysteresis:1; - unsigned char has_filter_strength:1; - } __packed; - unsigned char data[2]; - }; -}; - -struct synaptics_rmi4_f1a_control_0 { - union { - struct { - unsigned char multibutton_report:2; - unsigned char filter_mode:2; - unsigned char reserved:4; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f1a_control_3_4 { - unsigned char transmitterbutton; - unsigned char receiverbutton; -}; - -struct synaptics_rmi4_f1a_control { - struct synaptics_rmi4_f1a_control_0 general_control; - unsigned char *button_int_enable; - unsigned char *multi_button; - struct synaptics_rmi4_f1a_control_3_4 *electrode_map; - unsigned char *button_threshold; - unsigned char button_release_threshold; - unsigned char strongest_button_hysteresis; - unsigned char filter_strength; -}; - -struct synaptics_rmi4_f1a_handle { - int button_bitmask_size; - unsigned char button_count; - unsigned char valid_button_count; - unsigned char *button_data_buffer; - unsigned char *button_map; - struct synaptics_rmi4_f1a_query button_query; - struct synaptics_rmi4_f1a_control button_control; -}; - -struct synaptics_rmi4_f12_extra_data { - unsigned char data1_offset; - unsigned char data15_offset; - unsigned char data15_size; - unsigned char data15_data[(F12_FINGERS_TO_SUPPORT + 7) / 8]; -}; - -struct synaptics_rmi4_exp_fn { - enum exp_fn fn_type; - bool inserted; - int (*func_init)(struct synaptics_rmi4_data *rmi4_data); - void (*func_remove)(struct synaptics_rmi4_data *rmi4_data); - void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask); - struct list_head link; -}; - -static struct device_attribute attrs[] = { - __ATTR(full_pm_cycle, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_full_pm_cycle_show, - synaptics_rmi4_full_pm_cycle_store), - __ATTR(reset, S_IWUSR | S_IWGRP, - NULL, - synaptics_rmi4_f01_reset_store), - __ATTR(productinfo, S_IRUGO, - synaptics_rmi4_f01_productinfo_show, - synaptics_rmi4_store_error), - __ATTR(buildid, S_IRUGO, - synaptics_rmi4_f01_buildid_show, - synaptics_rmi4_store_error), - __ATTR(flashprog, S_IRUGO, - synaptics_rmi4_f01_flashprog_show, - synaptics_rmi4_store_error), - __ATTR(0dbutton, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_0dbutton_show, - synaptics_rmi4_0dbutton_store), - __ATTR(flipx, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_flipx_show, - synaptics_rmi4_flipx_store), - __ATTR(flipy, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_flipy_show, - synaptics_rmi4_flipy_store), -#if defined(CONFIG_SECURE_TOUCH) - __ATTR(secure_touch_enable, (S_IRUGO | S_IWUGO), - synaptics_secure_touch_enable_show, - synaptics_secure_touch_enable_store), - __ATTR(secure_touch, S_IRUGO , - synaptics_secure_touch_show, - NULL), -#endif -}; - -static bool exp_fn_inited; -static struct mutex exp_fn_list_mutex; -static struct list_head exp_fn_list; - -#if defined(CONFIG_SECURE_TOUCH) -static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) -{ - init_completion(&data->st_powerdown); - init_completion(&data->st_irq_processed); -} -static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *data) -{ - sysfs_notify(&data->i2c_client->dev.kobj, NULL, "secure_touch"); -} -static irqreturn_t synaptics_filter_interrupt(struct synaptics_rmi4_data *data) -{ - if (atomic_read(&data->st_enabled)) { - if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0) { - synaptics_secure_touch_notify(data); - wait_for_completion_interruptible( - &data->st_irq_processed); - } - return IRQ_HANDLED; - } - return IRQ_NONE; -} -static void synaptics_secure_touch_stop( - struct synaptics_rmi4_data *data, - int blocking) -{ - if (atomic_read(&data->st_enabled)) { - atomic_set(&data->st_pending_irqs, -1); - synaptics_secure_touch_notify(data); - if (blocking) - wait_for_completion_interruptible(&data->st_powerdown); - } -} -#else -static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) -{ -} -static irqreturn_t synaptics_filter_interrupt(struct synaptics_rmi4_data *data) -{ - return IRQ_NONE; -} -static void synaptics_secure_touch_stop( - struct synaptics_rmi4_data *data, - int blocking) -{ -} -#endif - -#if defined(CONFIG_SECURE_TOUCH) -static ssize_t synaptics_secure_touch_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *data = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%d", atomic_read(&data->st_enabled)); -} -/* - * Accept only "0" and "1" valid values. - * "0" will reset the st_enabled flag, then wake up the reading process and - * the interrupt handler. - * The bus driver is notified via pm_runtime that it is not required to stay - * awake anymore. - * It will also make sure the queue of events is emptied in the controller, - * in case a touch happened in between the secure touch being disabled and - * the local ISR being ungated. - * "1" will set the st_enabled flag and clear the st_pending_irqs flag. - * The bus driver is requested via pm_runtime to stay awake. - */ -static ssize_t synaptics_secure_touch_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct synaptics_rmi4_data *data = dev_get_drvdata(dev); - unsigned long value; - int err = 0; - - if (count > 2) - return -EINVAL; - - err = kstrtoul(buf, 10, &value); - if (err != 0) - return err; - - err = count; - - switch (value) { - case 0: - if (atomic_read(&data->st_enabled) == 0) - break; - - pm_runtime_put_sync(data->i2c_client->adapter->dev.parent); - atomic_set(&data->st_enabled, 0); - synaptics_secure_touch_notify(data); - complete(&data->st_irq_processed); - synaptics_rmi4_irq(data->irq, data); - complete(&data->st_powerdown); - - break; - case 1: - if (atomic_read(&data->st_enabled)) { - err = -EBUSY; - break; - } - - synchronize_irq(data->irq); - - if (pm_runtime_get_sync( - data->i2c_client->adapter->dev.parent) < 0) { - dev_err(&data->i2c_client->dev, - "pm_runtime_get failed\n"); - err = -EIO; - break; - } - INIT_COMPLETION(data->st_powerdown); - INIT_COMPLETION(data->st_irq_processed); - atomic_set(&data->st_enabled, 1); - atomic_set(&data->st_pending_irqs, 0); - break; - default: - dev_err(&data->i2c_client->dev, - "unsupported value: %lu\n", value); - err = -EINVAL; - break; - } - return err; -} - -/* - * This function returns whether there are pending interrupts, or - * other error conditions that need to be signaled to the userspace library, - * according tot he following logic: - * - st_enabled is 0 if secure touch is not enabled, returning -EBADF - * - st_pending_irqs is -1 to signal that secure touch is in being stopped, - * returning -EINVAL - * - st_pending_irqs is 1 to signal that there is a pending irq, returning - * the value "1" to the sysfs read operation - * - st_pending_irqs is 0 (only remaining case left) if the pending interrupt - * has been processed, so the interrupt handler can be allowed to continue. - */ -static ssize_t synaptics_secure_touch_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *data = dev_get_drvdata(dev); - int val = 0; - if (atomic_read(&data->st_enabled) == 0) - return -EBADF; - - if (atomic_cmpxchg(&data->st_pending_irqs, -1, 0) == -1) - return -EINVAL; - - if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) == 1) - val = 1; - else - complete(&data->st_irq_processed); - - return scnprintf(buf, PAGE_SIZE, "%u", val); - -} -#endif -static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val) -{ - struct synaptics_rmi4_data *rmi4_data = _data; - - if (val) - synaptics_rmi4_suspend(&rmi4_data->input_dev->dev); - else - synaptics_rmi4_resume(&rmi4_data->input_dev->dev); - - return 0; -} - -static int synaptics_rmi4_debug_suspend_get(void *_data, u64 *val) -{ - struct synaptics_rmi4_data *rmi4_data = _data; - - *val = rmi4_data->suspended; - - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, synaptics_rmi4_debug_suspend_get, - synaptics_rmi4_debug_suspend_set, "%lld\n"); - -static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", - rmi4_data->full_pm_cycle); -} - -static ssize_t synaptics_rmi4_full_pm_cycle_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - rmi4_data->full_pm_cycle = input > 0 ? 1 : 0; - - return count; -} - -#ifdef CONFIG_FB -static void configure_sleep(struct synaptics_rmi4_data *rmi4_data) -{ - int retval = 0; - - rmi4_data->fb_notif.notifier_call = fb_notifier_callback; - - retval = fb_register_client(&rmi4_data->fb_notif); - if (retval) - dev_err(&rmi4_data->i2c_client->dev, - "Unable to register fb_notifier: %d\n", retval); - return; -} -#elif defined CONFIG_HAS_EARLYSUSPEND -static void configure_sleep(struct synaptics_rmi4_data *rmi4_data) -{ - rmi4_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - rmi4_data->early_suspend.suspend = synaptics_rmi4_early_suspend; - rmi4_data->early_suspend.resume = synaptics_rmi4_late_resume; - register_early_suspend(&rmi4_data->early_suspend); - - return; -} -#else -static void configure_sleep(struct synaptics_rmi4_data *rmi4_data) -{ - return; -} -#endif - -static ssize_t synaptics_rmi4_f01_reset_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int reset; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - if (sscanf(buf, "%u", &reset) != 1) - return -EINVAL; - - if (reset != 1) - return -EINVAL; - - retval = synaptics_rmi4_reset_device(rmi4_data); - if (retval < 0) { - dev_err(dev, - "%s: Failed to issue reset command, error = %d\n", - __func__, retval); - return retval; - } - - return count; -} - -static ssize_t synaptics_rmi4_f01_productinfo_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "0x%02x 0x%02x\n", - (rmi4_data->rmi4_mod_info.product_info[0]), - (rmi4_data->rmi4_mod_info.product_info[1])); -} - -static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned int build_id; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - build_id = (unsigned int)rmi->build_id[0] + - (unsigned int)rmi->build_id[1] * 0x100 + - (unsigned int)rmi->build_id[2] * 0x10000; - - return snprintf(buf, PAGE_SIZE, "%u\n", - build_id); -} - -static ssize_t synaptics_rmi4_f01_flashprog_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - struct synaptics_rmi4_f01_device_status device_status; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_data_base_addr, - device_status.data, - sizeof(device_status.data)); - if (retval < 0) { - dev_err(dev, - "%s: Failed to read device status, error = %d\n", - __func__, retval); - return retval; - } - - return snprintf(buf, PAGE_SIZE, "%u\n", - device_status.flash_prog); -} - -static ssize_t synaptics_rmi4_0dbutton_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", - rmi4_data->button_0d_enabled); -} - -static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - unsigned char ii; - unsigned char intr_enable; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - input = input > 0 ? 1 : 0; - - if (rmi4_data->button_0d_enabled == input) - return count; - - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) { - ii = fhandler->intr_reg_num; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr + - 1 + ii, - &intr_enable, - sizeof(intr_enable)); - if (retval < 0) - goto exit; - - if (input == 1) - intr_enable |= fhandler->intr_mask; - else - intr_enable &= ~fhandler->intr_mask; - - retval = synaptics_rmi4_i2c_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr + - 1 + ii, - &intr_enable, - sizeof(intr_enable)); - if (retval < 0) - goto exit; - } - } - } - mutex_unlock(&rmi->support_fn_list_mutex); - rmi4_data->button_0d_enabled = input; - - return count; -exit: - mutex_unlock(&rmi->support_fn_list_mutex); - return retval; -} - -static ssize_t synaptics_rmi4_flipx_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", - rmi4_data->flip_x); -} - -static ssize_t synaptics_rmi4_flipx_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - rmi4_data->flip_x = input > 0 ? 1 : 0; - - return count; -} - -static ssize_t synaptics_rmi4_flipy_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", - rmi4_data->flip_y); -} - -static ssize_t synaptics_rmi4_flipy_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - rmi4_data->flip_y = input > 0 ? 1 : 0; - - return count; -} - - /** - * synaptics_rmi4_set_page() - * - * Called by synaptics_rmi4_i2c_read() and synaptics_rmi4_i2c_write(). - * - * This function writes to the page select register to switch to the - * assigned page. - */ -static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *rmi4_data, - unsigned int address) -{ - int retval = 0; - unsigned char retry; - unsigned char buf[PAGE_SELECT_LEN]; - unsigned char page; - struct i2c_client *i2c = rmi4_data->i2c_client; - - page = ((address >> 8) & MASK_8BIT); - if (page != rmi4_data->current_page) { - buf[0] = MASK_8BIT; - buf[1] = page; - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - retval = i2c_master_send(i2c, buf, PAGE_SELECT_LEN); - if (retval != PAGE_SELECT_LEN) { - dev_err(&i2c->dev, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - } else { - rmi4_data->current_page = page; - break; - } - } - } else - return PAGE_SELECT_LEN; - return (retval == PAGE_SELECT_LEN) ? retval : -EIO; -} - - /** - * synaptics_rmi4_i2c_read() - * - * Called by various functions in this driver, and also exported to - * other expansion Function modules such as rmi_dev. - * - * This function reads data of an arbitrary length from the sensor, - * starting from an assigned register address of the sensor, via I2C - * with a retry mechanism. - */ -static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, unsigned char *data, unsigned short length) -{ - int retval; - unsigned char retry; - unsigned char buf; - struct i2c_msg msg[] = { - { - .addr = rmi4_data->i2c_client->addr, - .flags = 0, - .len = 1, - .buf = &buf, - }, - { - .addr = rmi4_data->i2c_client->addr, - .flags = I2C_M_RD, - .len = length, - .buf = data, - }, - }; - - buf = addr & MASK_8BIT; - - mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex)); - - retval = synaptics_rmi4_set_page(rmi4_data, addr); - if (retval != PAGE_SELECT_LEN) - goto exit; - - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 2) == 2) { - retval = length; - break; - } - dev_err(&rmi4_data->i2c_client->dev, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - } - - if (retry == SYN_I2C_RETRY_TIMES) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: I2C read over retry limit\n", - __func__); - retval = -EIO; - } - -exit: - mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex)); - - return retval; -} - - /** - * synaptics_rmi4_i2c_write() - * - * Called by various functions in this driver, and also exported to - * other expansion Function modules such as rmi_dev. - * - * This function writes data of an arbitrary length to the sensor, - * starting from an assigned register address of the sensor, via I2C with - * a retry mechanism. - */ -static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr, unsigned char *data, unsigned short length) -{ - int retval; - unsigned char retry; - unsigned char buf[length + 1]; - struct i2c_msg msg[] = { - { - .addr = rmi4_data->i2c_client->addr, - .flags = 0, - .len = length + 1, - .buf = buf, - } - }; - - mutex_lock(&(rmi4_data->rmi4_io_ctrl_mutex)); - - retval = synaptics_rmi4_set_page(rmi4_data, addr); - if (retval != PAGE_SELECT_LEN) - goto exit; - - buf[0] = addr & MASK_8BIT; - memcpy(&buf[1], &data[0], length); - - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - if (i2c_transfer(rmi4_data->i2c_client->adapter, msg, 1) == 1) { - retval = length; - break; - } - dev_err(&rmi4_data->i2c_client->dev, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - } - - if (retry == SYN_I2C_RETRY_TIMES) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: I2C write over retry limit\n", - __func__); - retval = -EIO; - } - -exit: - mutex_unlock(&(rmi4_data->rmi4_io_ctrl_mutex)); - - return retval; -} - -/** - * synaptics_rmi4_release_all() - * - * Called by synaptics_rmi4_suspend() - * - * Release all touch data during the touch device switch to suspend state. - */ - -static void synaptics_rmi4_release_all(struct synaptics_rmi4_data *rmi4_data) -{ - int finger; - int max_num_fingers = rmi4_data->num_of_fingers; - - for (finger = 0; finger < max_num_fingers; finger++) { - input_mt_slot(rmi4_data->input_dev, finger); - input_mt_report_slot_state(rmi4_data->input_dev, - MT_TOOL_FINGER, 0); - } - - input_report_key(rmi4_data->input_dev, BTN_TOUCH, 0); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, 0); - - input_sync(rmi4_data->input_dev); -} - - /** - * synaptics_rmi4_f11_abs_report() - * - * Called by synaptics_rmi4_report_touch() when valid Function $11 - * finger data has been detected. - * - * This function reads the Function $11 data registers, determines the - * status of each finger supported by the Function, processes any - * necessary coordinate manipulation, reports the finger data to - * the input subsystem, and returns the number of fingers detected. - */ -static int synaptics_rmi4_f11_abs_report(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - unsigned char touch_count = 0; /* number of touch points */ - unsigned char reg_index; - unsigned char finger; - unsigned char fingers_supported; - unsigned char num_of_finger_status_regs; - unsigned char finger_shift; - unsigned char finger_status; - unsigned char data_reg_blk_size; - unsigned char finger_status_reg[3]; - unsigned char data[F11_STD_DATA_LEN]; - unsigned short data_addr; - unsigned short data_offset; - int x; - int y; - int wx; - int wy; - int z; - - /* - * The number of finger status registers is determined by the - * maximum number of fingers supported - 2 bits per finger. So - * the number of finger status registers to read is: - * register_count = ceil(max_num_of_fingers / 4) - */ - fingers_supported = fhandler->num_of_data_points; - num_of_finger_status_regs = (fingers_supported + 3) / 4; - data_addr = fhandler->full_addr.data_base; - data_reg_blk_size = fhandler->size_of_data_register_block; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - data_addr, - finger_status_reg, - num_of_finger_status_regs); - if (retval < 0) - return 0; - - for (finger = 0; finger < fingers_supported; finger++) { - reg_index = finger / 4; - finger_shift = (finger % 4) * 2; - finger_status = (finger_status_reg[reg_index] >> finger_shift) - & MASK_2BIT; - - /* - * Each 2-bit finger status field represents the following: - * 00 = finger not present - * 01 = finger present and data accurate - * 10 = finger present but data may be inaccurate - * 11 = reserved - */ -#ifdef TYPE_B_PROTOCOL - input_mt_slot(rmi4_data->input_dev, finger); - input_mt_report_slot_state(rmi4_data->input_dev, - MT_TOOL_FINGER, finger_status != 0); -#endif - - if (finger_status) { - data_offset = data_addr + - num_of_finger_status_regs + - (finger * data_reg_blk_size); - retval = synaptics_rmi4_i2c_read(rmi4_data, - data_offset, - data, - data_reg_blk_size); - if (retval < 0) - return 0; - - x = (data[0] << 4) | (data[2] & MASK_4BIT); - y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT); - wx = (data[3] & MASK_4BIT); - wy = (data[3] >> 4) & MASK_4BIT; - z = data[4]; - - if (rmi4_data->flip_x) - x = rmi4_data->sensor_max_x - x; - if (rmi4_data->flip_y) - y = rmi4_data->sensor_max_y - y; - - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Finger %d:\n" - "status = 0x%02x\n" - "x = %d\n" - "y = %d\n" - "wx = %d\n" - "wy = %d\n", - __func__, finger, - finger_status, - x, y, wx, wy); - - input_report_abs(rmi4_data->input_dev, - ABS_MT_POSITION_X, x); - input_report_abs(rmi4_data->input_dev, - ABS_MT_POSITION_Y, y); - input_report_abs(rmi4_data->input_dev, - ABS_MT_PRESSURE, z); - -#ifdef REPORT_2D_W - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MAJOR, max(wx, wy)); - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MINOR, min(wx, wy)); -#endif -#ifndef TYPE_B_PROTOCOL - input_mt_sync(rmi4_data->input_dev); -#endif - touch_count++; - } - } - - input_report_key(rmi4_data->input_dev, BTN_TOUCH, touch_count > 0); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, touch_count > 0); - -#ifndef TYPE_B_PROTOCOL - if (!touch_count) - input_mt_sync(rmi4_data->input_dev); -#else - input_mt_report_pointer_emulation(rmi4_data->input_dev, false); -#endif - - input_sync(rmi4_data->input_dev); - - return touch_count; -} - - /** - * synaptics_rmi4_f12_abs_report() - * - * Called by synaptics_rmi4_report_touch() when valid Function $12 - * finger data has been detected. - * - * This function reads the Function $12 data registers, determines the - * status of each finger supported by the Function, processes any - * necessary coordinate manipulation, reports the finger data to - * the input subsystem, and returns the number of fingers detected. - */ -static int synaptics_rmi4_f12_abs_report(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - unsigned char touch_count = 0; /* number of touch points */ - unsigned char finger; - unsigned char fingers_to_process; - unsigned char finger_status; - unsigned char size_of_2d_data; - unsigned short data_addr; - int x; - int y; - int wx; - int wy; - struct synaptics_rmi4_f12_extra_data *extra_data; - struct synaptics_rmi4_f12_finger_data *data; - struct synaptics_rmi4_f12_finger_data *finger_data; - - fingers_to_process = fhandler->num_of_data_points; - data_addr = fhandler->full_addr.data_base; - extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra; - size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data); - - retval = synaptics_rmi4_i2c_read(rmi4_data, - data_addr + extra_data->data1_offset, - (unsigned char *)fhandler->data, - fingers_to_process * size_of_2d_data); - if (retval < 0) - return 0; - - data = (struct synaptics_rmi4_f12_finger_data *)fhandler->data; - - for (finger = 0; finger < fingers_to_process; finger++) { - finger_data = data + finger; - finger_status = finger_data->object_type_and_status & MASK_2BIT; - - /* - * Each 2-bit finger status field represents the following: - * 00 = finger not present - * 01 = finger present and data accurate - * 10 = finger present but data may be inaccurate - * 11 = reserved - */ -#ifdef TYPE_B_PROTOCOL - input_mt_slot(rmi4_data->input_dev, finger); - input_mt_report_slot_state(rmi4_data->input_dev, - MT_TOOL_FINGER, finger_status != 0); -#endif - - if (finger_status) { - x = (finger_data->x_msb << 8) | (finger_data->x_lsb); - y = (finger_data->y_msb << 8) | (finger_data->y_lsb); -#ifdef REPORT_2D_W - wx = finger_data->wx; - wy = finger_data->wy; -#endif - - if (rmi4_data->flip_x) - x = rmi4_data->sensor_max_x - x; - if (rmi4_data->flip_y) - y = rmi4_data->sensor_max_y - y; - - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Finger %d:\n" - "status = 0x%02x\n" - "x = %d\n" - "y = %d\n" - "wx = %d\n" - "wy = %d\n", - __func__, finger, - finger_status, - x, y, wx, wy); - - input_report_key(rmi4_data->input_dev, - BTN_TOUCH, 1); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, 1); - input_report_abs(rmi4_data->input_dev, - ABS_MT_POSITION_X, x); - input_report_abs(rmi4_data->input_dev, - ABS_MT_POSITION_Y, y); -#ifdef REPORT_2D_W - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MAJOR, max(wx, wy)); - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MINOR, min(wx, wy)); -#endif -#ifndef TYPE_B_PROTOCOL - input_mt_sync(rmi4_data->input_dev); -#endif - touch_count++; - } - } - - input_report_key(rmi4_data->input_dev, - BTN_TOUCH, touch_count > 0); - input_report_key(rmi4_data->input_dev, - BTN_TOOL_FINGER, touch_count > 0); -#ifndef TYPE_B_PROTOCOL - if (!touch_count) - input_mt_sync(rmi4_data->input_dev); -#endif - input_mt_report_pointer_emulation(rmi4_data->input_dev, false); - input_sync(rmi4_data->input_dev); - - return touch_count; -} - -static void synaptics_rmi4_f1a_report(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - unsigned char button; - unsigned char index; - unsigned char shift; - unsigned char status; - unsigned char *data; - unsigned short data_addr = fhandler->full_addr.data_base; - struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; - static unsigned char do_once = 1; - static bool current_status[MAX_NUMBER_OF_BUTTONS]; -#ifdef NO_0D_WHILE_2D - static bool before_2d_status[MAX_NUMBER_OF_BUTTONS]; - static bool while_2d_status[MAX_NUMBER_OF_BUTTONS]; -#endif - - if (do_once) { - memset(current_status, 0, sizeof(current_status)); -#ifdef NO_0D_WHILE_2D - memset(before_2d_status, 0, sizeof(before_2d_status)); - memset(while_2d_status, 0, sizeof(while_2d_status)); -#endif - do_once = 0; - } - - retval = synaptics_rmi4_i2c_read(rmi4_data, - data_addr, - f1a->button_data_buffer, - f1a->button_bitmask_size); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to read button data registers\n", - __func__); - return; - } - - data = f1a->button_data_buffer; - - for (button = 0; button < f1a->valid_button_count; button++) { - index = button / 8; - shift = button % 8; - status = ((data[index] >> shift) & MASK_1BIT); - - if (current_status[button] == status) - continue; - else - current_status[button] = status; - - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Button %d (code %d) ->%d\n", - __func__, button, - f1a->button_map[button], - status); -#ifdef NO_0D_WHILE_2D - if (rmi4_data->fingers_on_2d == false) { - if (status == 1) { - before_2d_status[button] = 1; - } else { - if (while_2d_status[button] == 1) { - while_2d_status[button] = 0; - continue; - } else { - before_2d_status[button] = 0; - } - } - input_report_key(rmi4_data->input_dev, - f1a->button_map[button], - status); - } else { - if (before_2d_status[button] == 1) { - before_2d_status[button] = 0; - input_report_key(rmi4_data->input_dev, - f1a->button_map[button], - status); - } else { - if (status == 1) - while_2d_status[button] = 1; - else - while_2d_status[button] = 0; - } - } -#else - input_report_key(rmi4_data->input_dev, - f1a->button_map[button], - status); -#endif - } - - input_sync(rmi4_data->input_dev); - - return; -} - - /** - * synaptics_rmi4_report_touch() - * - * Called by synaptics_rmi4_sensor_report(). - * - * This function calls the appropriate finger data reporting function - * based on the function handler it receives and returns the number of - * fingers detected. - */ -static void synaptics_rmi4_report_touch(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - unsigned char *touch_count) -{ - unsigned char touch_count_2d; - - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Function %02x reporting\n", - __func__, fhandler->fn_number); - - switch (fhandler->fn_number) { - case SYNAPTICS_RMI4_F11: - touch_count_2d = synaptics_rmi4_f11_abs_report(rmi4_data, - fhandler); - - *touch_count += touch_count_2d; - - if (touch_count_2d) - rmi4_data->fingers_on_2d = true; - else - rmi4_data->fingers_on_2d = false; - break; - - case SYNAPTICS_RMI4_F12: - touch_count_2d = synaptics_rmi4_f12_abs_report(rmi4_data, - fhandler); - - if (touch_count_2d) - rmi4_data->fingers_on_2d = true; - else - rmi4_data->fingers_on_2d = false; - break; - - case SYNAPTICS_RMI4_F1A: - synaptics_rmi4_f1a_report(rmi4_data, fhandler); - break; - - default: - break; - } - - return; -} - - /** - * synaptics_rmi4_sensor_report() - * - * Called by synaptics_rmi4_irq(). - * - * This function determines the interrupt source(s) from the sensor - * and calls synaptics_rmi4_report_touch() with the appropriate - * function handler for each function with valid data inputs. - */ -static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char touch_count = 0; - unsigned char intr[MAX_INTR_REGISTERS]; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_exp_fn *exp_fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - if (wake_report) { - wake_report = 0; - input_report_key(rmi4_data->input_dev, KEY_TOUCHPAD_TOGGLE, 1); - input_sync(rmi4_data->input_dev); - input_report_key(rmi4_data->input_dev, KEY_TOUCHPAD_TOGGLE, 0); - input_sync(rmi4_data->input_dev); - } - /* - * Get interrupt status information from F01 Data1 register to - * determine the source(s) that are flagging the interrupt. - */ - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_data_base_addr + 1, - intr, - rmi4_data->num_of_intr_regs); - if (retval < 0) - return retval; - - /* - * Traverse the function handler list and service the source(s) - * of the interrupt accordingly. - */ - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->num_of_data_sources) { - if (fhandler->intr_mask & - intr[fhandler->intr_reg_num]) { - synaptics_rmi4_report_touch(rmi4_data, - fhandler, &touch_count); - } - } - } - } - mutex_unlock(&rmi->support_fn_list_mutex); - - mutex_lock(&exp_fn_list_mutex); - if (!list_empty(&exp_fn_list)) { - list_for_each_entry(exp_fhandler, &exp_fn_list, link) { - if (exp_fhandler->inserted && - (exp_fhandler->func_attn != NULL)) - exp_fhandler->func_attn(rmi4_data, intr[0]); - } - } - mutex_unlock(&exp_fn_list_mutex); - - return touch_count; -} - - /** - * synaptics_rmi4_irq() - * - * Called by the kernel when an interrupt occurs (when the sensor - * asserts the attention irq). - * - * This function is the ISR thread and handles the acquisition - * and the reporting of finger data when the presence of fingers - * is detected. - */ -static irqreturn_t synaptics_rmi4_irq(int irq, void *data) -{ - struct synaptics_rmi4_data *rmi4_data = data; - - if (IRQ_HANDLED == synaptics_filter_interrupt(data)) - return IRQ_HANDLED; - - synaptics_rmi4_sensor_report(rmi4_data); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_OF -static int synaptics_rmi4_get_button_map(struct device *dev, char *name, - struct synaptics_rmi4_platform_data *rmi4_pdata, - struct device_node *np) -{ - struct property *prop; - int rc, i; - u32 temp_val, num_buttons; - u32 button_map[MAX_NUMBER_OF_BUTTONS]; - - prop = of_find_property(np, "synaptics,button-map", NULL); - if (prop) { - num_buttons = prop->length / sizeof(temp_val); - - rmi4_pdata->capacitance_button_map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->capacitance_button_map), - GFP_KERNEL); - if (!rmi4_pdata->capacitance_button_map) - return -ENOMEM; - - rmi4_pdata->capacitance_button_map->map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->capacitance_button_map->map) * - MAX_NUMBER_OF_BUTTONS, GFP_KERNEL); - if (!rmi4_pdata->capacitance_button_map->map) - return -ENOMEM; - - if (num_buttons <= MAX_NUMBER_OF_BUTTONS) { - rc = of_property_read_u32_array(np, - "synaptics,button-map", button_map, - num_buttons); - if (rc) { - dev_err(dev, "Unable to read key codes\n"); - return rc; - } - for (i = 0; i < num_buttons; i++) - rmi4_pdata->capacitance_button_map->map[i] = - button_map[i]; - rmi4_pdata->capacitance_button_map->nbuttons = - num_buttons; - } else { - return -EINVAL; - } - } - return 0; -} - -static int synaptics_rmi4_get_dt_coords(struct device *dev, char *name, - struct synaptics_rmi4_platform_data *pdata, - struct device_node *node) -{ - u32 coords[RMI4_COORDS_ARR_SIZE]; - struct property *prop; - struct device_node *np = (node == NULL) ? (dev->of_node) : (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 != RMI4_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, "synaptics,panel-coords") == 0) { - pdata->panel_minx = coords[0]; - pdata->panel_miny = coords[1]; - pdata->panel_maxx = coords[2]; - pdata->panel_maxy = coords[3]; - - if (pdata->panel_maxx == 0 || pdata->panel_minx > 0) - rc = -EINVAL; - else if (pdata->panel_maxy == 0 || pdata->panel_miny > 0) - rc = -EINVAL; - - if (rc) { - dev_err(dev, "Invalid panel resolution %d\n", rc); - return rc; - } - } else if (strcmp(name, "synaptics,display-coords") == 0) { - pdata->disp_minx = coords[0]; - pdata->disp_miny = coords[1]; - pdata->disp_maxx = coords[2]; - pdata->disp_maxy = coords[3]; - } else { - dev_err(dev, "unsupported property %s\n", name); - return -EINVAL; - } - - return 0; -} - -static int synaptics_rmi4_parse_dt_children(struct device *dev, - struct synaptics_rmi4_platform_data *rmi4_pdata, - struct synaptics_rmi4_data *rmi4_data) -{ - struct synaptics_rmi4_device_info *rmi = &(rmi4_data->rmi4_mod_info); - struct device_node *node = dev->of_node, *child; - int rc = 0; - struct synaptics_rmi4_fn *fhandler = NULL; - - for_each_child_of_node(node, child) { - rc = of_property_read_u32(child, "synaptics,package-id", - &rmi4_pdata->package_id); - if (rc && (rc != -EINVAL)) { - dev_err(dev, "Unable to read package_id\n"); - return rc; - } else if (rc == -EINVAL) { - rmi4_pdata->package_id = 0x00; - } - - if (rmi4_pdata->package_id) { - if (rmi4_pdata->package_id != rmi->package_id) { - dev_err(dev, - "%s: Synaptics package id don't match %d %d\n", - __func__, - rmi4_pdata->package_id, - rmi->package_id); - - continue; - } - } - - rc = synaptics_rmi4_get_dt_coords(dev, - "synaptics,display-coords", - rmi4_pdata, - child); - if (rc && (rc != -EINVAL)) - return rc; - - rc = synaptics_rmi4_get_dt_coords(dev, "synaptics,panel-coords", - rmi4_pdata, child); - if (rc && (rc != -EINVAL)) - return rc; - - rc = synaptics_rmi4_get_button_map(dev, "synaptics,button-map", - rmi4_pdata, child); - if (rc < 0) { - dev_err(dev, "Unable to read key codes\n"); - return rc; - } - - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, - &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) - break; - } - } - mutex_unlock(&rmi->support_fn_list_mutex); - - if (fhandler != NULL && fhandler->fn_number == - SYNAPTICS_RMI4_F1A) { - rc = synaptics_rmi4_capacitance_button_map(rmi4_data, - fhandler); - if (rc < 0) { - dev_err(dev, "Fail to register F1A %d\n", rc); - return rc; - } - } - break; - } - - return 0; -} - -static int synaptics_rmi4_parse_dt(struct device *dev, - struct synaptics_rmi4_platform_data *rmi4_pdata) -{ - struct device_node *np = dev->of_node; - struct property *prop; - u32 temp_val, num_buttons; - u32 button_map[MAX_NUMBER_OF_BUTTONS]; - int rc, i; - - rmi4_pdata->i2c_pull_up = of_property_read_bool(np, - "synaptics,i2c-pull-up"); - rmi4_pdata->power_down_enable = of_property_read_bool(np, - "synaptics,power-down"); - rmi4_pdata->disable_gpios = of_property_read_bool(np, - "synaptics,disable-gpios"); - rmi4_pdata->modify_reso = of_property_read_bool(np, - "synaptics,modify-reso"); - rmi4_pdata->x_flip = of_property_read_bool(np, "synaptics,x-flip"); - rmi4_pdata->y_flip = of_property_read_bool(np, "synaptics,y-flip"); - rmi4_pdata->do_lockdown = of_property_read_bool(np, - "synaptics,do-lockdown"); - rmi4_pdata->is_wake = of_property_read_bool(np, - "synaptics,is_wake"); - - rc = synaptics_rmi4_get_dt_coords(dev, "synaptics,display-coords", - rmi4_pdata, NULL); - if (rc && (rc != -EINVAL)) - return rc; - - rc = synaptics_rmi4_get_dt_coords(dev, "synaptics,panel-coords", - rmi4_pdata, NULL); - if (rc && (rc != -EINVAL)) - return rc; - - rmi4_pdata->reset_delay = RESET_DELAY; - rc = of_property_read_u32(np, "synaptics,reset-delay", &temp_val); - if (!rc) - rmi4_pdata->reset_delay = temp_val; - else if (rc != -EINVAL) { - dev_err(dev, "Unable to read reset delay\n"); - return rc; - } - - rc = of_property_read_string(np, "synaptics,fw-image-name", - &rmi4_pdata->fw_image_name); - if (rc && (rc != -EINVAL)) { - dev_err(dev, "Unable to read fw image name\n"); - return rc; - } - - /* reset, irq gpio info */ - rmi4_pdata->reset_gpio = of_get_named_gpio_flags(np, - "synaptics,reset-gpio", 0, &rmi4_pdata->reset_flags); - rmi4_pdata->irq_gpio = of_get_named_gpio_flags(np, - "synaptics,irq-gpio", 0, &rmi4_pdata->irq_flags); - - rmi4_pdata->detect_device = of_property_read_bool(np, - "synaptics,detect-device"); - - if (rmi4_pdata->detect_device) - return 0; - - prop = of_find_property(np, "synaptics,button-map", NULL); - if (prop) { - num_buttons = prop->length / sizeof(temp_val); - - rmi4_pdata->capacitance_button_map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->capacitance_button_map), - GFP_KERNEL); - if (!rmi4_pdata->capacitance_button_map) - return -ENOMEM; - - rmi4_pdata->capacitance_button_map->map = devm_kzalloc(dev, - sizeof(*rmi4_pdata->capacitance_button_map->map) * - MAX_NUMBER_OF_BUTTONS, GFP_KERNEL); - if (!rmi4_pdata->capacitance_button_map->map) - return -ENOMEM; - - if (num_buttons <= MAX_NUMBER_OF_BUTTONS) { - rc = of_property_read_u32_array(np, - "synaptics,button-map", button_map, - num_buttons); - if (rc) { - dev_err(dev, "Unable to read key codes\n"); - return rc; - } - for (i = 0; i < num_buttons; i++) - rmi4_pdata->capacitance_button_map->map[i] = - button_map[i]; - rmi4_pdata->capacitance_button_map->nbuttons = - num_buttons; - } else { - return -EINVAL; - } - } - - return 0; -} -#else -static inline int synaptics_rmi4_parse_dt(struct device *dev, - struct synaptics_rmi4_platform_data *rmi4_pdata) -{ - return 0; -} -#endif - - /** - * synaptics_rmi4_irq_enable() - * - * Called by synaptics_rmi4_probe() and the power management functions - * in this driver and also exported to other expansion Function modules - * such as rmi_dev. - * - * This function handles the enabling and disabling of the attention - * irq including the setting up of the ISR thread. - */ -static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - int retval = 0; - unsigned char *intr_status; - - if (enable) { - if (rmi4_data->irq_enabled) - return retval; - - intr_status = kzalloc(rmi4_data->num_of_intr_regs, GFP_KERNEL); - if (!intr_status) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc memory\n", - __func__); - return -ENOMEM; - } - /* Clear interrupts first */ - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_data_base_addr + 1, - intr_status, - rmi4_data->num_of_intr_regs); - kfree(intr_status); - if (retval < 0) - return retval; - - enable_irq(rmi4_data->irq); - - rmi4_data->irq_enabled = true; - } else { - if (rmi4_data->irq_enabled) { - disable_irq(rmi4_data->irq); - rmi4_data->irq_enabled = false; - } - } - - return retval; -} - - /** - * synaptics_rmi4_f11_init() - * - * Called by synaptics_rmi4_query_device(). - * - * This funtion parses information from the Function 11 registers - * and determines the number of fingers supported, x and y data ranges, - * offset to the associated interrupt status register, interrupt bit - * mask, and gathers finger data acquisition capabilities from the query - * registers. - */ -static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count) -{ - int retval; - unsigned char ii; - unsigned char intr_offset; - unsigned char abs_data_size; - unsigned char abs_data_blk_size; - unsigned char query[F11_STD_QUERY_LEN]; - unsigned char control[F11_STD_CTRL_LEN]; - - fhandler->fn_number = fd->fn_number; - fhandler->num_of_data_sources = fd->intr_src_count; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - fhandler->full_addr.query_base, - query, - sizeof(query)); - if (retval < 0) - return retval; - - /* Maximum number of fingers supported */ - if ((query[1] & MASK_3BIT) <= 4) - fhandler->num_of_data_points = (query[1] & MASK_3BIT) + 1; - else if ((query[1] & MASK_3BIT) == 5) - fhandler->num_of_data_points = 10; - - rmi4_data->num_of_fingers = fhandler->num_of_data_points; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - fhandler->full_addr.ctrl_base, - control, - sizeof(control)); - if (retval < 0) - return retval; - - /* Maximum x */ - rmi4_data->sensor_max_x = ((control[6] & MASK_8BIT) << 0) | - ((control[7] & MASK_4BIT) << 8); - - if (rmi4_data->board->modify_reso) { - if (rmi4_data->board->panel_maxx) { - if (rmi4_data->board->panel_maxx >= F11_MAX_X) { - dev_err(&rmi4_data->i2c_client->dev, - "F11 max_x value out of bound."); - return -EINVAL; - } - if (rmi4_data->sensor_max_x != - rmi4_data->board->panel_maxx) { - rmi4_data->sensor_max_x = - rmi4_data->board->panel_maxx; - control[6] = rmi4_data->board->panel_maxx - & MASK_8BIT; - control[7] = (rmi4_data->board->panel_maxx >> 8) - & MASK_4BIT; - retval = synaptics_rmi4_i2c_write(rmi4_data, - fhandler->full_addr.ctrl_base, - control, - sizeof(control)); - if (retval < 0) - return retval; - } - } - } - - /* Maximum y */ - rmi4_data->sensor_max_y = ((control[8] & MASK_8BIT) << 0) | - ((control[9] & MASK_4BIT) << 8); - - if (rmi4_data->board->modify_reso) { - if (rmi4_data->board->panel_maxy) { - if (rmi4_data->board->panel_maxy >= F11_MAX_Y) { - dev_err(&rmi4_data->i2c_client->dev, - "F11 max_y value out of bound."); - return -EINVAL; - } - if (rmi4_data->sensor_max_y != - rmi4_data->board->panel_maxy) { - rmi4_data->sensor_max_y = - rmi4_data->board->panel_maxy; - control[8] = rmi4_data->board->panel_maxy - & MASK_8BIT; - control[9] = (rmi4_data->board->panel_maxy >> 8) - & MASK_4BIT; - retval = synaptics_rmi4_i2c_write(rmi4_data, - fhandler->full_addr.ctrl_base, - control, - sizeof(control)); - if (retval < 0) - return retval; - } - } - } - - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Function %02x max x = %d max y = %d\n", - __func__, fhandler->fn_number, - rmi4_data->sensor_max_x, - rmi4_data->sensor_max_y); - - rmi4_data->max_touch_width = MAX_F11_TOUCH_WIDTH; - - fhandler->intr_reg_num = (intr_count + 7) / 8; - if (fhandler->intr_reg_num != 0) - fhandler->intr_reg_num -= 1; - - /* Set an enable bit for each data source */ - intr_offset = intr_count % 8; - fhandler->intr_mask = 0; - for (ii = intr_offset; - ii < ((fd->intr_src_count & MASK_3BIT) + - intr_offset); - ii++) - fhandler->intr_mask |= 1 << ii; - - abs_data_size = query[5] & MASK_2BIT; - abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0)); - fhandler->size_of_data_register_block = abs_data_blk_size; - - return retval; -} - -static int synaptics_rmi4_f12_set_enables(struct synaptics_rmi4_data *rmi4_data, - unsigned short ctrl28) -{ - int retval; - static unsigned short ctrl_28_address; - - if (ctrl28) - ctrl_28_address = ctrl28; - - retval = synaptics_rmi4_i2c_write(rmi4_data, - ctrl_28_address, - &rmi4_data->report_enable, - sizeof(rmi4_data->report_enable)); - if (retval < 0) - return retval; - - return retval; -} - - /** - * synaptics_rmi4_f12_init() - * - * Called by synaptics_rmi4_query_device(). - * - * This funtion parses information from the Function 12 registers and - * determines the number of fingers supported, offset to the data1 - * register, x and y data ranges, offset to the associated interrupt - * status register, interrupt bit mask, and allocates memory resources - * for finger data acquisition. - */ -static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count) -{ - int retval; - unsigned char ii; - unsigned char intr_offset; - unsigned char size_of_2d_data; - unsigned char size_of_query8; - unsigned char ctrl_8_offset; - unsigned char ctrl_23_offset; - unsigned char ctrl_28_offset; - unsigned char num_of_fingers; - struct synaptics_rmi4_f12_extra_data *extra_data; - struct synaptics_rmi4_f12_query_5 query_5; - struct synaptics_rmi4_f12_query_8 query_8; - struct synaptics_rmi4_f12_ctrl_8 ctrl_8; - struct synaptics_rmi4_f12_ctrl_23 ctrl_23; - - fhandler->fn_number = fd->fn_number; - fhandler->num_of_data_sources = fd->intr_src_count; - fhandler->extra = kmalloc(sizeof(*extra_data), GFP_KERNEL); - extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra; - size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data); - - retval = synaptics_rmi4_i2c_read(rmi4_data, - fhandler->full_addr.query_base + 5, - query_5.data, - sizeof(query_5.data)); - if (retval < 0) - return retval; - - ctrl_8_offset = query_5.ctrl0_is_present + - query_5.ctrl1_is_present + - query_5.ctrl2_is_present + - query_5.ctrl3_is_present + - query_5.ctrl4_is_present + - query_5.ctrl5_is_present + - query_5.ctrl6_is_present + - query_5.ctrl7_is_present; - - ctrl_23_offset = ctrl_8_offset + - query_5.ctrl8_is_present + - query_5.ctrl9_is_present + - query_5.ctrl10_is_present + - query_5.ctrl11_is_present + - query_5.ctrl12_is_present + - query_5.ctrl13_is_present + - query_5.ctrl14_is_present + - query_5.ctrl15_is_present + - query_5.ctrl16_is_present + - query_5.ctrl17_is_present + - query_5.ctrl18_is_present + - query_5.ctrl19_is_present + - query_5.ctrl20_is_present + - query_5.ctrl21_is_present + - query_5.ctrl22_is_present; - - ctrl_28_offset = ctrl_23_offset + - query_5.ctrl23_is_present + - query_5.ctrl24_is_present + - query_5.ctrl25_is_present + - query_5.ctrl26_is_present + - query_5.ctrl27_is_present; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_23_offset, - ctrl_23.data, - sizeof(ctrl_23.data)); - if (retval < 0) - return retval; - - /* Maximum number of fingers supported */ - fhandler->num_of_data_points = min(ctrl_23.max_reported_objects, - (unsigned char)F12_FINGERS_TO_SUPPORT); - - num_of_fingers = fhandler->num_of_data_points; - rmi4_data->num_of_fingers = num_of_fingers; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - fhandler->full_addr.query_base + 7, - &size_of_query8, - sizeof(size_of_query8)); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - fhandler->full_addr.query_base + 8, - query_8.data, - size_of_query8); - if (retval < 0) - return retval; - - /* Determine the presence of the Data0 register */ - extra_data->data1_offset = query_8.data0_is_present; - - if ((size_of_query8 >= 3) && (query_8.data15_is_present)) { - extra_data->data15_offset = query_8.data0_is_present + - query_8.data1_is_present + - query_8.data2_is_present + - query_8.data3_is_present + - query_8.data4_is_present + - query_8.data5_is_present + - query_8.data6_is_present + - query_8.data7_is_present + - query_8.data8_is_present + - query_8.data9_is_present + - query_8.data10_is_present + - query_8.data11_is_present + - query_8.data12_is_present + - query_8.data13_is_present + - query_8.data14_is_present; - extra_data->data15_size = (num_of_fingers + 7) / 8; - } else { - extra_data->data15_size = 0; - } - - rmi4_data->report_enable = RPT_DEFAULT; -#ifdef REPORT_2D_Z - rmi4_data->report_enable |= RPT_Z; -#endif -#ifdef REPORT_2D_W - rmi4_data->report_enable |= (RPT_WX | RPT_WY); -#endif - - retval = synaptics_rmi4_f12_set_enables(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_28_offset); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_8_offset, - ctrl_8.data, - sizeof(ctrl_8.data)); - if (retval < 0) - return retval; - - /* Maximum x */ - rmi4_data->sensor_max_x = - ((unsigned short)ctrl_8.max_x_coord_lsb << 0) | - ((unsigned short)ctrl_8.max_x_coord_msb << 8); - - if (rmi4_data->board->modify_reso) { - if (rmi4_data->board->panel_maxx) { - if (rmi4_data->board->panel_maxx >= F12_MAX_X) { - dev_err(&rmi4_data->i2c_client->dev, - "F12 max_x value out of bound."); - return -EINVAL; - } - if (rmi4_data->sensor_max_x != - rmi4_data->board->panel_maxx) { - rmi4_data->sensor_max_x = - rmi4_data->board->panel_maxx; - ctrl_8.max_x_coord_lsb = (unsigned char) - (rmi4_data->board->panel_maxx - & MASK_8BIT); - ctrl_8.max_x_coord_msb = (unsigned char) - ((rmi4_data->board->panel_maxx >> 8) - & MASK_8BIT); - retval = synaptics_rmi4_i2c_write(rmi4_data, - fhandler->full_addr.ctrl_base - + ctrl_8_offset, - ctrl_8.data, - sizeof(ctrl_8.data)); - if (retval < 0) - return retval; - } - } - } - - /* Maximum y */ - rmi4_data->sensor_max_y = - ((unsigned short)ctrl_8.max_y_coord_lsb << 0) | - ((unsigned short)ctrl_8.max_y_coord_msb << 8); - - if (rmi4_data->board->modify_reso) { - if (rmi4_data->board->panel_maxy) { - if (rmi4_data->board->panel_maxy >= F12_MAX_Y) { - dev_err(&rmi4_data->i2c_client->dev, - "F12 max_y value out of bound."); - return -EINVAL; - } - if (rmi4_data->sensor_max_y != - rmi4_data->board->panel_maxy) { - rmi4_data->sensor_max_y = - rmi4_data->board->panel_maxy; - ctrl_8.max_y_coord_lsb = (unsigned char) - (rmi4_data->board->panel_maxy - & MASK_8BIT); - ctrl_8.max_y_coord_msb = (unsigned char) - ((rmi4_data->board->panel_maxy >> 8) - & MASK_8BIT); - retval = synaptics_rmi4_i2c_write(rmi4_data, - fhandler->full_addr.ctrl_base - + ctrl_8_offset, - ctrl_8.data, - sizeof(ctrl_8.data)); - if (retval < 0) - return retval; - } - } - } - - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Function %02x max x = %d max y = %d\n", - __func__, fhandler->fn_number, - rmi4_data->sensor_max_x, - rmi4_data->sensor_max_y); - - rmi4_data->num_of_rx = ctrl_8.num_of_rx; - rmi4_data->num_of_tx = ctrl_8.num_of_tx; - rmi4_data->max_touch_width = max(rmi4_data->num_of_rx, - rmi4_data->num_of_tx); - - fhandler->intr_reg_num = (intr_count + 7) / 8; - if (fhandler->intr_reg_num != 0) - fhandler->intr_reg_num -= 1; - - /* Set an enable bit for each data source */ - intr_offset = intr_count % 8; - fhandler->intr_mask = 0; - for (ii = intr_offset; - ii < ((fd->intr_src_count & MASK_3BIT) + - intr_offset); - ii++) - fhandler->intr_mask |= 1 << ii; - - /* Allocate memory for finger data storage space */ - fhandler->data_size = num_of_fingers * size_of_2d_data; - fhandler->data = kmalloc(fhandler->data_size, GFP_KERNEL); - - return retval; -} - -static int synaptics_rmi4_f1a_alloc_mem(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int retval; - struct synaptics_rmi4_f1a_handle *f1a; - - f1a = kzalloc(sizeof(*f1a), GFP_KERNEL); - if (!f1a) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for function handle\n", - __func__); - return -ENOMEM; - } - - fhandler->data = (void *)f1a; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - fhandler->full_addr.query_base, - f1a->button_query.data, - sizeof(f1a->button_query.data)); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to read query registers\n", - __func__); - return retval; - } - - f1a->button_count = f1a->button_query.max_button_count + 1; - f1a->button_bitmask_size = (f1a->button_count + 7) / 8; - - f1a->button_data_buffer = kcalloc(f1a->button_bitmask_size, - sizeof(*(f1a->button_data_buffer)), GFP_KERNEL); - if (!f1a->button_data_buffer) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for data buffer\n", - __func__); - return -ENOMEM; - } - - f1a->button_map = kcalloc(f1a->button_count, - sizeof(*(f1a->button_map)), GFP_KERNEL); - if (!f1a->button_map) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for button map\n", - __func__); - return -ENOMEM; - } - - return 0; -} - -static int synaptics_rmi4_capacitance_button_map( - struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - unsigned char ii; - struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; - const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board; - - if (!pdata->capacitance_button_map) { - dev_info(&rmi4_data->i2c_client->dev, - "%s: capacitance_button_map not in use\n", - __func__); - return 0; - } else if (!pdata->capacitance_button_map->map) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Button map is missing in board file\n", - __func__); - return -ENODEV; - } else { - if (pdata->capacitance_button_map->nbuttons != - f1a->button_count) { - f1a->valid_button_count = min(f1a->button_count, - pdata->capacitance_button_map->nbuttons); - } else { - f1a->valid_button_count = f1a->button_count; - } - - for (ii = 0; ii < f1a->valid_button_count; ii++) - f1a->button_map[ii] = - pdata->capacitance_button_map->map[ii]; - } - - return 0; -} - -static void synaptics_rmi4_f1a_kfree(struct synaptics_rmi4_fn *fhandler) -{ - struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; - - if (f1a) { - kfree(f1a->button_data_buffer); - kfree(f1a->button_map); - kfree(f1a); - fhandler->data = NULL; - } - - return; -} - -static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count) -{ - int retval; - unsigned char ii; - unsigned short intr_offset; - - fhandler->fn_number = fd->fn_number; - fhandler->num_of_data_sources = fd->intr_src_count; - - fhandler->intr_reg_num = (intr_count + 7) / 8; - if (fhandler->intr_reg_num != 0) - fhandler->intr_reg_num -= 1; - - /* Set an enable bit for each data source */ - intr_offset = intr_count % 8; - fhandler->intr_mask = 0; - for (ii = intr_offset; - ii < ((fd->intr_src_count & MASK_3BIT) + - intr_offset); - ii++) - fhandler->intr_mask |= 1 << ii; - - retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler); - if (retval < 0) - goto error_exit; - - retval = synaptics_rmi4_capacitance_button_map(rmi4_data, fhandler); - if (retval < 0) - goto error_exit; - - rmi4_data->button_0d_enabled = 1; - - return 0; - -error_exit: - synaptics_rmi4_f1a_kfree(fhandler); - - return retval; -} - -static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler, - struct synaptics_rmi4_fn_desc *rmi_fd, int page_number) -{ - *fhandler = kzalloc(sizeof(**fhandler), GFP_KERNEL); - if (!(*fhandler)) - return -ENOMEM; - - (*fhandler)->full_addr.data_base = - (rmi_fd->data_base_addr | - (page_number << 8)); - (*fhandler)->full_addr.ctrl_base = - (rmi_fd->ctrl_base_addr | - (page_number << 8)); - (*fhandler)->full_addr.cmd_base = - (rmi_fd->cmd_base_addr | - (page_number << 8)); - (*fhandler)->full_addr.query_base = - (rmi_fd->query_base_addr | - (page_number << 8)); - (*fhandler)->fn_number = rmi_fd->fn_number; - - return 0; -} - - - /** - * synaptics_rmi4_query_device_info() - * - * Called by synaptics_rmi4_query_device(). - * - */ -static int synaptics_rmi4_query_device_info( - struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char f01_query[F01_STD_QUERY_LEN]; - struct synaptics_rmi4_device_info *rmi = &(rmi4_data->rmi4_mod_info); - unsigned char pkg_id[4]; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_query_base_addr, - f01_query, - sizeof(f01_query)); - if (retval < 0) - return retval; - - /* RMI Version 4.0 currently supported */ - rmi->version_major = 4; - rmi->version_minor = 0; - - rmi->manufacturer_id = f01_query[0]; - rmi->product_props = f01_query[1]; - rmi->product_info[0] = f01_query[2] & MASK_7BIT; - rmi->product_info[1] = f01_query[3] & MASK_7BIT; - rmi->date_code[0] = f01_query[4] & MASK_5BIT; - rmi->date_code[1] = f01_query[5] & MASK_4BIT; - rmi->date_code[2] = f01_query[6] & MASK_5BIT; - rmi->tester_id = ((f01_query[7] & MASK_7BIT) << 8) | - (f01_query[8] & MASK_7BIT); - rmi->serial_number = ((f01_query[9] & MASK_7BIT) << 8) | - (f01_query[10] & MASK_7BIT); - memcpy(rmi->product_id_string, &f01_query[11], 10); - - if (rmi->manufacturer_id != 1) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Non-Synaptics device found, manufacturer ID = %d\n", - __func__, rmi->manufacturer_id); - } - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_query_base_addr + F01_PACKAGE_ID_OFFSET, - pkg_id, - sizeof(pkg_id)); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to read device package id (code %d)\n", - __func__, retval); - return retval; - } - - rmi->package_id = (pkg_id[1] << 8) | pkg_id[0]; - rmi->package_id_rev = (pkg_id[3] << 8) | pkg_id[2]; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_query_base_addr + F01_BUID_ID_OFFSET, - rmi->build_id, - sizeof(rmi->build_id)); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to read firmware build id (code %d)\n", - __func__, retval); - return retval; - } - return 0; -} - -/* -* This function checks whether the fhandler already existis in the -* support_fn_list or not. -* If it exists then return 1 as found or return 0 as not found. -* -* Called by synaptics_rmi4_query_device(). -*/ -static int synaptics_rmi4_check_fn_list(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler) -{ - int found = 0; - struct synaptics_rmi4_fn *new_fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) - list_for_each_entry(new_fhandler, &rmi->support_fn_list, link) - if (new_fhandler->fn_number == fhandler->fn_number) - found = 1; - mutex_unlock(&rmi->support_fn_list_mutex); - - return found; -} - - /** - * synaptics_rmi4_query_device() - * - * Called by synaptics_rmi4_probe(). - * - * This funtion scans the page description table, records the offsets - * to the register types of Function $01, sets up the function handlers - * for Function $11 and Function $12, determines the number of interrupt - * sources from the sensor, adds valid Functions with data inputs to the - * Function linked list, parses information from the query registers of - * Function $01, and enables the interrupt sources from the valid Functions - * with data inputs. - */ -static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval, found; - unsigned char ii; - unsigned char page_number; - unsigned char intr_count = 0; - unsigned char data_sources = 0; - unsigned short pdt_entry_addr; - unsigned short intr_addr; - struct synaptics_rmi4_f01_device_status status; - struct synaptics_rmi4_fn_desc rmi_fd; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - /* Scan the page description tables of the pages to service */ - for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) { - for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END; - pdt_entry_addr -= PDT_ENTRY_SIZE) { - pdt_entry_addr |= (page_number << 8); - - retval = synaptics_rmi4_i2c_read(rmi4_data, - pdt_entry_addr, - (unsigned char *)&rmi_fd, - sizeof(rmi_fd)); - if (retval < 0) - return retval; - - fhandler = NULL; - found = 0; - if (rmi_fd.fn_number == 0) { - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Reached end of PDT\n", - __func__); - break; - } - - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: F%02x found (page %d)\n", - __func__, rmi_fd.fn_number, - page_number); - - switch (rmi_fd.fn_number) { - case SYNAPTICS_RMI4_F01: - rmi4_data->f01_query_base_addr = - rmi_fd.query_base_addr; - rmi4_data->f01_ctrl_base_addr = - rmi_fd.ctrl_base_addr; - rmi4_data->f01_data_base_addr = - rmi_fd.data_base_addr; - rmi4_data->f01_cmd_base_addr = - rmi_fd.cmd_base_addr; - - retval = - synaptics_rmi4_query_device_info(rmi4_data); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_data_base_addr, - status.data, - sizeof(status.data)); - if (retval < 0) - return retval; - - while (status.status_code == STATUS_CRC_IN_PROGRESS) { - msleep(1); - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_data_base_addr, - status.data, - sizeof(status.data)); - if (retval < 0) - return retval; - } - - if (status.flash_prog == 1) { - pr_notice("%s: In flash prog mode, status = 0x%02x\n", - __func__, - status.status_code); - goto flash_prog_mode; - } - break; - - case SYNAPTICS_RMI4_F11: - if (rmi_fd.intr_src_count == 0) - break; - - retval = synaptics_rmi4_alloc_fh(&fhandler, - &rmi_fd, page_number); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc for F%d\n", - __func__, - rmi_fd.fn_number); - return retval; - } - - retval = synaptics_rmi4_f11_init(rmi4_data, - fhandler, &rmi_fd, intr_count); - if (retval < 0) - return retval; - break; - - case SYNAPTICS_RMI4_F12: - if (rmi_fd.intr_src_count == 0) - break; - - retval = synaptics_rmi4_alloc_fh(&fhandler, - &rmi_fd, page_number); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc for F%d\n", - __func__, - rmi_fd.fn_number); - return retval; - } - - retval = synaptics_rmi4_f12_init(rmi4_data, - fhandler, &rmi_fd, intr_count); - if (retval < 0) - return retval; - break; - - case SYNAPTICS_RMI4_F1A: - if (rmi_fd.intr_src_count == 0) - break; - - retval = synaptics_rmi4_alloc_fh(&fhandler, - &rmi_fd, page_number); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc for F%d\n", - __func__, - rmi_fd.fn_number); - return retval; - } - - retval = synaptics_rmi4_f1a_init(rmi4_data, - fhandler, &rmi_fd, intr_count); - if (retval < 0) - return retval; - break; - } - - /* Accumulate the interrupt count */ - intr_count += (rmi_fd.intr_src_count & MASK_3BIT); - - if (fhandler && rmi_fd.intr_src_count) { - /* Want to check whether the fhandler already - exists in the support_fn_list or not. - If not found then add it to the list, otherwise - free the memory allocated to it. - */ - found = synaptics_rmi4_check_fn_list(rmi4_data, - fhandler); - - if (!found) { - mutex_lock(&rmi->support_fn_list_mutex); - list_add_tail(&fhandler->link, - &rmi->support_fn_list); - mutex_unlock( - &rmi->support_fn_list_mutex); - } else { - if (fhandler->fn_number == - SYNAPTICS_RMI4_F1A) { - synaptics_rmi4_f1a_kfree( - fhandler); - } else { - kfree(fhandler->data); - kfree(fhandler->extra); - } - kfree(fhandler); - } - } - } - } - -flash_prog_mode: - rmi4_data->num_of_intr_regs = (intr_count + 7) / 8; - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Number of interrupt registers = %d\n", - __func__, rmi4_data->num_of_intr_regs); - - memset(rmi4_data->intr_mask, 0x00, sizeof(rmi4_data->intr_mask)); - - /* - * Map out the interrupt bit masks for the interrupt sources - * from the registered function handlers. - */ - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, &rmi->support_fn_list, link) - data_sources += fhandler->num_of_data_sources; - } - mutex_unlock(&rmi->support_fn_list_mutex); - - if (data_sources) { - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, - &rmi->support_fn_list, link) { - if (fhandler->num_of_data_sources) { - rmi4_data->intr_mask[fhandler->intr_reg_num] |= - fhandler->intr_mask; - } - } - } - mutex_unlock(&rmi->support_fn_list_mutex); - } - - /* Enable the interrupt sources */ - for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) { - if (rmi4_data->intr_mask[ii] != 0x00) { - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Interrupt enable mask %d = 0x%02x\n", - __func__, ii, rmi4_data->intr_mask[ii]); - intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii; - retval = synaptics_rmi4_i2c_write(rmi4_data, - intr_addr, - &(rmi4_data->intr_mask[ii]), - sizeof(rmi4_data->intr_mask[ii])); - if (retval < 0) - return retval; - } - } - - return 0; -} - -static int synaptics_rmi4_reset_command(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - int page_number; - unsigned char command = 0x01; - unsigned short pdt_entry_addr; - struct synaptics_rmi4_fn_desc rmi_fd; - bool done = false; - - /* Scan the page description tables of the pages to service */ - for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) { - for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END; - pdt_entry_addr -= PDT_ENTRY_SIZE) { - retval = synaptics_rmi4_i2c_read(rmi4_data, - pdt_entry_addr, - (unsigned char *)&rmi_fd, - sizeof(rmi_fd)); - if (retval < 0) - return retval; - - if (rmi_fd.fn_number == 0) - break; - - switch (rmi_fd.fn_number) { - case SYNAPTICS_RMI4_F01: - rmi4_data->f01_cmd_base_addr = - rmi_fd.cmd_base_addr; - done = true; - break; - } - } - if (done) { - dev_info(&rmi4_data->i2c_client->dev, - "%s: Find F01 in page description table 0x%x\n", - __func__, rmi4_data->f01_cmd_base_addr); - break; - } - } - - if (!done) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Cannot find F01 in page description table\n", - __func__); - return -EINVAL; - } - - retval = synaptics_rmi4_i2c_write(rmi4_data, - rmi4_data->f01_cmd_base_addr, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to issue reset command, error = %d\n", - __func__, retval); - return retval; - } - - msleep(rmi4_data->board->reset_delay); - return retval; -}; - -static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_fn *next_fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - retval = synaptics_rmi4_reset_command(rmi4_data); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to send command reset\n", - __func__); - return retval; - } - - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry_safe(fhandler, next_fhandler, - &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) - synaptics_rmi4_f1a_kfree(fhandler); - else { - kfree(fhandler->data); - kfree(fhandler->extra); - } - kfree(fhandler); - } - } - - INIT_LIST_HEAD(&rmi->support_fn_list); - - retval = synaptics_rmi4_query_device(rmi4_data); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to query device\n", - __func__); - return retval; - } - - return 0; -} - -/** -* synaptics_rmi4_detection_work() -* -* Called by the kernel at the scheduled time. -* -* This function is a self-rearming work thread that checks for the -* insertion and removal of other expansion Function modules such as -* rmi_dev and calls their initialization and removal callback functions -* accordingly. -*/ -static void synaptics_rmi4_detection_work(struct work_struct *work) -{ - struct synaptics_rmi4_exp_fn *exp_fhandler, *next_list_entry; - struct synaptics_rmi4_data *rmi4_data = - container_of(work, struct synaptics_rmi4_data, - det_work.work); - - mutex_lock(&exp_fn_list_mutex); - if (!list_empty(&exp_fn_list)) { - list_for_each_entry_safe(exp_fhandler, - next_list_entry, - &exp_fn_list, - link) { - if ((exp_fhandler->func_init != NULL) && - (exp_fhandler->inserted == false)) { - if (exp_fhandler->func_init(rmi4_data) < 0) { - list_del(&exp_fhandler->link); - kfree(exp_fhandler); - } else { - exp_fhandler->inserted = true; - } - } else if ((exp_fhandler->func_init == NULL) && - (exp_fhandler->inserted == true)) { - exp_fhandler->func_remove(rmi4_data); - list_del(&exp_fhandler->link); - kfree(exp_fhandler); - } - } - } - mutex_unlock(&exp_fn_list_mutex); - - return; -} - -/** -* synaptics_rmi4_new_function() -* -* Called by other expansion Function modules in their module init and -* module exit functions. -* -* This function is used by other expansion Function modules such as -* rmi_dev to register themselves with the driver by providing their -* initialization and removal callback function pointers so that they -* can be inserted or removed dynamically at module init and exit times, -* respectively. -*/ -void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert, - int (*func_init)(struct synaptics_rmi4_data *rmi4_data), - void (*func_remove)(struct synaptics_rmi4_data *rmi4_data), - void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask)) -{ - struct synaptics_rmi4_exp_fn *exp_fhandler; - - if (!exp_fn_inited) { - mutex_init(&exp_fn_list_mutex); - INIT_LIST_HEAD(&exp_fn_list); - exp_fn_inited = 1; - } - - mutex_lock(&exp_fn_list_mutex); - if (insert) { - exp_fhandler = kzalloc(sizeof(*exp_fhandler), GFP_KERNEL); - if (!exp_fhandler) { - pr_err("%s: Failed to alloc mem for expansion function\n", - __func__); - goto exit; - } - exp_fhandler->fn_type = fn_type; - exp_fhandler->func_init = func_init; - exp_fhandler->func_attn = func_attn; - exp_fhandler->func_remove = func_remove; - exp_fhandler->inserted = false; - list_add_tail(&exp_fhandler->link, &exp_fn_list); - } else { - if (!list_empty(&exp_fn_list)) { - list_for_each_entry(exp_fhandler, &exp_fn_list, link) { - if (exp_fhandler->func_init == func_init) { - exp_fhandler->inserted = false; - exp_fhandler->func_init = NULL; - exp_fhandler->func_attn = NULL; - goto exit; - } - } - } - } - -exit: - mutex_unlock(&exp_fn_list_mutex); - - return; -} -EXPORT_SYMBOL(synaptics_rmi4_new_function); - - -static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA) -{ - return (regulator_count_voltages(reg) > 0) ? - regulator_set_optimum_mode(reg, load_uA) : 0; -} - -static int synaptics_rmi4_regulator_configure(struct synaptics_rmi4_data - *rmi4_data, bool on) -{ - int retval; - - if (on == false) - goto hw_shutdown; - - rmi4_data->vdd = regulator_get(&rmi4_data->i2c_client->dev, - "vdd"); - if (IS_ERR(rmi4_data->vdd)) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to get vdd regulator\n", - __func__); - return PTR_ERR(rmi4_data->vdd); - } - - if (regulator_count_voltages(rmi4_data->vdd) > 0) { - retval = regulator_set_voltage(rmi4_data->vdd, - RMI4_VTG_MIN_UV, RMI4_VTG_MAX_UV); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "regulator set_vtg failed retval =%d\n", - retval); - goto err_set_vtg_vdd; - } - } - - if (rmi4_data->board->i2c_pull_up) { - rmi4_data->vcc_i2c = regulator_get(&rmi4_data->i2c_client->dev, - "vcc_i2c"); - if (IS_ERR(rmi4_data->vcc_i2c)) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to get i2c regulator\n", - __func__); - retval = PTR_ERR(rmi4_data->vcc_i2c); - goto err_get_vtg_i2c; - } - - if (regulator_count_voltages(rmi4_data->vcc_i2c) > 0) { - retval = regulator_set_voltage(rmi4_data->vcc_i2c, - RMI4_I2C_VTG_MIN_UV, RMI4_I2C_VTG_MAX_UV); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "reg set i2c vtg failed retval =%d\n", - retval); - goto err_set_vtg_i2c; - } - } - } - return 0; - -err_set_vtg_i2c: - if (rmi4_data->board->i2c_pull_up) - regulator_put(rmi4_data->vcc_i2c); -err_get_vtg_i2c: - if (regulator_count_voltages(rmi4_data->vdd) > 0) - regulator_set_voltage(rmi4_data->vdd, 0, - RMI4_VTG_MAX_UV); -err_set_vtg_vdd: - regulator_put(rmi4_data->vdd); - return retval; - -hw_shutdown: - if (regulator_count_voltages(rmi4_data->vdd) > 0) - regulator_set_voltage(rmi4_data->vdd, 0, - RMI4_VTG_MAX_UV); - regulator_put(rmi4_data->vdd); - if (rmi4_data->board->i2c_pull_up) { - if (regulator_count_voltages(rmi4_data->vcc_i2c) > 0) - regulator_set_voltage(rmi4_data->vcc_i2c, 0, - RMI4_I2C_VTG_MAX_UV); - regulator_put(rmi4_data->vcc_i2c); - } - return 0; -}; - -static int synaptics_rmi4_power_on(struct synaptics_rmi4_data *rmi4_data, - bool on) { - int retval; - - if (on == false) - goto power_off; - - retval = reg_set_optimum_mode_check(rmi4_data->vdd, - RMI4_ACTIVE_LOAD_UA); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vdd set_opt failed rc=%d\n", - retval); - return retval; - } - - retval = regulator_enable(rmi4_data->vdd); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vdd enable failed rc=%d\n", - retval); - goto error_reg_en_vdd; - } - - if (rmi4_data->board->i2c_pull_up) { - retval = reg_set_optimum_mode_check(rmi4_data->vcc_i2c, - RMI4_I2C_LOAD_UA); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vcc_i2c set_opt failed rc=%d\n", - retval); - goto error_reg_opt_i2c; - } - - retval = regulator_enable(rmi4_data->vcc_i2c); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vcc_i2c enable failed rc=%d\n", - retval); - goto error_reg_en_vcc_i2c; - } - } - return 0; - -error_reg_en_vcc_i2c: - if (rmi4_data->board->i2c_pull_up) - reg_set_optimum_mode_check(rmi4_data->vcc_i2c, 0); -error_reg_opt_i2c: - regulator_disable(rmi4_data->vdd); -error_reg_en_vdd: - reg_set_optimum_mode_check(rmi4_data->vdd, 0); - return retval; - -power_off: - reg_set_optimum_mode_check(rmi4_data->vdd, 0); - regulator_disable(rmi4_data->vdd); - if (rmi4_data->board->i2c_pull_up) { - reg_set_optimum_mode_check(rmi4_data->vcc_i2c, 0); - regulator_disable(rmi4_data->vcc_i2c); - } - return 0; -} - -static int synaptics_rmi4_pinctrl_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - - /* Get pinctrl if target uses pinctrl */ - rmi4_data->ts_pinctrl = devm_pinctrl_get(&(rmi4_data->i2c_client->dev)); - if (IS_ERR_OR_NULL(rmi4_data->ts_pinctrl)) { - dev_dbg(&rmi4_data->i2c_client->dev, - "Target does not use pinctrl\n"); - retval = PTR_ERR(rmi4_data->ts_pinctrl); - rmi4_data->ts_pinctrl = NULL; - return retval; - } - - rmi4_data->gpio_state_active - = pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_active"); - if (IS_ERR_OR_NULL(rmi4_data->gpio_state_active)) { - dev_dbg(&rmi4_data->i2c_client->dev, - "Can not get ts default pinstate\n"); - retval = PTR_ERR(rmi4_data->gpio_state_active); - rmi4_data->ts_pinctrl = NULL; - return retval; - } - - rmi4_data->gpio_state_suspend - = pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_suspend"); - if (IS_ERR_OR_NULL(rmi4_data->gpio_state_suspend)) { - dev_dbg(&rmi4_data->i2c_client->dev, - "Can not get ts sleep pinstate\n"); - retval = PTR_ERR(rmi4_data->gpio_state_suspend); - rmi4_data->ts_pinctrl = NULL; - return retval; - } - - return 0; -} - -static int synpatics_rmi4_pinctrl_select(struct synaptics_rmi4_data *rmi4_data, - bool on) -{ - struct pinctrl_state *pins_state; - int ret; - - pins_state = on ? rmi4_data->gpio_state_active - : rmi4_data->gpio_state_suspend; - if (!IS_ERR_OR_NULL(pins_state)) { - ret = pinctrl_select_state(rmi4_data->ts_pinctrl, pins_state); - if (ret) { - dev_err(&rmi4_data->i2c_client->dev, - "can not set %s pins\n", - on ? "pmx_ts_active" : "pmx_ts_suspend"); - return ret; - } - } else - dev_err(&rmi4_data->i2c_client->dev, - "not a valid '%s' pinstate\n", - on ? "pmx_ts_active" : "pmx_ts_suspend"); - - return 0; -} - -static int synaptics_rmi4_gpio_configure(struct synaptics_rmi4_data *rmi4_data, - bool on) -{ - int retval = 0; - - if (on) { - if (gpio_is_valid(rmi4_data->board->irq_gpio)) { - /* configure touchscreen irq gpio */ - retval = gpio_request(rmi4_data->board->irq_gpio, - "rmi4_irq_gpio"); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "unable to request gpio [%d]\n", - rmi4_data->board->irq_gpio); - goto err_irq_gpio_req; - } - retval = gpio_direction_input(rmi4_data->board->\ - irq_gpio); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "unable to set direction for gpio " \ - "[%d]\n", rmi4_data->board->irq_gpio); - goto err_irq_gpio_dir; - } - } else { - dev_err(&rmi4_data->i2c_client->dev, - "irq gpio not provided\n"); - goto err_irq_gpio_req; - } - - if (gpio_is_valid(rmi4_data->board->reset_gpio)) { - /* configure touchscreen reset out gpio */ - retval = gpio_request(rmi4_data->board->reset_gpio, - "rmi4_reset_gpio"); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "unable to request gpio [%d]\n", - rmi4_data->board->reset_gpio); - goto err_irq_gpio_dir; - } - - retval = gpio_direction_output(rmi4_data->board->\ - reset_gpio, 1); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "unable to set direction for gpio " \ - "[%d]\n", rmi4_data->board->reset_gpio); - goto err_reset_gpio_dir; - } - - gpio_set_value(rmi4_data->board->reset_gpio, 1); - msleep(rmi4_data->board->reset_delay); - } else - synaptics_rmi4_reset_command(rmi4_data); - - return 0; - } else { - if (rmi4_data->board->disable_gpios) { - if (gpio_is_valid(rmi4_data->board->irq_gpio)) - gpio_free(rmi4_data->board->irq_gpio); - if (gpio_is_valid(rmi4_data->board->reset_gpio)) { - /* - * This is intended to save leakage current - * only. Even if the call(gpio_direction_input) - * fails, only leakage current will be more but - * functionality will not be affected. - */ - retval = gpio_direction_input(rmi4_data-> - board->reset_gpio); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "unable to set direction for gpio " - "[%d]\n", rmi4_data->board->irq_gpio); - } - gpio_free(rmi4_data->board->reset_gpio); - } - } - - return 0; - } - -err_reset_gpio_dir: - if (gpio_is_valid(rmi4_data->board->reset_gpio)) - gpio_free(rmi4_data->board->reset_gpio); -err_irq_gpio_dir: - if (gpio_is_valid(rmi4_data->board->irq_gpio)) - gpio_free(rmi4_data->board->irq_gpio); -err_irq_gpio_req: - return retval; -} - - /** - * synaptics_rmi4_probe() - * - * Called by the kernel when an association with an I2C device of the - * same name is made (after doing i2c_add_driver). - * - * This funtion allocates and initializes the resources for the driver - * as an input driver, turns on the power to the sensor, queries the - * sensor for its supported Functions and characteristics, registers - * the driver to the input subsystem, sets up the interrupt, handles - * the registration of the early_suspend and late_resume functions, - * and creates a work queue for detection of other expansion Function - * modules. - */ -static int synaptics_rmi4_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - int retval = 0; - unsigned char ii; - unsigned char attr_count; - struct synaptics_rmi4_f1a_handle *f1a; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_fn *next_fhandler; - struct synaptics_rmi4_data *rmi4_data; - struct synaptics_rmi4_device_info *rmi; - struct synaptics_rmi4_platform_data *platform_data = - client->dev.platform_data; - struct dentry *temp; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, - "%s: SMBus byte data not supported\n", - __func__); - return -EIO; - } - - if (client->dev.of_node) { - platform_data = devm_kzalloc(&client->dev, - sizeof(*platform_data), - GFP_KERNEL); - if (!platform_data) { - dev_err(&client->dev, "Failed to allocate memory\n"); - return -ENOMEM; - } - - retval = synaptics_rmi4_parse_dt(&client->dev, platform_data); - if (retval) - return retval; - } else { - platform_data = client->dev.platform_data; - } - - if (!platform_data) { - dev_err(&client->dev, - "%s: No platform data found\n", - __func__); - return -EINVAL; - } - - rmi4_data = kzalloc(sizeof(*rmi4_data) * 2, GFP_KERNEL); - if (!rmi4_data) { - dev_err(&client->dev, - "%s: Failed to alloc mem for rmi4_data\n", - __func__); - return -ENOMEM; - } - - rmi = &(rmi4_data->rmi4_mod_info); - - rmi4_data->input_dev = input_allocate_device(); - if (rmi4_data->input_dev == NULL) { - dev_err(&client->dev, - "%s: Failed to allocate input device\n", - __func__); - retval = -ENOMEM; - goto err_input_device; - } - - rmi4_data->i2c_client = client; - rmi4_data->current_page = MASK_8BIT; - rmi4_data->board = platform_data; - rmi4_data->touch_stopped = false; - rmi4_data->sensor_sleep = false; - rmi4_data->irq_enabled = false; - rmi4_data->fw_updating = false; - rmi4_data->suspended = false; - - rmi4_data->stay_awake = rmi4_data->board->is_wake; - rmi4_data->i2c_read = synaptics_rmi4_i2c_read; - rmi4_data->i2c_write = synaptics_rmi4_i2c_write; - rmi4_data->irq_enable = synaptics_rmi4_irq_enable; - rmi4_data->reset_device = synaptics_rmi4_reset_device; - - rmi4_data->flip_x = rmi4_data->board->x_flip; - rmi4_data->flip_y = rmi4_data->board->y_flip; - - if (rmi4_data->board->fw_image_name) - snprintf(rmi4_data->fw_image_name, NAME_BUFFER_SIZE, "%s", - rmi4_data->board->fw_image_name); - - rmi4_data->input_dev->name = DRIVER_NAME; - rmi4_data->input_dev->phys = INPUT_PHYS_NAME; - rmi4_data->input_dev->id.bustype = BUS_I2C; - rmi4_data->input_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; - rmi4_data->input_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; - rmi4_data->input_dev->dev.parent = &client->dev; - input_set_drvdata(rmi4_data->input_dev, rmi4_data); - - set_bit(EV_SYN, rmi4_data->input_dev->evbit); - set_bit(EV_KEY, rmi4_data->input_dev->evbit); - set_bit(EV_ABS, rmi4_data->input_dev->evbit); - set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit); - set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit); - -#ifdef INPUT_PROP_DIRECT - set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit); -#endif - - retval = synaptics_rmi4_regulator_configure(rmi4_data, true); - if (retval < 0) { - dev_err(&client->dev, "Failed to configure regulators\n"); - goto err_reg_configure; - } - - retval = synaptics_rmi4_power_on(rmi4_data, true); - if (retval < 0) { - dev_err(&client->dev, "Failed to power on\n"); - goto err_power_device; - } - - retval = synaptics_rmi4_pinctrl_init(rmi4_data); - if (!retval && rmi4_data->ts_pinctrl) { - retval = synpatics_rmi4_pinctrl_select(rmi4_data, true); - if (retval < 0) - goto err_gpio_config; - } - - retval = synaptics_rmi4_gpio_configure(rmi4_data, true); - if (retval < 0) { - dev_err(&client->dev, "Failed to configure gpios\n"); - goto pinctrl_sleep; - } - - init_waitqueue_head(&rmi4_data->wait); - mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex)); - - INIT_LIST_HEAD(&rmi->support_fn_list); - mutex_init(&rmi->support_fn_list_mutex); - - retval = synaptics_rmi4_query_device(rmi4_data); - if (retval < 0) { - dev_err(&client->dev, - "%s: Failed to query device\n", - __func__); - goto err_free_gpios; - } - - if (platform_data->detect_device) { - retval = synaptics_rmi4_parse_dt_children(&client->dev, - platform_data, rmi4_data); - if (retval < 0) - dev_err(&client->dev, - "%s: Failed to parse device tree property\n", - __func__); - } - - if (rmi4_data->board->disp_maxx) - rmi4_data->disp_maxx = rmi4_data->board->disp_maxx; - else - rmi4_data->disp_maxx = rmi4_data->sensor_max_x; - - if (rmi4_data->board->disp_maxy) - rmi4_data->disp_maxy = rmi4_data->board->disp_maxy; - else - rmi4_data->disp_maxy = rmi4_data->sensor_max_y; - - if (rmi4_data->board->disp_minx) - rmi4_data->disp_minx = rmi4_data->board->disp_minx; - else - rmi4_data->disp_minx = 0; - - if (rmi4_data->board->disp_miny) - rmi4_data->disp_miny = rmi4_data->board->disp_miny; - else - rmi4_data->disp_miny = 0; - - input_set_abs_params(rmi4_data->input_dev, - ABS_MT_POSITION_X, rmi4_data->disp_minx, - rmi4_data->disp_maxx, 0, 0); - input_set_abs_params(rmi4_data->input_dev, - ABS_MT_POSITION_Y, rmi4_data->disp_miny, - rmi4_data->disp_maxy, 0, 0); - input_set_abs_params(rmi4_data->input_dev, - ABS_PRESSURE, 0, 255, 0, 0); -#ifdef REPORT_2D_W - input_set_abs_params(rmi4_data->input_dev, - ABS_MT_TOUCH_MAJOR, 0, - rmi4_data->max_touch_width, 0, 0); - input_set_abs_params(rmi4_data->input_dev, - ABS_MT_TOUCH_MINOR, 0, - rmi4_data->max_touch_width, 0, 0); -#endif - -#ifdef TYPE_B_PROTOCOL - input_mt_init_slots(rmi4_data->input_dev, - rmi4_data->num_of_fingers, 0); -#endif - - i2c_set_clientdata(client, rmi4_data); - - f1a = NULL; - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) - f1a = fhandler->data; - } - } - mutex_unlock(&rmi->support_fn_list_mutex); - - if (f1a) { - for (ii = 0; ii < f1a->valid_button_count; ii++) { - set_bit(f1a->button_map[ii], - rmi4_data->input_dev->keybit); - input_set_capability(rmi4_data->input_dev, - EV_KEY, f1a->button_map[ii]); - } - } - - retval = input_register_device(rmi4_data->input_dev); - if (retval) { - dev_err(&client->dev, - "%s: Failed to register input device\n", - __func__); - goto err_register_input; - } - - configure_sleep(rmi4_data); - - if (!exp_fn_inited) { - mutex_init(&exp_fn_list_mutex); - INIT_LIST_HEAD(&exp_fn_list); - exp_fn_inited = 1; - } - - rmi4_data->det_workqueue = - create_singlethread_workqueue("rmi_det_workqueue"); - INIT_DELAYED_WORK(&rmi4_data->det_work, - synaptics_rmi4_detection_work); - queue_delayed_work(rmi4_data->det_workqueue, - &rmi4_data->det_work, - msecs_to_jiffies(EXP_FN_DET_INTERVAL)); - - rmi4_data->irq = gpio_to_irq(platform_data->irq_gpio); - - retval = request_threaded_irq(rmi4_data->irq, NULL, - synaptics_rmi4_irq, platform_data->irq_flags, - DRIVER_NAME, rmi4_data); - rmi4_data->irq_enabled = true; - - if (retval < 0) { - dev_err(&client->dev, - "%s: Failed to create irq thread\n", - __func__); - goto err_enable_irq; - } - - rmi4_data->dir = debugfs_create_dir(DEBUGFS_DIR_NAME, NULL); - if (rmi4_data->dir == NULL || IS_ERR(rmi4_data->dir)) { - dev_err(&client->dev, - "%s: Failed to create debugfs directory, rc = %ld\n", - __func__, PTR_ERR(rmi4_data->dir)); - retval = PTR_ERR(rmi4_data->dir); - goto err_create_debugfs_dir; - } - - temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, rmi4_data->dir, - rmi4_data, &debug_suspend_fops); - if (temp == NULL || IS_ERR(temp)) { - dev_err(&client->dev, - "%s: Failed to create suspend debugfs file, rc = %ld\n", - __func__, PTR_ERR(temp)); - retval = PTR_ERR(temp); - goto err_create_debugfs_file; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(&client->dev.kobj, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(&client->dev, - "%s: Failed to create sysfs attributes\n", - __func__); - goto err_sysfs; - } - } - - synaptics_rmi4_sensor_wake(rmi4_data); - - retval = synaptics_rmi4_irq_enable(rmi4_data, true); - if (retval < 0) { - dev_err(&client->dev, - "%s: Failed to enable attention interrupt\n", - __func__); - goto err_sysfs; - } - - synaptics_secure_touch_init(rmi4_data); - synaptics_secure_touch_stop(rmi4_data, 1); - - retval = synaptics_rmi4_check_configuration(rmi4_data); - if (retval < 0) { - dev_err(&client->dev, "Failed to check configuration\n"); - return retval; - } - - device_init_wakeup(&client->dev, rmi4_data->stay_awake); - if (rmi4_data->stay_awake) - input_set_capability(rmi4_data->input_dev, EV_KEY, - KEY_TOUCHPAD_TOGGLE); - - - return retval; - -err_sysfs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } -err_create_debugfs_file: - debugfs_remove_recursive(rmi4_data->dir); -err_create_debugfs_dir: - free_irq(rmi4_data->irq, rmi4_data); -err_enable_irq: - cancel_delayed_work_sync(&rmi4_data->det_work); - flush_workqueue(rmi4_data->det_workqueue); - destroy_workqueue(rmi4_data->det_workqueue); - input_unregister_device(rmi4_data->input_dev); - -err_register_input: - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry_safe(fhandler, next_fhandler, - &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) - synaptics_rmi4_f1a_kfree(fhandler); - else { - kfree(fhandler->data); - kfree(fhandler->extra); - } - kfree(fhandler); - } - } - mutex_unlock(&rmi->support_fn_list_mutex); -err_free_gpios: - if (gpio_is_valid(rmi4_data->board->reset_gpio)) - gpio_free(rmi4_data->board->reset_gpio); - if (gpio_is_valid(rmi4_data->board->irq_gpio)) - gpio_free(rmi4_data->board->irq_gpio); -pinctrl_sleep: - if (rmi4_data->ts_pinctrl) { - retval = synpatics_rmi4_pinctrl_select(rmi4_data, false); - if (retval < 0) - pr_err("Cannot get idle pinctrl state\n"); - } -err_gpio_config: - synaptics_rmi4_power_on(rmi4_data, false); -err_power_device: - synaptics_rmi4_regulator_configure(rmi4_data, false); -err_reg_configure: - input_free_device(rmi4_data->input_dev); - rmi4_data->input_dev = NULL; -err_input_device: - kfree(rmi4_data); - - return retval; -} - - /** - * synaptics_rmi4_remove() - * - * Called by the kernel when the association with an I2C device of the - * same name is broken (when the driver is unloaded). - * - * This funtion terminates the work queue, stops sensor data acquisition, - * frees the interrupt, unregisters the driver from the input subsystem, - * turns off the power to the sensor, and frees other allocated resources. - */ -static int synaptics_rmi4_remove(struct i2c_client *client) -{ - unsigned char attr_count; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_fn *next_fhandler; - struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client); - struct synaptics_rmi4_device_info *rmi; - int retval; - - rmi = &(rmi4_data->rmi4_mod_info); - - debugfs_remove_recursive(rmi4_data->dir); - cancel_delayed_work_sync(&rmi4_data->det_work); - flush_workqueue(rmi4_data->det_workqueue); - destroy_workqueue(rmi4_data->det_workqueue); - - rmi4_data->touch_stopped = true; - wake_up(&rmi4_data->wait); - - free_irq(rmi4_data->irq, rmi4_data); - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - input_unregister_device(rmi4_data->input_dev); - - mutex_lock(&rmi->support_fn_list_mutex); - if (!list_empty(&rmi->support_fn_list)) { - list_for_each_entry_safe(fhandler, next_fhandler, - &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F1A) - synaptics_rmi4_f1a_kfree(fhandler); - else { - kfree(fhandler->data); - kfree(fhandler->extra); - } - kfree(fhandler); - } - } - mutex_unlock(&rmi->support_fn_list_mutex); - - if (gpio_is_valid(rmi4_data->board->reset_gpio)) - gpio_free(rmi4_data->board->reset_gpio); - if (gpio_is_valid(rmi4_data->board->irq_gpio)) - gpio_free(rmi4_data->board->irq_gpio); - - if (rmi4_data->ts_pinctrl) { - retval = synpatics_rmi4_pinctrl_select(rmi4_data, false); - if (retval < 0) - pr_err("Cannot get idle pinctrl state\n"); - } - - synaptics_rmi4_power_on(rmi4_data, false); - synaptics_rmi4_regulator_configure(rmi4_data, false); - - kfree(rmi4_data); - - return 0; -} - - /** - * synaptics_rmi4_sensor_sleep() - * - * Called by synaptics_rmi4_early_suspend() and synaptics_rmi4_suspend(). - * - * This function stops finger data acquisition and puts the sensor to sleep. - */ -static void synaptics_rmi4_sensor_sleep(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - struct synaptics_rmi4_f01_device_control_0 device_ctrl; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - device_ctrl.data, - sizeof(device_ctrl.data)); - if (retval < 0) { - dev_err(&(rmi4_data->input_dev->dev), - "%s: Failed to enter sleep mode\n", - __func__); - rmi4_data->sensor_sleep = false; - return; - } - - device_ctrl.sleep_mode = SENSOR_SLEEP; - device_ctrl.nosleep = NO_SLEEP_OFF; - - retval = synaptics_rmi4_i2c_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - device_ctrl.data, - sizeof(device_ctrl.data)); - if (retval < 0) { - dev_err(&(rmi4_data->input_dev->dev), - "%s: Failed to enter sleep mode\n", - __func__); - rmi4_data->sensor_sleep = false; - return; - } else { - rmi4_data->sensor_sleep = true; - } - - return; -} - - /** - * synaptics_rmi4_sensor_wake() - * - * Called by synaptics_rmi4_resume() and synaptics_rmi4_late_resume(). - * - * This function wakes the sensor from sleep. - */ -static void synaptics_rmi4_sensor_wake(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - struct synaptics_rmi4_f01_device_control_0 device_ctrl; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - device_ctrl.data, - sizeof(device_ctrl.data)); - if (retval < 0) { - dev_err(&(rmi4_data->input_dev->dev), - "%s: Failed to wake from sleep mode\n", - __func__); - rmi4_data->sensor_sleep = true; - return; - } - - if (device_ctrl.nosleep == NO_SLEEP_OFF && - device_ctrl.sleep_mode == NORMAL_OPERATION) { - rmi4_data->sensor_sleep = false; - return; - } - - device_ctrl.sleep_mode = NORMAL_OPERATION; - device_ctrl.nosleep = NO_SLEEP_OFF; - - retval = synaptics_rmi4_i2c_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - device_ctrl.data, - sizeof(device_ctrl.data)); - if (retval < 0) { - dev_err(&(rmi4_data->input_dev->dev), - "%s: Failed to wake from sleep mode\n", - __func__); - rmi4_data->sensor_sleep = true; - return; - } else { - rmi4_data->sensor_sleep = false; - } - - return; -} - -#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 synaptics_rmi4_data *rmi4_data = - container_of(self, struct synaptics_rmi4_data, fb_notif); - - if (evdata && evdata->data && rmi4_data && rmi4_data->i2c_client) { - if (event == FB_EARLY_EVENT_BLANK) - synaptics_secure_touch_stop(rmi4_data, 0); - else if (event == FB_EVENT_BLANK) { - blank = evdata->data; - if (*blank == FB_BLANK_UNBLANK) - synaptics_rmi4_resume( - &(rmi4_data->input_dev->dev)); - else if (*blank == FB_BLANK_POWERDOWN) - synaptics_rmi4_suspend( - &(rmi4_data->input_dev->dev)); - } - } - - return 0; -} -#elif defined(CONFIG_HAS_EARLYSUSPEND) - /** - * synaptics_rmi4_early_suspend() - * - * Called by the kernel during the early suspend phase when the system - * enters suspend. - * - * This function calls synaptics_rmi4_sensor_sleep() to stop finger - * data acquisition and put the sensor to sleep. - */ -static void synaptics_rmi4_early_suspend(struct early_suspend *h) -{ - struct synaptics_rmi4_data *rmi4_data = - container_of(h, struct synaptics_rmi4_data, - early_suspend); - - if (rmi4_data->stay_awake) - rmi4_data->staying_awake = true; - else - rmi4_data->staying_awake = false; - - synaptics_secure_touch_stop(rmi4_data, 0); - - rmi4_data->touch_stopped = true; - wake_up(&rmi4_data->wait); - synaptics_rmi4_irq_enable(rmi4_data, false); - synaptics_rmi4_sensor_sleep(rmi4_data); - - if (rmi4_data->full_pm_cycle) - synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev)); - - return; -} - - /** - * synaptics_rmi4_late_resume() - * - * Called by the kernel during the late resume phase when the system - * wakes up from suspend. - * - * This function goes through the sensor wake process if the system wakes - * up from early suspend (without going into suspend). - */ -static void synaptics_rmi4_late_resume(struct early_suspend *h) -{ - struct synaptics_rmi4_data *rmi4_data = - container_of(h, struct synaptics_rmi4_data, - early_suspend); - - if (rmi4_data->staying_awake) - return; - - synaptics_secure_touch_stop(rmi4_data, 0); - - if (rmi4_data->full_pm_cycle) - synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); - - if (rmi4_data->sensor_sleep == true) { - synaptics_rmi4_sensor_wake(rmi4_data); - rmi4_data->touch_stopped = false; - synaptics_rmi4_irq_enable(rmi4_data, true); - } - - return; -} -#endif - -static int synaptics_rmi4_regulator_lpm(struct synaptics_rmi4_data *rmi4_data, - bool on) -{ - int retval; - int load_ua; - - if (on == false) - goto regulator_hpm; - - if (rmi4_data->board->i2c_pull_up) { - load_ua = rmi4_data->board->power_down_enable ? - 0 : RMI4_I2C_LPM_LOAD_UA; - retval = reg_set_optimum_mode_check(rmi4_data->vcc_i2c, - load_ua); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vcc_i2c set_opt failed " \ - "rc=%d\n", retval); - goto fail_regulator_lpm; - } - - if (rmi4_data->board->power_down_enable) { - retval = regulator_disable(rmi4_data->vcc_i2c); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vcc_i2c disable failed " \ - "rc=%d\n", retval); - goto fail_regulator_lpm; - } - } - } - - load_ua = rmi4_data->board->power_down_enable ? 0 : RMI4_LPM_LOAD_UA; - retval = reg_set_optimum_mode_check(rmi4_data->vdd, load_ua); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vdd_ana set_opt failed rc=%d\n", - retval); - goto fail_regulator_lpm; - } - - if (rmi4_data->board->power_down_enable) { - retval = regulator_disable(rmi4_data->vdd); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vdd disable failed rc=%d\n", - retval); - goto fail_regulator_lpm; - } - } - - return 0; - -regulator_hpm: - - retval = reg_set_optimum_mode_check(rmi4_data->vdd, - RMI4_ACTIVE_LOAD_UA); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vcc_ana set_opt failed rc=%d\n", - retval); - goto fail_regulator_hpm; - } - - if (rmi4_data->board->power_down_enable) { - retval = regulator_enable(rmi4_data->vdd); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vdd enable failed rc=%d\n", - retval); - goto fail_regulator_hpm; - } - } - - if (rmi4_data->board->i2c_pull_up) { - retval = reg_set_optimum_mode_check(rmi4_data->vcc_i2c, - RMI4_I2C_LOAD_UA); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vcc_i2c set_opt failed rc=%d\n", - retval); - goto fail_regulator_hpm; - } - - if (rmi4_data->board->power_down_enable) { - retval = regulator_enable(rmi4_data->vcc_i2c); - if (retval) { - dev_err(&rmi4_data->i2c_client->dev, - "Regulator vcc_i2c enable failed " \ - "rc=%d\n", retval); - goto fail_regulator_hpm; - } - } - } - - return 0; - -fail_regulator_lpm: - reg_set_optimum_mode_check(rmi4_data->vdd, RMI4_ACTIVE_LOAD_UA); - if (rmi4_data->board->i2c_pull_up) - reg_set_optimum_mode_check(rmi4_data->vcc_i2c, - RMI4_I2C_LOAD_UA); - - return retval; - -fail_regulator_hpm: - load_ua = rmi4_data->board->power_down_enable ? 0 : RMI4_LPM_LOAD_UA; - reg_set_optimum_mode_check(rmi4_data->vdd, load_ua); - if (rmi4_data->board->i2c_pull_up) { - load_ua = rmi4_data->board->power_down_enable ? - 0 : RMI4_I2C_LPM_LOAD_UA; - reg_set_optimum_mode_check(rmi4_data->vcc_i2c, load_ua); - } - return retval; -} - -static int synaptics_rmi4_check_configuration(struct synaptics_rmi4_data - *rmi4_data) -{ - int retval; - struct synaptics_rmi4_f01_device_control_0 device_control; - struct synaptics_rmi4_f01_device_status device_status; - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_data_base_addr, - device_status.data, - sizeof(device_status.data)); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "Failed to read device status, rc=%d\n", retval); - return retval; - } - - if (device_status.unconfigured) { - retval = synaptics_rmi4_query_device(rmi4_data); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "Failed to query device, rc=%d\n", retval); - return retval; - } - - retval = synaptics_rmi4_i2c_read(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - device_control.data, - sizeof(device_control.data)); - if (retval < 0) - return retval; - - device_control.configured = DEVICE_CONFIGURED; - - retval = synaptics_rmi4_i2c_write(rmi4_data, - rmi4_data->f01_ctrl_base_addr, - device_control.data, - sizeof(device_control.data)); - if (retval < 0) - return retval; - } - - return 0; -} - - /** - * synaptics_rmi4_suspend() - * - * Called by the kernel during the suspend phase when the system - * enters suspend. - * - * This function stops finger data acquisition and puts the sensor to - * sleep (if not already done so during the early suspend phase), - * disables the interrupt, and turns off the power to the sensor. - */ -#ifdef CONFIG_PM -static int synaptics_rmi4_suspend(struct device *dev) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - int retval; - - if (rmi4_data->stay_awake) { - wake_report = 1; - rmi4_data->staying_awake = true; - enable_irq_wake(rmi4_data->irq); - return 0; - } else - rmi4_data->staying_awake = false; - - if (rmi4_data->suspended) { - dev_info(dev, "Already in suspend state\n"); - return 0; - } - - synaptics_secure_touch_stop(rmi4_data, 1); - - if (!rmi4_data->fw_updating) { - if (!rmi4_data->sensor_sleep) { - rmi4_data->touch_stopped = true; - wake_up(&rmi4_data->wait); - synaptics_rmi4_irq_enable(rmi4_data, false); - synaptics_rmi4_sensor_sleep(rmi4_data); - } - - synaptics_rmi4_release_all(rmi4_data); - - retval = synaptics_rmi4_regulator_lpm(rmi4_data, true); - if (retval < 0) { - dev_err(dev, "failed to enter low power mode\n"); - goto err_lpm_regulator; - } - } else { - dev_err(dev, - "Firmware updating, cannot go into suspend mode\n"); - return 0; - } - - if (rmi4_data->board->disable_gpios) { - if (rmi4_data->ts_pinctrl) { - retval = synpatics_rmi4_pinctrl_select(rmi4_data, - false); - if (retval < 0) - dev_err(dev, "Cannot get idle pinctrl state\n"); - } - - retval = synaptics_rmi4_gpio_configure(rmi4_data, false); - if (retval < 0) { - dev_err(dev, "failed to put gpios in suspend state\n"); - goto err_gpio_configure; - } - } - rmi4_data->suspended = true; - - return 0; - -err_gpio_configure: - if (rmi4_data->ts_pinctrl) { - retval = synpatics_rmi4_pinctrl_select(rmi4_data, true); - if (retval < 0) - dev_err(dev, "Cannot get default pinctrl state\n"); - } - synaptics_rmi4_regulator_lpm(rmi4_data, false); - -err_lpm_regulator: - if (rmi4_data->sensor_sleep) { - synaptics_rmi4_sensor_wake(rmi4_data); - synaptics_rmi4_irq_enable(rmi4_data, true); - rmi4_data->touch_stopped = false; - } - - return retval; -} - - /** - * synaptics_rmi4_resume() - * - * Called by the kernel during the resume phase when the system - * wakes up from suspend. - * - * This function turns on the power to the sensor, wakes the sensor - * from sleep, enables the interrupt, and starts finger data - * acquisition. - */ -static int synaptics_rmi4_resume(struct device *dev) -{ - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - int retval; - - if (rmi4_data->staying_awake) { - wake_report = 0; - disable_irq_wake(rmi4_data->irq); - return 0; - } - - if (!rmi4_data->suspended) { - dev_info(dev, "Already in awake state\n"); - return 0; - } - - synaptics_secure_touch_stop(rmi4_data, 1); - - retval = synaptics_rmi4_regulator_lpm(rmi4_data, false); - if (retval < 0) { - dev_err(dev, "Failed to enter active power mode\n"); - return retval; - } - - if (rmi4_data->board->disable_gpios) { - if (rmi4_data->ts_pinctrl) { - retval = synpatics_rmi4_pinctrl_select(rmi4_data, true); - if (retval < 0) - dev_err(dev, "Cannot get default pinctrl state\n"); - } - - retval = synaptics_rmi4_gpio_configure(rmi4_data, true); - if (retval < 0) { - dev_err(dev, "Failed to put gpios in active state\n"); - goto err_gpio_configure; - } - } - - synaptics_rmi4_sensor_wake(rmi4_data); - rmi4_data->touch_stopped = false; - synaptics_rmi4_irq_enable(rmi4_data, true); - - retval = synaptics_rmi4_check_configuration(rmi4_data); - if (retval < 0) { - dev_err(dev, "Failed to check configuration\n"); - goto err_check_configuration; - } - rmi4_data->suspended = false; - - return 0; - -err_check_configuration: - synaptics_rmi4_irq_enable(rmi4_data, false); - rmi4_data->touch_stopped = true; - synaptics_rmi4_sensor_sleep(rmi4_data); - - if (rmi4_data->board->disable_gpios) { - if (rmi4_data->ts_pinctrl) { - retval = synpatics_rmi4_pinctrl_select(rmi4_data, - false); - if (retval < 0) - dev_err(dev, "Cannot get idle pinctrl state\n"); - } - - synaptics_rmi4_gpio_configure(rmi4_data, false); - } - synaptics_rmi4_regulator_lpm(rmi4_data, true); - wake_up(&rmi4_data->wait); - - return retval; - -err_gpio_configure: - if (rmi4_data->ts_pinctrl) { - retval = synpatics_rmi4_pinctrl_select(rmi4_data, false); - if (retval < 0) - pr_err("Cannot get idle pinctrl state\n"); - } - synaptics_rmi4_regulator_lpm(rmi4_data, true); - wake_up(&rmi4_data->wait); - - return retval; -} - -static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = { - .suspend = synaptics_rmi4_suspend, - .resume = synaptics_rmi4_resume, -}; -#else -static int synaptics_rmi4_suspend(struct device *dev) -{ - return 0; -} - -static int synaptics_rmi4_resume(struct device *dev) -{ - return 0; -} -#endif - -static const struct i2c_device_id synaptics_rmi4_id_table[] = { - {DRIVER_NAME, 0}, - {}, -}; -MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table); - -#ifdef CONFIG_OF -static struct of_device_id rmi4_match_table[] = { - { .compatible = "synaptics,rmi4",}, - { }, -}; -#else -#define rmi4_match_table NULL -#endif - -static struct i2c_driver synaptics_rmi4_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = rmi4_match_table, -#ifdef CONFIG_PM - .pm = &synaptics_rmi4_dev_pm_ops, -#endif - }, - .probe = synaptics_rmi4_probe, - .remove = synaptics_rmi4_remove, - .id_table = synaptics_rmi4_id_table, -}; - - /** - * synaptics_rmi4_init() - * - * Called by the kernel during do_initcalls (if built-in) - * or when the driver is loaded (if a module). - * - * This function registers the driver to the I2C subsystem. - * - */ -static int __init synaptics_rmi4_init(void) -{ - return i2c_add_driver(&synaptics_rmi4_driver); -} - - /** - * synaptics_rmi4_exit() - * - * Called by the kernel when the driver is unloaded. - * - * This funtion unregisters the driver from the I2C subsystem. - * - */ -static void __exit synaptics_rmi4_exit(void) -{ - i2c_del_driver(&synaptics_rmi4_driver); -} - -module_init(synaptics_rmi4_init); -module_exit(synaptics_rmi4_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics RMI4 I2C Touch Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h deleted file mode 100644 index 67b416517de8..000000000000 --- a/drivers/input/touchscreen/synaptics_i2c_rmi4.h +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Synaptics RMI4 touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * Copyright (c) 2013-2014, 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. - */ - -#ifndef _SYNAPTICS_DSX_RMI4_H_ -#define _SYNAPTICS_DSX_RMI4_H_ - -#define SYNAPTICS_DS4 (1 << 0) -#define SYNAPTICS_DS5 (1 << 1) -#define SYNAPTICS_DSX_DRIVER_PRODUCT SYNAPTICS_DS4 -#define SYNAPTICS_DSX_DRIVER_VERSION 0x1005 - -#include <linux/version.h> - -#ifdef CONFIG_FB -#include <linux/notifier.h> -#include <linux/fb.h> -#elif defined CONFIG_HAS_EARLYSUSPEND -#include <linux/earlysuspend.h> -#endif -#include <linux/debugfs.h> -#if defined(CONFIG_SECURE_TOUCH) -#include <linux/completion.h> -#include <linux/atomic.h> -#endif - -#define PDT_PROPS (0x00EF) -#define PDT_START (0x00E9) -#define PDT_END (0x000A) -#define PDT_ENTRY_SIZE (0x0006) -#define PAGES_TO_SERVICE (10) -#define PAGE_SELECT_LEN (2) - -#define SYNAPTICS_RMI4_F01 (0x01) -#define SYNAPTICS_RMI4_F11 (0x11) -#define SYNAPTICS_RMI4_F12 (0x12) -#define SYNAPTICS_RMI4_F1A (0x1a) -#define SYNAPTICS_RMI4_F34 (0x34) -#define SYNAPTICS_RMI4_F54 (0x54) -#define SYNAPTICS_RMI4_F55 (0x55) - -#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2 -#define SYNAPTICS_RMI4_DATE_CODE_SIZE 3 -#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10 -#define SYNAPTICS_RMI4_BUILD_ID_SIZE 3 - -#define MAX_NUMBER_OF_FINGERS 10 -#define MAX_NUMBER_OF_BUTTONS 4 -#define MAX_INTR_REGISTERS 4 - -#define MASK_16BIT 0xFFFF -#define MASK_8BIT 0xFF -#define MASK_7BIT 0x7F -#define MASK_6BIT 0x3F -#define MASK_5BIT 0x1F -#define MASK_4BIT 0x0F -#define MASK_3BIT 0x07 -#define MASK_2BIT 0x03 -#define MASK_1BIT 0x01 - -#define NAME_BUFFER_SIZE 256 - -/* - * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT - * @query_base_addr: base address for query registers - * @cmd_base_addr: base address for command registers - * @ctrl_base_addr: base address for control registers - * @data_base_addr: base address for data registers - * @intr_src_count: number of interrupt sources - * @fn_number: function number - */ -struct synaptics_rmi4_fn_desc { - unsigned char query_base_addr; - unsigned char cmd_base_addr; - unsigned char ctrl_base_addr; - unsigned char data_base_addr; - unsigned char intr_src_count:3; - unsigned char reserved_b3_b4:2; - unsigned char version:2; - unsigned char reserved_b7:1; - unsigned char fn_number; -} __packed; - -/* - * synaptics_rmi4_fn_full_addr - full 16-bit base addresses - * @query_base: 16-bit base address for query registers - * @cmd_base: 16-bit base address for data registers - * @ctrl_base: 16-bit base address for command registers - * @data_base: 16-bit base address for control registers - */ -struct synaptics_rmi4_fn_full_addr { - unsigned short query_base; - unsigned short cmd_base; - unsigned short ctrl_base; - unsigned short data_base; -}; - -/* - * struct synaptics_rmi4_fn - function handler data structure - * @fn_number: function number - * @num_of_data_sources: number of data sources - * @num_of_data_points: maximum number of fingers supported - * @size_of_data_register_block: data register block size - * @data1_offset: offset to data1 register from data base address - * @intr_reg_num: index to associated interrupt register - * @intr_mask: interrupt mask - * @full_addr: full 16-bit base addresses of function registers - * @link: linked list for function handlers - * @data_size: size of private data - * @data: pointer to private data - */ -struct synaptics_rmi4_fn { - unsigned char fn_number; - unsigned char num_of_data_sources; - unsigned char num_of_data_points; - unsigned char size_of_data_register_block; - unsigned char data1_offset; - unsigned char intr_reg_num; - unsigned char intr_mask; - struct synaptics_rmi4_fn_full_addr full_addr; - struct list_head link; - int data_size; - void *data; - void *extra; -}; - -/* - * struct synaptics_rmi4_device_info - device information - * @version_major: rmi protocol major version number - * @version_minor: rmi protocol minor version number - * @manufacturer_id: manufacturer id - * @product_props: product properties information - * @product_info: product info array - * @date_code: device manufacture date - * @tester_id: tester id array - * @serial_number: device serial number - * @product_id_string: device product id - * @support_fn_list: linked list for function handlers - */ -struct synaptics_rmi4_device_info { - unsigned int version_major; - unsigned int version_minor; - unsigned char manufacturer_id; - unsigned char product_props; - unsigned char product_info[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE]; - unsigned char date_code[SYNAPTICS_RMI4_DATE_CODE_SIZE]; - unsigned short tester_id; - unsigned short serial_number; - unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1]; - unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE]; - unsigned char config_id[3]; - struct mutex support_fn_list_mutex; - struct list_head support_fn_list; - unsigned int package_id; - unsigned int package_id_rev; -}; - -/* - * struct synaptics_rmi4_data - rmi4 device instance data - * @i2c_client: pointer to associated i2c client - * @input_dev: pointer to associated input device - * @board: constant pointer to platform data - * @rmi4_mod_info: device information - * @regulator: pointer to associated regulator - * @rmi4_io_ctrl_mutex: mutex for i2c i/o control - * @det_work: work thread instance for expansion function detection - * @det_workqueue: pointer to work queue for work thread instance - * @early_suspend: instance to support early suspend power management - * @current_page: current page in sensor to acess - * @button_0d_enabled: flag for 0d button support - * @full_pm_cycle: flag for full power management cycle in early suspend stage - * @num_of_intr_regs: number of interrupt registers - * @f01_query_base_addr: query base address for f01 - * @f01_cmd_base_addr: command base address for f01 - * @f01_ctrl_base_addr: control base address for f01 - * @f01_data_base_addr: data base address for f01 - * @irq: attention interrupt - * @sensor_max_x: sensor maximum x value - * @sensor_max_y: sensor maximum y value - * @disp_maxx: max x value of display - * @disp_maxy: max y value of display - * @disp_minx: min x value of display - * @disp_miny: min y value of display - * @irq_enabled: flag for indicating interrupt enable status - * @touch_stopped: flag to stop interrupt thread processing - * @fingers_on_2d: flag to indicate presence of fingers in 2d area - * @flip_x: set to TRUE if desired to flip direction on x-axis - * @flip_y: set to TRUE if desired to flip direction on y-axis - * @fw_updating: firmware is updating flag - * @sensor_sleep: flag to indicate sleep state of sensor - * @wait: wait queue for touch data polling in interrupt thread - * @i2c_read: pointer to i2c read function - * @i2c_write: pointer to i2c write function - * @irq_enable: pointer to irq enable function - */ -struct synaptics_rmi4_data { - struct i2c_client *i2c_client; - struct input_dev *input_dev; - const struct synaptics_rmi4_platform_data *board; - struct synaptics_rmi4_device_info rmi4_mod_info; - struct regulator *vdd; - struct regulator *vcc_i2c; - struct mutex rmi4_io_ctrl_mutex; - struct delayed_work det_work; - struct workqueue_struct *det_workqueue; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif - struct dentry *dir; - char fw_image_name[NAME_BUFFER_SIZE]; - unsigned char current_page; - unsigned char button_0d_enabled; - unsigned char full_pm_cycle; - unsigned char num_of_rx; - unsigned char num_of_tx; - unsigned char num_of_fingers; - unsigned char max_touch_width; - unsigned char report_enable; - unsigned char intr_mask[MAX_INTR_REGISTERS]; - unsigned short num_of_intr_regs; - unsigned short f01_query_base_addr; - unsigned short f01_cmd_base_addr; - unsigned short f01_ctrl_base_addr; - unsigned short f01_data_base_addr; - int irq; - int sensor_max_x; - int sensor_max_y; - int disp_maxx; - int disp_maxy; - int disp_minx; - int disp_miny; - bool irq_enabled; - bool touch_stopped; - bool fingers_on_2d; - bool sensor_sleep; - bool flip_x; - bool flip_y; - bool fw_updating; - bool suspended; - wait_queue_head_t wait; - bool stay_awake; - bool staying_awake; - int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr, - unsigned char *data, unsigned short length); - int (*i2c_write)(struct synaptics_rmi4_data *pdata, unsigned short addr, - unsigned char *data, unsigned short length); - int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable); - int (*reset_device)(struct synaptics_rmi4_data *rmi4_data); -#ifdef CONFIG_FB - struct notifier_block fb_notif; -#else -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif -#endif - struct pinctrl *ts_pinctrl; - struct pinctrl_state *gpio_state_active; - struct pinctrl_state *gpio_state_suspend; -#if defined(CONFIG_SECURE_TOUCH) - atomic_t st_enabled; - atomic_t st_pending_irqs; - struct completion st_powerdown; - struct completion st_irq_processed; -#endif -}; - -enum exp_fn { - RMI_DEV = 0, - RMI_F34, - RMI_F54, - RMI_FW_UPDATER, - RMI_LAST, -}; - -struct synaptics_rmi4_exp_fn_ptr { - int (*read)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, - unsigned char *data, unsigned short length); - int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, - unsigned char *data, unsigned short length); - int (*enable)(struct synaptics_rmi4_data *rmi4_data, bool enable); -}; - -void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert, - int (*func_init)(struct synaptics_rmi4_data *rmi4_data), - void (*func_remove)(struct synaptics_rmi4_data *rmi4_data), - void (*func_attn)(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask)); - -static inline ssize_t synaptics_rmi4_store_error(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - dev_warn(dev, "%s Attempted to write to read-only attribute %s\n", - __func__, attr->attr.name); - return -EPERM; -} - -static inline void batohs(unsigned short *dest, unsigned char *src) -{ - *dest = src[1] * 0x100 + src[0]; -} - -static inline void hstoba(unsigned char *dest, unsigned short src) -{ - dest[0] = src % 0x100; - dest[1] = src / 0x100; -} - -#endif diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c deleted file mode 100644 index 8478b24b5832..000000000000 --- a/drivers/input/touchscreen/synaptics_rmi_dev.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Synaptics RMI4 touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * 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/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/gpio.h> -#include <linux/uaccess.h> -#include <linux/cdev.h> -#include <linux/input/synaptics_dsx.h> -#include "synaptics_i2c_rmi4.h" - -#define CHAR_DEVICE_NAME "rmi" -#define DEVICE_CLASS_NAME "rmidev" -#define DEV_NUMBER 1 -#define REG_ADDR_LIMIT 0xFFFF - -static ssize_t rmidev_sysfs_open_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_release_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_address_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_length_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_data_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t rmidev_sysfs_data_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -struct rmidev_handle { - dev_t dev_no; - unsigned short address; - unsigned int length; - struct device dev; - struct synaptics_rmi4_data *rmi4_data; - struct synaptics_rmi4_exp_fn_ptr *fn_ptr; - struct kobject *sysfs_dir; - void *data; -}; - -struct rmidev_data { - int ref_count; - struct cdev main_dev; - struct class *device_class; - struct mutex file_mutex; - struct rmidev_handle *rmi_dev; -}; - -static struct device_attribute attrs[] = { - __ATTR(open, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_open_store), - __ATTR(release, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_release_store), - __ATTR(address, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_address_store), - __ATTR(length, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_length_store), - __ATTR(data, (S_IWUSR | S_IWGRP), - rmidev_sysfs_data_show, - rmidev_sysfs_data_store), -}; - -static int rmidev_major_num; - -static struct class *rmidev_device_class; - -static struct rmidev_handle *rmidev; - -static struct completion remove_complete; - -static ssize_t rmidev_sysfs_open_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - rmidev->fn_ptr->enable(rmidev->rmi4_data, false); - dev_dbg(&rmidev->rmi4_data->i2c_client->dev, - "%s: Attention interrupt disabled\n", - __func__); - - return count; -} - -static ssize_t rmidev_sysfs_release_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - rmidev->fn_ptr->enable(rmidev->rmi4_data, true); - dev_dbg(&rmidev->rmi4_data->i2c_client->dev, - "%s: Attention interrupt enabled\n", - __func__); - - return count; -} - -static ssize_t rmidev_sysfs_address_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input > REG_ADDR_LIMIT) - return -EINVAL; - - rmidev->address = (unsigned short)input; - - return count; -} - -static ssize_t rmidev_sysfs_length_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input > REG_ADDR_LIMIT) - return -EINVAL; - - rmidev->length = input; - - return count; -} - -static ssize_t rmidev_sysfs_data_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned int data_length = rmidev->length; - - if (data_length > (REG_ADDR_LIMIT - rmidev->address)) - data_length = REG_ADDR_LIMIT - rmidev->address; - - if (data_length) { - retval = rmidev->fn_ptr->read(rmidev->rmi4_data, - rmidev->address, - (unsigned char *)buf, - data_length); - if (retval < 0) { - dev_err(&rmidev->rmi4_data->i2c_client->dev, - "%s: Failed to read data\n", - __func__); - return retval; - } - } else { - return -EINVAL; - } - - return data_length; -} - -static ssize_t rmidev_sysfs_data_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int data_length = rmidev->length; - - if (data_length > (REG_ADDR_LIMIT - rmidev->address)) - data_length = REG_ADDR_LIMIT - rmidev->address; - - if (data_length) { - retval = rmidev->fn_ptr->write(rmidev->rmi4_data, - rmidev->address, - (unsigned char *)buf, - data_length); - if (retval < 0) { - dev_err(&rmidev->rmi4_data->i2c_client->dev, - "%s: Failed to write data\n", - __func__); - return retval; - } - } else { - return -EINVAL; - } - - return data_length; -} - -/* - * rmidev_llseek - used to set up register address - * - * @filp: file structure for seek - * @off: offset - * if whence == SEEK_SET, - * high 16 bits: page address - * low 16 bits: register address - * if whence == SEEK_CUR, - * offset from current position - * if whence == SEEK_END, - * offset from end position (0xFFFF) - * @whence: SEEK_SET, SEEK_CUR, or SEEK_END - */ -static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence) -{ - loff_t newpos; - struct rmidev_data *dev_data = filp->private_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - mutex_lock(&(dev_data->file_mutex)); - - switch (whence) { - case SEEK_SET: - newpos = off; - break; - case SEEK_CUR: - newpos = filp->f_pos + off; - break; - case SEEK_END: - newpos = REG_ADDR_LIMIT + off; - break; - default: - newpos = -EINVAL; - goto clean_up; - } - - if (newpos < 0 || newpos > REG_ADDR_LIMIT) { - dev_err(&rmidev->rmi4_data->i2c_client->dev, - "%s: New position 0x%04x is invalid\n", - __func__, (unsigned int)newpos); - newpos = -EINVAL; - goto clean_up; - } - - filp->f_pos = newpos; - -clean_up: - mutex_unlock(&(dev_data->file_mutex)); - - return newpos; -} - -/* - * rmidev_read: - use to read data from rmi device - * - * @filp: file structure for read - * @buf: user space buffer pointer - * @count: number of bytes to read - * @f_pos: offset (starting register address) - */ -static ssize_t rmidev_read(struct file *filp, char __user *buf, - size_t count, loff_t *f_pos) -{ - ssize_t retval; - unsigned char tmpbuf[count + 1]; - struct rmidev_data *dev_data = filp->private_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - if (count == 0) - return 0; - - if (count > (REG_ADDR_LIMIT - *f_pos)) - count = REG_ADDR_LIMIT - *f_pos; - - mutex_lock(&(dev_data->file_mutex)); - - retval = rmidev->fn_ptr->read(rmidev->rmi4_data, - *f_pos, - tmpbuf, - count); - if (retval < 0) - goto clean_up; - - if (copy_to_user(buf, tmpbuf, count)) - retval = -EFAULT; - else - *f_pos += retval; - -clean_up: - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -/* - * rmidev_write: - used to write data to rmi device - * - * @filep: file structure for write - * @buf: user space buffer pointer - * @count: number of bytes to write - * @f_pos: offset (starting register address) - */ -static ssize_t rmidev_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - ssize_t retval; - unsigned char tmpbuf[count + 1]; - struct rmidev_data *dev_data = filp->private_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - if (count == 0) - return 0; - - if (count > (REG_ADDR_LIMIT - *f_pos)) - count = REG_ADDR_LIMIT - *f_pos; - - if (copy_from_user(tmpbuf, buf, count)) - return -EFAULT; - - mutex_lock(&(dev_data->file_mutex)); - - retval = rmidev->fn_ptr->write(rmidev->rmi4_data, - *f_pos, - tmpbuf, - count); - if (retval >= 0) - *f_pos += retval; - - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -/* - * rmidev_open: enable access to rmi device - * @inp: inode struture - * @filp: file structure - */ -static int rmidev_open(struct inode *inp, struct file *filp) -{ - int retval = 0; - struct rmidev_data *dev_data = - container_of(inp->i_cdev, struct rmidev_data, main_dev); - - if (!dev_data) - return -EACCES; - - filp->private_data = dev_data; - - mutex_lock(&(dev_data->file_mutex)); - - rmidev->fn_ptr->enable(rmidev->rmi4_data, false); - dev_dbg(&rmidev->rmi4_data->i2c_client->dev, - "%s: Attention interrupt disabled\n", - __func__); - - if (dev_data->ref_count < 1) - dev_data->ref_count++; - else - retval = -EACCES; - - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -/* - * rmidev_release: - release access to rmi device - * @inp: inode structure - * @filp: file structure - */ -static int rmidev_release(struct inode *inp, struct file *filp) -{ - struct rmidev_data *dev_data = - container_of(inp->i_cdev, struct rmidev_data, main_dev); - - if (!dev_data) - return -EACCES; - - mutex_lock(&(dev_data->file_mutex)); - - dev_data->ref_count--; - if (dev_data->ref_count < 0) - dev_data->ref_count = 0; - - rmidev->fn_ptr->enable(rmidev->rmi4_data, true); - dev_dbg(&rmidev->rmi4_data->i2c_client->dev, - "%s: Attention interrupt enabled\n", - __func__); - - mutex_unlock(&(dev_data->file_mutex)); - - return 0; -} - -static const struct file_operations rmidev_fops = { - .owner = THIS_MODULE, - .llseek = rmidev_llseek, - .read = rmidev_read, - .write = rmidev_write, - .open = rmidev_open, - .release = rmidev_release, -}; - -static void rmidev_device_cleanup(struct rmidev_data *dev_data) -{ - dev_t devno; - - if (dev_data) { - devno = dev_data->main_dev.dev; - - if (dev_data->device_class) - device_destroy(dev_data->device_class, devno); - - cdev_del(&dev_data->main_dev); - - unregister_chrdev_region(devno, 1); - - dev_dbg(&rmidev->rmi4_data->i2c_client->dev, - "%s: rmidev device removed\n", - __func__); - } - - return; -} - -static char *rmi_char_devnode(struct device *dev, umode_t *mode) -{ - if (!mode) - return NULL; - - *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - - return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev)); -} - -static int rmidev_create_device_class(void) -{ - rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME); - - if (IS_ERR(rmidev_device_class)) { - pr_err("%s: Failed to create /dev/%s\n", - __func__, CHAR_DEVICE_NAME); - return -ENODEV; - } - - rmidev_device_class->devnode = rmi_char_devnode; - - return 0; -} - -static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - dev_t dev_no; - unsigned char attr_count; - struct rmidev_data *dev_data; - struct device *device_ptr; - - rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL); - if (!rmidev) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for rmidev\n", - __func__); - retval = -ENOMEM; - goto err_rmidev; - } - - rmidev->fn_ptr = kzalloc(sizeof(*(rmidev->fn_ptr)), GFP_KERNEL); - if (!rmidev) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for fn_ptr\n", - __func__); - retval = -ENOMEM; - goto err_fn_ptr; - } - - rmidev->fn_ptr->read = rmi4_data->i2c_read; - rmidev->fn_ptr->write = rmi4_data->i2c_write; - rmidev->fn_ptr->enable = rmi4_data->irq_enable; - rmidev->rmi4_data = rmi4_data; - - retval = rmidev_create_device_class(); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to create device class\n", - __func__); - goto err_device_class; - } - - if (rmidev_major_num) { - dev_no = MKDEV(rmidev_major_num, DEV_NUMBER); - retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME); - } else { - retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to allocate char device region\n", - __func__); - goto err_device_region; - } - - rmidev_major_num = MAJOR(dev_no); - dev_dbg(&rmi4_data->i2c_client->dev, - "%s: Major number of rmidev = %d\n", - __func__, rmidev_major_num); - } - - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); - if (!dev_data) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to alloc mem for dev_data\n", - __func__); - retval = -ENOMEM; - goto err_dev_data; - } - - mutex_init(&dev_data->file_mutex); - dev_data->rmi_dev = rmidev; - rmidev->data = dev_data; - - cdev_init(&dev_data->main_dev, &rmidev_fops); - - retval = cdev_add(&dev_data->main_dev, dev_no, 1); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to add rmi char device\n", - __func__); - goto err_char_device; - } - - dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no)); - dev_data->device_class = rmidev_device_class; - - device_ptr = device_create(dev_data->device_class, NULL, dev_no, - NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no)); - if (IS_ERR(device_ptr)) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to create rmi char device\n", - __func__); - retval = -ENODEV; - goto err_char_device; - } - - retval = gpio_export(rmi4_data->board->irq_gpio, false); - if (retval < 0) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to export attention gpio\n", - __func__); - } else { - retval = gpio_export_link(&(rmi4_data->input_dev->dev), - "attn", rmi4_data->board->irq_gpio); - if (retval < 0) { - dev_err(&rmi4_data->input_dev->dev, - "%s Failed to create gpio symlink\n", - __func__); - } else { - dev_dbg(&rmi4_data->input_dev->dev, - "%s: Exported attention gpio %d\n", - __func__, rmi4_data->board->irq_gpio); - } - } - - rmidev->sysfs_dir = kobject_create_and_add("rmidev", - &rmi4_data->input_dev->dev.kobj); - if (!rmidev->sysfs_dir) { - dev_err(&rmi4_data->i2c_client->dev, - "%s: Failed to create sysfs directory\n", - __func__); - goto err_sysfs_dir; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(rmidev->sysfs_dir, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(&rmi4_data->input_dev->dev, - "%s: Failed to create sysfs attributes\n", - __func__); - retval = -ENODEV; - goto err_sysfs_attrs; - } - } - - init_completion(&remove_complete); - - return 0; - -err_sysfs_attrs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - kobject_put(rmidev->sysfs_dir); - -err_sysfs_dir: -err_char_device: - rmidev_device_cleanup(dev_data); - kfree(dev_data); - -err_dev_data: - unregister_chrdev_region(dev_no, 1); - -err_device_region: - class_destroy(rmidev_device_class); - -err_device_class: - kfree(rmidev->fn_ptr); - -err_fn_ptr: - kfree(rmidev); - -err_rmidev: - return retval; -} - -static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char attr_count; - struct rmidev_data *dev_data; - - if (!rmidev) - return; - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) - sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); - - kobject_put(rmidev->sysfs_dir); - - dev_data = rmidev->data; - if (dev_data) { - rmidev_device_cleanup(dev_data); - kfree(dev_data); - } - - unregister_chrdev_region(rmidev->dev_no, 1); - - class_destroy(rmidev_device_class); - - kfree(rmidev->fn_ptr); - kfree(rmidev); - - complete(&remove_complete); - - return; -} - -static int __init rmidev_module_init(void) -{ - synaptics_rmi4_new_function(RMI_DEV, true, - rmidev_init_device, - rmidev_remove_device, - NULL); - return 0; -} - -static void __exit rmidev_module_exit(void) -{ - init_completion(&remove_complete); - synaptics_rmi4_new_function(RMI_DEV, false, - rmidev_init_device, - rmidev_remove_device, - NULL); - wait_for_completion(&remove_complete); - return; -} - -module_init(rmidev_module_init); -module_exit(rmidev_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("RMI4 RMI_Dev Module"); -MODULE_LICENSE("GPL v2"); diff --git a/include/linux/input/synaptics_dsx.h b/include/linux/input/synaptics_dsx.h deleted file mode 100644 index e9e4b3f97d2b..000000000000 --- a/include/linux/input/synaptics_dsx.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Synaptics RMI4 touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * Copyright (c) 2013-2014, 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. - */ - -#ifndef _SYNAPTICS_DSX_H_ -#define _SYNAPTICS_DSX_H_ - -/* - * struct synaptics_rmi4_capacitance_button_map - 0d button map - * @nbuttons: number of buttons - * @map: button map - */ -struct synaptics_rmi4_capacitance_button_map { - unsigned char nbuttons; - unsigned char *map; -}; - -/* - * struct synaptics_rmi4_platform_data - rmi4 platform data - * @x_flip: x flip flag - * @y_flip: y flip flag - * @i2c_pull_up: pull up i2c bus with regulator - * @power_down_enable: enable complete regulator shutdown in suspend - * @is_wake: keep awake in suspend - * @irq_gpio: attention interrupt gpio - * @irq_flags: flags used by the irq - * @reset_flags: flags used by reset line - * @reset_gpio: reset gpio - * @panel_x: panel maximum values on the x - * @panel_y: panel maximum values on the y - * @disp_maxx: display panel maximum values on the x - * @disp_maxy: display panel maximum values on the y - * @disp_minx: display panel minimum values on the x - * @disp_miny: display panel minimum values on the y - * @panel_maxx: touch panel maximum values on the x - * @panel_maxy: touch panel maximum values on the y - * @panel_minx: touch panel minimum values on the x - * @panel_miny: touch panel minimum values on the y - * @reset_delay: reset delay - * @gpio_config: pointer to gpio configuration function - * @capacitance_button_map: pointer to 0d button map - */ -struct synaptics_rmi4_platform_data { - bool x_flip; - bool y_flip; - bool i2c_pull_up; - bool power_down_enable; - bool disable_gpios; - bool do_lockdown; - bool detect_device; - bool modify_reso; - bool is_wake; - unsigned irq_gpio; - u32 irq_flags; - u32 reset_flags; - unsigned reset_gpio; - unsigned panel_minx; - unsigned panel_miny; - unsigned panel_maxx; - unsigned panel_maxy; - unsigned disp_minx; - unsigned disp_miny; - unsigned disp_maxx; - unsigned disp_maxy; - unsigned reset_delay; - const char *fw_image_name; - unsigned int package_id; - int (*gpio_config)(unsigned gpio, bool configure); - struct synaptics_rmi4_capacitance_button_map *capacitance_button_map; -}; - -#endif -- GitLab