From 27ff365a173b5fa28a3112d6d0b7edea17f178c7 Mon Sep 17 00:00:00 2001 From: Shantanu Jain Date: Fri, 17 Mar 2017 19:30:40 +0530 Subject: [PATCH] input: touchscreen: remove synaptics v2.6 touch driver Remove synaptics v2.6 touch driver from the kernel code as it has never been used in any of the recent platforms. Change-Id: Ibf14dec548a180e517d9b41098af642577c4328b Signed-off-by: Shantanu Jain --- .../touchscreen/synaptics_dsxv26_i2c.txt | 57 - drivers/input/touchscreen/Kconfig | 1 - drivers/input/touchscreen/Makefile | 1 - .../touchscreen/synaptics_dsx_2.6/Kconfig | 127 - .../touchscreen/synaptics_dsx_2.6/Makefile | 17 - .../synaptics_dsx_active_pen.c | 624 --- .../synaptics_dsx_2.6/synaptics_dsx_core.c | 4711 ----------------- .../synaptics_dsx_2.6/synaptics_dsx_core.h | 500 -- .../synaptics_dsx_fw_update.c | 4440 ---------------- .../synaptics_dsx_2.6/synaptics_dsx_gesture.c | 2308 -------- .../synaptics_dsx_2.6/synaptics_dsx_i2c.c | 712 --- .../synaptics_dsx_proximity.c | 692 --- .../synaptics_dsx_2.6/synaptics_dsx_rmi_dev.c | 1058 ---- .../synaptics_dsx_rmi_hid_i2c.c | 1006 ---- .../synaptics_dsx_2.6/synaptics_dsx_spi.c | 634 --- .../synaptics_dsx_test_reporting.c | 4162 --------------- .../synaptics_dsx_2.6/synaptics_dsx_video.c | 416 -- include/linux/input/synaptics_dsx_v2_6.h | 115 - 18 files changed, 21581 deletions(-) delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/Makefile delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_active_pen.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.h delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_fw_update.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_gesture.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_proximity.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_rmi_dev.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_rmi_hid_i2c.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_spi.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_test_reporting.c delete mode 100644 drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_video.c delete mode 100644 include/linux/input/synaptics_dsx_v2_6.h diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt deleted file mode 100644 index c10fd981df2b..000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt +++ /dev/null @@ -1,57 +0,0 @@ -Synaptics DSXV26 touch controller - -Please add this description here: The Synaptics Touch controller is connected to the -host processor via I2C. The controller generates interrupts when the user touches -the panel. The host controller is expected to read the touch coordinates over I2C and -pass the coordinates to the rest of the system. - -Required properties: - - - compatible : should be "synaptics,dsx-i2c". - - reg : i2c slave address of the device. - - interrupt-parent : parent of interrupt. - - synaptics,irq-gpio : irq gpio. - - synaptics,irq-flags : irq flags. - -Optional property: - - vdd_ana-supply : digital voltage power supply needed to power device. - - vcc_i2c-supply : analog voltage power supply needed to power device. - - synaptics,pwr-reg-name : power reg name of digital voltage. - - synaptics,bus-reg-name : bus reg name of analog voltage. - - synaptics,irq-on-state : status of irq gpio. - - synaptics,cap-button-codes : virtual key code mappings to be used. - - synaptics,vir-button-codes : virtual key code and the response region on panel. - - synaptics,x-flip : modify orientation of the x axis. - - synaptics,y-flip : modify orientation of the y axis. - - synaptics,reset-delay-ms : reset delay for controller (ms), default 100. - - synaptics,max-y-for-2d : maximal y value of the panel. - - clock-names : Clock names used for secure touch. They are: "iface_clk", "core_clk" - - clocks : Defined if 'clock-names' DT property is defined. These clocks - are associated with the underlying I2C bus. - -Example: - i2c@78b7000 { - status = "ok"; - synaptics@4b { - compatible = "synaptics,dsx-i2c"; - reg = <0x4b>; - interrupt-parent = <&tlmm>; - interrupts = <65 0x2008>; - vdd_ana-supply = <&pmtitanium_l17>; - vcc_i2c-supply = <&pmtitanium_l6>; - synaptics,pwr-reg-name = "vdd_ana"; - synaptics,bus-reg-name = "vcc_i2c"; - synaptics,irq-gpio = <&tlmm 65 0x2008>; - synaptics,irq-on-state = <0>; - synaptics,irq-flags = <0x2008>; /* IRQF_ONESHOT | IRQF_TRIGGER_LOW */ - synaptics,power-delay-ms = <200>; - synaptics,reset-delay-ms = <200>; - synaptics,max-y-for-2d = <1919>; /* remove if no virtual buttons */ - synaptics,cap-button-codes = <139 172 158>; - synaptics,vir-button-codes = <139 180 2000 320 160 172 540 2000 320 160 158 900 2000 320 160>; - /* Underlying clocks used by secure touch */ - clock-names = "iface_clk", "core_clk"; - clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, - <&clock_gcc clk_gcc_blsp1_qup3_i2c_apps_clk>; - }; - }; diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 1d4e8a4ce206..2d564aabbc74 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -12,7 +12,6 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN source "drivers/input/touchscreen/synaptics_dsx/Kconfig" -source "drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig" config OF_TOUCHSCREEN def_tristate INPUT diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 2e0161cf95bc..f5be6fc19751 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -70,7 +70,6 @@ obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o obj-$(CONFIG_TOUCHSCREEN_SUN4I) += sun4i-ts.o obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_v21) += synaptics_dsx/ -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_v26) += synaptics_dsx_2.6/ obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig b/drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig deleted file mode 100644 index 53896288ba77..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig +++ /dev/null @@ -1,127 +0,0 @@ -# -# Synaptics DSX v2.6 touchscreen driver configuration -# -menuconfig TOUCHSCREEN_SYNAPTICS_DSX_v26 - bool "Synaptics DSX v2.6 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_v26 - -choice - default TOUCHSCREEN_SYNAPTICS_DSX_I2C_v26 - prompt "Synaptics DSX v2.6 bus interface" -config TOUCHSCREEN_SYNAPTICS_DSX_I2C_v26 - bool "RMI over I2C" - depends on I2C -config TOUCHSCREEN_SYNAPTICS_DSX_SPI_v26 - bool "RMI over SPI" - depends on SPI_MASTER -config TOUCHSCREEN_SYNAPTICS_DSX_RMI_HID_I2C_v26 - bool "HID over I2C" - depends on I2C -endchoice - -config TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 - tristate "Synaptics DSX v2.6 core driver module" - depends on I2C || SPI_MASTER - help - Say Y here to enable basic touch reporting functionality. - - 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_v26 - tristate "Synaptics DSX v2.6 RMI device module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 - 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_v26 - tristate "Synaptics DSX v2.6 firmware update module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 - help - Say Y here to enable support for doing 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_TEST_REPORTING_v26 - tristate "Synaptics DSX v2.6 test reporting module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 - help - Say Y here to enable support for retrieving production test reports. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_test_reporting. - -config TOUCHSCREEN_SYNAPTICS_DSX_PROXIMITY_v26 - tristate "Synaptics DSX v2.6 proximity module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 - help - Say Y here to enable support for proximity functionality. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_proximity. - -config TOUCHSCREEN_SYNAPTICS_DSX_ACTIVE_PEN_v26 - tristate "Synaptics DSX v2.6 active pen module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 - help - Say Y here to enable support for active pen functionality. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_active_pen. - -config TOUCHSCREEN_SYNAPTICS_DSX_GESTURE_v26 - tristate "Synaptics DSX v2.6 user defined gesture module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 - help - Say Y here to enable support for user defined gesture functionality. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_gesture. - -config TOUCHSCREEN_SYNAPTICS_DSX_VIDEO_v26 - tristate "Synaptics DSX v2.6 video module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 - help - Say Y here to enable support for video communication functionality. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_video. - -config SECURE_TOUCH_SYNAPTICS_DSX_V26 - bool "Secure Touch support for Synaptics V2.6 Touchscreen" - depends on TOUCHSCREEN_SYNAPTICS_DSX_I2C_v26 - help - Say Y here - -Synaptics DSX V2.6 touch driver is connected - -To enable secure touch for Synaptics DSX V2.6 touch driver - - If unsure, say N. - -endif diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/Makefile b/drivers/input/touchscreen/synaptics_dsx_2.6/Makefile deleted file mode 100644 index e5e72153f8c4..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# -# Makefile for the Synaptics DSX touchscreen driver. -# - -# Each configuration option enables a list of files. - -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C_v26) += synaptics_dsx_i2c.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_SPI_v26) += synaptics_dsx_spi.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_HID_I2C_v26) += synaptics_dsx_rmi_hid_i2c.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26) += synaptics_dsx_core.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26) += synaptics_dsx_rmi_dev.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26) += synaptics_dsx_fw_update.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_TEST_REPORTING_v26) += synaptics_dsx_test_reporting.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_PROXIMITY_v26) += synaptics_dsx_proximity.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_ACTIVE_PEN_v26) += synaptics_dsx_active_pen.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_GESTURE_v26) += synaptics_dsx_gesture.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_VIDEO_v26) += synaptics_dsx_video.o diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_active_pen.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_active_pen.c deleted file mode 100644 index db5324ab09fe..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_active_pen.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define APEN_PHYS_NAME "synaptics_dsx/active_pen" - -#define ACTIVE_PEN_MAX_PRESSURE_16BIT 65535 -#define ACTIVE_PEN_MAX_PRESSURE_8BIT 255 - -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 apen_data_8b_pressure { - union { - struct { - unsigned char status_pen:1; - unsigned char status_invert:1; - unsigned char status_barrel:1; - unsigned char status_reserved:5; - unsigned char x_lsb; - unsigned char x_msb; - unsigned char y_lsb; - unsigned char y_msb; - unsigned char pressure_msb; - unsigned char battery_state; - unsigned char pen_id_0_7; - unsigned char pen_id_8_15; - unsigned char pen_id_16_23; - unsigned char pen_id_24_31; - } __packed; - unsigned char data[11]; - }; -}; - -struct apen_data { - union { - struct { - unsigned char status_pen:1; - unsigned char status_invert:1; - unsigned char status_barrel:1; - unsigned char status_reserved:5; - unsigned char x_lsb; - unsigned char x_msb; - unsigned char y_lsb; - unsigned char y_msb; - unsigned char pressure_lsb; - unsigned char pressure_msb; - unsigned char battery_state; - unsigned char pen_id_0_7; - unsigned char pen_id_8_15; - unsigned char pen_id_16_23; - unsigned char pen_id_24_31; - } __packed; - unsigned char data[12]; - }; -}; - -struct synaptics_rmi4_apen_handle { - bool apen_present; - unsigned char intr_mask; - unsigned char battery_state; - unsigned short query_base_addr; - unsigned short control_base_addr; - unsigned short data_base_addr; - unsigned short command_base_addr; - unsigned short apen_data_addr; - unsigned short max_pressure; - unsigned int pen_id; - struct input_dev *apen_dev; - struct apen_data *apen_data; - struct synaptics_rmi4_data *rmi4_data; -}; - -static struct synaptics_rmi4_apen_handle *apen; - -DECLARE_COMPLETION(apen_remove_complete); - -static void apen_lift(void) -{ - input_report_key(apen->apen_dev, BTN_TOUCH, 0); - input_report_key(apen->apen_dev, BTN_TOOL_PEN, 0); - input_report_key(apen->apen_dev, BTN_TOOL_RUBBER, 0); - input_sync(apen->apen_dev); - apen->apen_present = false; - - return; -} - -static void apen_report(void) -{ - int retval; - int x; - int y; - int pressure; - static int invert = -1; - struct apen_data_8b_pressure *apen_data_8b; - struct synaptics_rmi4_data *rmi4_data = apen->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - apen->apen_data_addr, - apen->apen_data->data, - sizeof(apen->apen_data->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read active pen data\n", - __func__); - return; - } - - if (apen->apen_data->status_pen == 0) { - if (apen->apen_present) - apen_lift(); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: No active pen data\n", - __func__); - - return; - } - - x = (apen->apen_data->x_msb << 8) | (apen->apen_data->x_lsb); - y = (apen->apen_data->y_msb << 8) | (apen->apen_data->y_lsb); - - if ((x == -1) && (y == -1)) { - if (apen->apen_present) - apen_lift(); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Active pen in range but no valid x & y\n", - __func__); - - return; - } - - if (!apen->apen_present) - invert = -1; - - if (invert != -1 && invert != apen->apen_data->status_invert) - apen_lift(); - - invert = apen->apen_data->status_invert; - - if (apen->max_pressure == ACTIVE_PEN_MAX_PRESSURE_16BIT) { - pressure = (apen->apen_data->pressure_msb << 8) | - apen->apen_data->pressure_lsb; - apen->battery_state = apen->apen_data->battery_state; - apen->pen_id = (apen->apen_data->pen_id_24_31 << 24) | - (apen->apen_data->pen_id_16_23 << 16) | - (apen->apen_data->pen_id_8_15 << 8) | - apen->apen_data->pen_id_0_7; - } else { - apen_data_8b = (struct apen_data_8b_pressure *)apen->apen_data; - pressure = apen_data_8b->pressure_msb; - apen->battery_state = apen_data_8b->battery_state; - apen->pen_id = (apen_data_8b->pen_id_24_31 << 24) | - (apen_data_8b->pen_id_16_23 << 16) | - (apen_data_8b->pen_id_8_15 << 8) | - apen_data_8b->pen_id_0_7; - } - - input_report_key(apen->apen_dev, BTN_TOUCH, pressure > 0 ? 1 : 0); - input_report_key(apen->apen_dev, - apen->apen_data->status_invert > 0 ? - BTN_TOOL_RUBBER : BTN_TOOL_PEN, 1); - input_report_key(apen->apen_dev, - BTN_STYLUS, apen->apen_data->status_barrel > 0 ? - 1 : 0); - input_report_abs(apen->apen_dev, ABS_X, x); - input_report_abs(apen->apen_dev, ABS_Y, y); - input_report_abs(apen->apen_dev, ABS_PRESSURE, pressure); - - input_sync(apen->apen_dev); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Active pen: status = %d, invert = %d, barrel = %d, x = %d, y = %d, pressure = %d\n", - __func__, - apen->apen_data->status_pen, - apen->apen_data->status_invert, - apen->apen_data->status_barrel, - x, y, pressure); - - apen->apen_present = true; - - return; -} - -static void apen_set_params(void) -{ - input_set_abs_params(apen->apen_dev, ABS_X, 0, - apen->rmi4_data->sensor_max_x, 0, 0); - input_set_abs_params(apen->apen_dev, ABS_Y, 0, - apen->rmi4_data->sensor_max_y, 0, 0); - input_set_abs_params(apen->apen_dev, ABS_PRESSURE, 0, - apen->max_pressure, 0, 0); - - return; -} - -static int apen_pressure(struct synaptics_rmi4_f12_query_8 *query_8) -{ - int retval; - unsigned char ii; - unsigned char data_reg_presence; - unsigned char size_of_query_9; - unsigned char *query_9; - unsigned char *data_desc; - struct synaptics_rmi4_data *rmi4_data = apen->rmi4_data; - - data_reg_presence = query_8->data[1]; - - size_of_query_9 = query_8->size_of_query9; - query_9 = kmalloc(size_of_query_9, GFP_KERNEL); - - retval = synaptics_rmi4_reg_read(rmi4_data, - apen->query_base_addr + 9, - query_9, - size_of_query_9); - if (retval < 0) - goto exit; - - data_desc = query_9; - - for (ii = 0; ii < 6; ii++) { - if (!(data_reg_presence & (1 << ii))) - continue; /* The data register is not present */ - data_desc++; /* Jump over the size entry */ - while (*data_desc & (1 << 7)) - data_desc++; - data_desc++; /* Go to the next descriptor */ - } - - data_desc++; /* Jump over the size entry */ - /* Check for the presence of subpackets 1 and 2 */ - if ((*data_desc & (3 << 1)) == (3 << 1)) - apen->max_pressure = ACTIVE_PEN_MAX_PRESSURE_16BIT; - else - apen->max_pressure = ACTIVE_PEN_MAX_PRESSURE_8BIT; - -exit: - kfree(query_9); - - return retval; -} - -static int apen_reg_init(void) -{ - int retval; - unsigned char data_offset; - unsigned char size_of_query8; - struct synaptics_rmi4_f12_query_8 query_8; - struct synaptics_rmi4_data *rmi4_data = apen->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - apen->query_base_addr + 7, - &size_of_query8, - sizeof(size_of_query8)); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_reg_read(rmi4_data, - apen->query_base_addr + 8, - query_8.data, - sizeof(query_8.data)); - if (retval < 0) - return retval; - - if ((size_of_query8 >= 2) && (query_8.data6_is_present)) { - data_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; - apen->apen_data_addr = apen->data_base_addr + data_offset; - retval = apen_pressure(&query_8); - if (retval < 0) - return retval; - } else { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Active pen support unavailable\n", - __func__); - retval = -ENODEV; - } - - return retval; -} - -static int apen_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 = apen->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; - } - } - - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F12\n", - __func__); - return -EINVAL; - -f12_found: - apen->query_base_addr = fd.query_base_addr | (page << 8); - apen->control_base_addr = fd.ctrl_base_addr | (page << 8); - apen->data_base_addr = fd.data_base_addr | (page << 8); - apen->command_base_addr = fd.cmd_base_addr | (page << 8); - - retval = apen_reg_init(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to initialize active pen registers\n", - __func__); - return retval; - } - - apen->intr_mask = 0; - intr_src = fd.intr_src_count; - intr_off = intr_count % 8; - for (ii = intr_off; - ii < (intr_src + intr_off); - ii++) { - apen->intr_mask |= 1 << ii; - } - - rmi4_data->intr_mask[0] |= apen->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 void synaptics_rmi4_apen_attn(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask) -{ - if (!apen) - return; - - if (apen->intr_mask & intr_mask) - apen_report(); - - return; -} - -static int synaptics_rmi4_apen_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - - if (apen) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Handle already exists\n", - __func__); - return 0; - } - - apen = kzalloc(sizeof(*apen), GFP_KERNEL); - if (!apen) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for apen\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - apen->apen_data = kzalloc(sizeof(*(apen->apen_data)), GFP_KERNEL); - if (!apen->apen_data) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for apen_data\n", - __func__); - retval = -ENOMEM; - goto exit_free_apen; - } - - apen->rmi4_data = rmi4_data; - - retval = apen_scan_pdt(); - if (retval < 0) - goto exit_free_apen_data; - - apen->apen_dev = input_allocate_device(); - if (apen->apen_dev == NULL) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate active pen device\n", - __func__); - retval = -ENOMEM; - goto exit_free_apen_data; - } - - apen->apen_dev->name = ACTIVE_PEN_DRIVER_NAME; - apen->apen_dev->phys = APEN_PHYS_NAME; - apen->apen_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; - apen->apen_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; - apen->apen_dev->dev.parent = rmi4_data->pdev->dev.parent; - input_set_drvdata(apen->apen_dev, rmi4_data); - - set_bit(EV_KEY, apen->apen_dev->evbit); - set_bit(EV_ABS, apen->apen_dev->evbit); - set_bit(BTN_TOUCH, apen->apen_dev->keybit); - set_bit(BTN_TOOL_PEN, apen->apen_dev->keybit); - set_bit(BTN_TOOL_RUBBER, apen->apen_dev->keybit); - set_bit(BTN_STYLUS, apen->apen_dev->keybit); -#ifdef INPUT_PROP_DIRECT - set_bit(INPUT_PROP_DIRECT, apen->apen_dev->propbit); -#endif - - apen_set_params(); - - retval = input_register_device(apen->apen_dev); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to register active pen device\n", - __func__); - goto exit_free_input_device; - } - - return 0; - -exit_free_input_device: - input_free_device(apen->apen_dev); - -exit_free_apen_data: - kfree(apen->apen_data); - -exit_free_apen: - kfree(apen); - apen = NULL; - -exit: - return retval; -} - -static void synaptics_rmi4_apen_remove(struct synaptics_rmi4_data *rmi4_data) -{ - if (!apen) - goto exit; - - input_unregister_device(apen->apen_dev); - kfree(apen->apen_data); - kfree(apen); - apen = NULL; - -exit: - complete(&apen_remove_complete); - - return; -} - -static void synaptics_rmi4_apen_reset(struct synaptics_rmi4_data *rmi4_data) -{ - if (!apen) { - synaptics_rmi4_apen_init(rmi4_data); - return; - } - - apen_lift(); - - apen_scan_pdt(); - - return; -} - -static void synaptics_rmi4_apen_reinit(struct synaptics_rmi4_data *rmi4_data) -{ - if (!apen) - return; - - apen_lift(); - - return; -} - -static void synaptics_rmi4_apen_e_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - if (!apen) - return; - - apen_lift(); - - return; -} - -static void synaptics_rmi4_apen_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - if (!apen) - return; - - apen_lift(); - - return; -} - -static struct synaptics_rmi4_exp_fn active_pen_module = { - .fn_type = RMI_ACTIVE_PEN, - .init = synaptics_rmi4_apen_init, - .remove = synaptics_rmi4_apen_remove, - .reset = synaptics_rmi4_apen_reset, - .reinit = synaptics_rmi4_apen_reinit, - .early_suspend = synaptics_rmi4_apen_e_suspend, - .suspend = synaptics_rmi4_apen_suspend, - .resume = NULL, - .late_resume = NULL, - .attn = synaptics_rmi4_apen_attn, -}; - -static int __init rmi4_active_pen_module_init(void) -{ - synaptics_rmi4_new_function(&active_pen_module, true); - - return 0; -} - -static void __exit rmi4_active_pen_module_exit(void) -{ - synaptics_rmi4_new_function(&active_pen_module, false); - - wait_for_completion(&apen_remove_complete); - - return; -} - -module_init(rmi4_active_pen_module_init); -module_exit(rmi4_active_pen_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX Active Pen Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c deleted file mode 100644 index d358f329e7a8..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c +++ /dev/null @@ -1,4711 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" -#ifdef KERNEL_ABOVE_2_6_38 -#include -#endif - -#define INPUT_PHYS_NAME "synaptics_dsx/touch_input" -#define STYLUS_PHYS_NAME "synaptics_dsx/stylus" - -#define VIRTUAL_KEY_MAP_FILE_NAME "virtualkeys." PLATFORM_DRIVER_NAME - -#ifdef KERNEL_ABOVE_2_6_38 -#define TYPE_B_PROTOCOL -#endif - -#define WAKEUP_GESTURE false - -#define NO_0D_WHILE_2D -#define REPORT_2D_Z -#define REPORT_2D_W -/* -#define REPORT_2D_PRESSURE -*/ - -#define F12_DATA_15_WORKAROUND - -#define IGNORE_FN_INIT_FAILURE - -#define FB_READY_RESET -#define FB_READY_WAIT_MS 100 -#define FB_READY_TIMEOUT_S 30 - -#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 REBUILD_WORK_DELAY_MS 500 /* ms */ - -#define EXP_FN_WORK_DELAY_MS 500 /* ms */ -#define MAX_F11_TOUCH_WIDTH 15 -#define MAX_F12_TOUCH_WIDTH 255 -#define MAX_F12_TOUCH_PRESSURE 255 - -#define CHECK_STATUS_TIMEOUT_MS 100 - -#define F01_STD_QUERY_LEN 21 -#define F01_BUID_ID_OFFSET 18 - -#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 F11_CONTINUOUS_MODE 0x00 -#define F11_WAKEUP_GESTURE_MODE 0x04 -#define F12_CONTINUOUS_MODE 0x00 -#define F12_WAKEUP_GESTURE_MODE 0x02 -#define F12_UDG_DETECT 0x0f - -static int synaptics_rmi4_check_status(struct synaptics_rmi4_data *rmi4_data, - bool *was_in_bl_mode); -static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data); -static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data, - bool rebuild); - -#ifdef CONFIG_FB -static void synaptics_rmi4_fb_notify_resume_work(struct work_struct *work); -static int synaptics_rmi4_fb_notifier_cb(struct notifier_block *self, - unsigned long event, void *data); -#endif - -#ifdef CONFIG_HAS_EARLYSUSPEND -#ifndef CONFIG_FB -#define USE_EARLYSUSPEND -#endif -#endif - -#ifdef USE_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 ssize_t synaptics_rmi4_suspend_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_rmi4_wake_gesture_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_wake_gesture_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_rmi4_virtual_key_map_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf); - -#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26) -static ssize_t synaptics_rmi4_secure_touch_enable_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_secure_touch_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t synaptics_rmi4_secure_touch_show(struct device *dev, - struct device_attribute *attr, char *buf); -#endif - -static irqreturn_t synaptics_rmi4_irq(int irq, void *data); - -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_f11_query_0_5 { - union { - struct { - /* query 0 */ - unsigned char f11_query0_b0__2:3; - unsigned char has_query_9:1; - unsigned char has_query_11:1; - unsigned char has_query_12:1; - unsigned char has_query_27:1; - unsigned char has_query_28:1; - - /* query 1 */ - unsigned char num_of_fingers:3; - unsigned char has_rel:1; - unsigned char has_abs:1; - unsigned char has_gestures:1; - unsigned char has_sensitibity_adjust:1; - unsigned char f11_query1_b7:1; - - /* query 2 */ - unsigned char num_of_x_electrodes; - - /* query 3 */ - unsigned char num_of_y_electrodes; - - /* query 4 */ - unsigned char max_electrodes:7; - unsigned char f11_query4_b7:1; - - /* query 5 */ - unsigned char abs_data_size:2; - unsigned char has_anchored_finger:1; - unsigned char has_adj_hyst:1; - unsigned char has_dribble:1; - unsigned char has_bending_correction:1; - unsigned char has_large_object_suppression:1; - unsigned char has_jitter_filter:1; - } __packed; - unsigned char data[6]; - }; -}; - -struct synaptics_rmi4_f11_query_7_8 { - union { - struct { - /* query 7 */ - unsigned char has_single_tap:1; - unsigned char has_tap_and_hold:1; - unsigned char has_double_tap:1; - unsigned char has_early_tap:1; - unsigned char has_flick:1; - unsigned char has_press:1; - unsigned char has_pinch:1; - unsigned char has_chiral_scroll:1; - - /* query 8 */ - unsigned char has_palm_detect:1; - unsigned char has_rotate:1; - unsigned char has_touch_shapes:1; - unsigned char has_scroll_zones:1; - unsigned char individual_scroll_zones:1; - unsigned char has_multi_finger_scroll:1; - unsigned char has_multi_finger_scroll_edge_motion:1; - unsigned char has_multi_finger_scroll_inertia:1; - } __packed; - unsigned char data[2]; - }; -}; - -struct synaptics_rmi4_f11_query_9 { - union { - struct { - unsigned char has_pen:1; - unsigned char has_proximity:1; - unsigned char has_large_object_sensitivity:1; - unsigned char has_suppress_on_large_object_detect:1; - unsigned char has_two_pen_thresholds:1; - unsigned char has_contact_geometry:1; - unsigned char has_pen_hover_discrimination:1; - unsigned char has_pen_hover_and_edge_filters:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f11_query_12 { - union { - struct { - unsigned char has_small_object_detection:1; - unsigned char has_small_object_detection_tuning:1; - unsigned char has_8bit_w:1; - unsigned char has_2d_adjustable_mapping:1; - unsigned char has_general_information_2:1; - unsigned char has_physical_properties:1; - unsigned char has_finger_limit:1; - unsigned char has_linear_cofficient_2:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f11_query_27 { - union { - struct { - unsigned char f11_query27_b0:1; - unsigned char has_pen_position_correction:1; - unsigned char has_pen_jitter_filter_coefficient:1; - unsigned char has_group_decomposition:1; - unsigned char has_wakeup_gesture:1; - unsigned char has_small_finger_correction:1; - unsigned char has_data_37:1; - unsigned char f11_query27_b7:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f11_ctrl_6_9 { - union { - struct { - unsigned char sensor_max_x_pos_7_0; - unsigned char sensor_max_x_pos_11_8:4; - unsigned char f11_ctrl7_b4__7:4; - unsigned char sensor_max_y_pos_7_0; - unsigned char sensor_max_y_pos_11_8:4; - unsigned char f11_ctrl9_b4__7:4; - } __packed; - unsigned char data[4]; - }; -}; - -struct synaptics_rmi4_f11_data_1_5 { - union { - struct { - unsigned char x_position_11_4; - unsigned char y_position_11_4; - unsigned char x_position_3_0:4; - unsigned char y_position_3_0:4; - unsigned char wx:4; - unsigned char wy:4; - unsigned char z; - } __packed; - unsigned char data[5]; - }; -}; - -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; - struct { - unsigned char data16_is_present:1; - unsigned char data17_is_present:1; - unsigned char data18_is_present:1; - unsigned char data19_is_present:1; - unsigned char data20_is_present:1; - unsigned char data21_is_present:1; - unsigned char data22_is_present:1; - unsigned char data23_is_present:1; - } __packed; - }; - unsigned char data[4]; - }; -}; - -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 finger_enable:1; - unsigned char active_stylus_enable:1; - unsigned char palm_enable:1; - unsigned char unclassified_object_enable:1; - unsigned char hovering_finger_enable:1; - unsigned char gloved_finger_enable:1; - unsigned char f12_ctr23_00_b6__7:2; - unsigned char max_reported_objects; - unsigned char f12_ctr23_02_b0:1; - unsigned char report_active_stylus_as_finger:1; - unsigned char report_palm_as_finger:1; - unsigned char report_unclassified_object_as_finger:1; - unsigned char report_hovering_finger_as_finger:1; - unsigned char report_gloved_finger_as_finger:1; - unsigned char report_narrow_object_swipe_as_finger:1; - unsigned char report_handedge_as_finger:1; - unsigned char cover_enable:1; - unsigned char stylus_enable:1; - unsigned char eraser_enable:1; - unsigned char small_object_enable:1; - unsigned char f12_ctr23_03_b4__7:4; - unsigned char report_cover_as_finger:1; - unsigned char report_stylus_as_finger:1; - unsigned char report_eraser_as_finger:1; - unsigned char report_small_object_as_finger:1; - unsigned char f12_ctr23_04_b4__7:4; - }; - unsigned char data[5]; - }; -}; - -struct synaptics_rmi4_f12_ctrl_31 { - 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 rx_clip_low; - unsigned char rx_clip_high; - unsigned char wedge_clip_low; - unsigned char wedge_clip_high; - unsigned char num_of_p; - unsigned char num_of_q; - }; - unsigned char data[12]; - }; -}; - -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 f1a_query0_b3__4:2; - unsigned char has_query4:1; - unsigned char has_query3:1; - unsigned char has_query2:1; - 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_query_4 { - union { - struct { - unsigned char has_ctrl19:1; - unsigned char f1a_query4_b1__4:4; - unsigned char has_ctrl24:1; - unsigned char f1a_query4_b6__7:2; - } __packed; - unsigned char data[1]; - }; -}; - -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 synaptics_dsx_button_map *vir_button_map; - -static struct device_attribute attrs[] = { - __ATTR(reset, S_IWUSR | S_IWGRP, - NULL, - synaptics_rmi4_f01_reset_store), - __ATTR(productinfo, S_IRUGO, - synaptics_rmi4_f01_productinfo_show, - NULL), - __ATTR(buildid, S_IRUGO, - synaptics_rmi4_f01_buildid_show, - NULL), - __ATTR(flashprog, S_IRUGO, - synaptics_rmi4_f01_flashprog_show, - NULL), - __ATTR(0dbutton, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_0dbutton_show, - synaptics_rmi4_0dbutton_store), - __ATTR(suspend, S_IWUSR | S_IWGRP, - NULL, - synaptics_rmi4_suspend_store), - __ATTR(wake_gesture, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_wake_gesture_show, - synaptics_rmi4_wake_gesture_store), -#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26) - __ATTR(secure_touch_enable, (S_IRUGO | S_IWUSR | S_IWGRP), - synaptics_rmi4_secure_touch_enable_show, - synaptics_rmi4_secure_touch_enable_store), - __ATTR(secure_touch, S_IRUGO, - synaptics_rmi4_secure_touch_show, - NULL), -#endif -}; - -static struct kobj_attribute virtual_key_map_attr = { - .attr = { - .name = VIRTUAL_KEY_MAP_FILE_NAME, - .mode = S_IRUGO, - }, - .show = synaptics_rmi4_virtual_key_map_show, -}; - -#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26) -static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) -{ - data->st_initialized = 0; - init_completion(&data->st_powerdown); - init_completion(&data->st_irq_processed); - - /* Get clocks */ - data->core_clk = devm_clk_get(data->pdev->dev.parent, "core_clk"); - if (IS_ERR(data->core_clk)) { - dev_warn(data->pdev->dev.parent, - "%s: error on clk_get(core_clk): %ld\n", __func__, - PTR_ERR(data->core_clk)); - data->core_clk = NULL; - } - - data->iface_clk = devm_clk_get(data->pdev->dev.parent, "iface_clk"); - if (IS_ERR(data->iface_clk)) { - dev_warn(data->pdev->dev.parent, - "%s: error on clk_get(iface_clk): %ld\n", __func__, - PTR_ERR(data->iface_clk)); - data->iface_clk = NULL; - } - - data->st_initialized = 1; -} - -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) { - reinit_completion(&rmi4_data->st_irq_processed); - synaptics_secure_touch_notify(rmi4_data); - wait_for_completion_interruptible( - &rmi4_data->st_irq_processed); - } - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -/* - * 'blocking' variable will have value 'true' when we want to prevent the driver - * from accessing the xPU/SMMU protected HW resources while the session is - * active. - */ -static void synaptics_secure_touch_stop(struct synaptics_rmi4_data *rmi4_data, - bool 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, - bool blocking) -{ -} -#endif - -#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26) -static ssize_t synaptics_rmi4_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_rmi4_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; - - if (!rmi4_data->st_initialized) - return -EIO; - - 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; - } - reinit_completion(&rmi4_data->st_powerdown); - reinit_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_rmi4_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_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, false); - 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; -} - -static ssize_t synaptics_rmi4_suspend_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) - synaptics_rmi4_suspend(dev); - else if (input == 0) - synaptics_rmi4_resume(dev); - else - return -EINVAL; - - return count; -} - -static ssize_t synaptics_rmi4_wake_gesture_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->enable_wakeup_gesture); -} - -static ssize_t synaptics_rmi4_wake_gesture_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; - - input = input > 0 ? 1 : 0; - - if (rmi4_data->f11_wakeup_gesture || rmi4_data->f12_wakeup_gesture) - rmi4_data->enable_wakeup_gesture = input; - - return count; -} - -static ssize_t synaptics_rmi4_virtual_key_map_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int ii; - int cnt; - int count = 0; - - for (ii = 0; ii < vir_button_map->nbuttons; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, "0x01:%d:%d:%d:%d:%d\n", - vir_button_map->map[ii * 5 + 0], - vir_button_map->map[ii * 5 + 1], - vir_button_map->map[ii * 5 + 2], - vir_button_map->map[ii * 5 + 3], - vir_button_map->map[ii * 5 + 4]); - buf += cnt; - count += cnt; - } - - return count; -} - -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 finger_status_reg[3]; - unsigned char detected_gestures; - unsigned short data_addr; - unsigned short data_offset; - int x; - int y; - int wx; - int wy; - int temp; - struct synaptics_rmi4_f11_data_1_5 data; - struct synaptics_rmi4_f11_extra_data *extra_data; - - /* - * 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; - - extra_data = (struct synaptics_rmi4_f11_extra_data *)fhandler->extra; - - if (rmi4_data->suspend && rmi4_data->enable_wakeup_gesture) { - retval = synaptics_rmi4_reg_read(rmi4_data, - data_addr + extra_data->data38_offset, - &detected_gestures, - sizeof(detected_gestures)); - if (retval < 0) - return 0; - - if (detected_gestures) { - input_report_key(rmi4_data->input_dev, KEY_WAKEUP, 1); - input_sync(rmi4_data->input_dev); - input_report_key(rmi4_data->input_dev, KEY_WAKEUP, 0); - input_sync(rmi4_data->input_dev); - rmi4_data->suspend = false; - } - - return 0; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - data_addr, - finger_status_reg, - num_of_finger_status_regs); - if (retval < 0) - return 0; - - mutex_lock(&(rmi4_data->rmi4_report_mutex)); - - 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 * sizeof(data.data)); - retval = synaptics_rmi4_reg_read(rmi4_data, - data_offset, - data.data, - sizeof(data.data)); - if (retval < 0) { - touch_count = 0; - goto exit; - } - - x = (data.x_position_11_4 << 4) | data.x_position_3_0; - y = (data.y_position_11_4 << 4) | data.y_position_3_0; - wx = data.wx; - wy = data.wy; - - 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: status = 0x%02x, x = %d, y = %d, wx = %d, 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); - -exit: - mutex_unlock(&(rmi4_data->rmi4_report_mutex)); - - return touch_count; -} - -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 index; - unsigned char finger; - unsigned char fingers_to_process; - unsigned char finger_status; - unsigned char size_of_2d_data; - unsigned char gesture_type; - unsigned short data_addr; - int x; - int y; - int wx; - int wy; - int temp; -#ifdef REPORT_2D_PRESSURE - int pressure; -#endif - struct synaptics_rmi4_f12_extra_data *extra_data; - struct synaptics_rmi4_f12_finger_data *data; - struct synaptics_rmi4_f12_finger_data *finger_data; - static unsigned char finger_presence; - static unsigned char stylus_presence; -#ifdef F12_DATA_15_WORKAROUND - static unsigned char objects_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); - - if (rmi4_data->suspend && rmi4_data->enable_wakeup_gesture) { - retval = synaptics_rmi4_reg_read(rmi4_data, - data_addr + extra_data->data4_offset, - rmi4_data->gesture_detection, - sizeof(rmi4_data->gesture_detection)); - if (retval < 0) - return 0; - - gesture_type = rmi4_data->gesture_detection[0]; - - if (gesture_type && gesture_type != F12_UDG_DETECT) { - input_report_key(rmi4_data->input_dev, KEY_WAKEUP, 1); - input_sync(rmi4_data->input_dev); - input_report_key(rmi4_data->input_dev, KEY_WAKEUP, 0); - input_sync(rmi4_data->input_dev); - rmi4_data->suspend = false; - } - - return 0; - } - - /* 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 */ - index = extra_data->data15_size - 1; /* Highest byte */ - finger = (fingers_to_process - 1) % 8; /* Highest bit */ - do { - if (extra_data->data15_data[index] & (1 << finger)) - break; - - if (finger) { - finger--; - } else if (index > 0) { - index--; /* 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, objects_already_present); -#endif - - if (!fingers_to_process) { - synaptics_rmi4_free_fingers(rmi4_data); - finger_presence = 0; - stylus_presence = 0; - 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; - -#ifdef REPORT_2D_PRESSURE - if (rmi4_data->report_pressure) { - retval = synaptics_rmi4_reg_read(rmi4_data, - data_addr + extra_data->data23_offset, - extra_data->data23_data, - fingers_to_process); - if (retval < 0) - return 0; - } -#endif - - mutex_lock(&(rmi4_data->rmi4_report_mutex)); - - for (finger = 0; finger < fingers_to_process; finger++) { - finger_data = data + finger; - finger_status = finger_data->object_type_and_status; - -#ifdef F12_DATA_15_WORKAROUND - objects_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; - - switch (finger_status) { - case F12_FINGER_STATUS: - case F12_GLOVED_FINGER_STATUS: - /* Stylus has priority over fingers */ - if (stylus_presence) - break; -#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 - - 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 - if (rmi4_data->wedge_sensor) { - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MAJOR, wx); - input_report_abs(rmi4_data->input_dev, - ABS_MT_TOUCH_MINOR, wx); - } else { - 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 -#ifdef REPORT_2D_PRESSURE - if (rmi4_data->report_pressure) { - pressure = extra_data->data23_data[finger]; - input_report_abs(rmi4_data->input_dev, - ABS_MT_PRESSURE, pressure); - } -#endif -#ifndef TYPE_B_PROTOCOL - input_mt_sync(rmi4_data->input_dev); -#endif - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Finger %d: status = 0x%02x, x = %d, y = %d, wx = %d, wy = %d\n", - __func__, finger, - finger_status, - x, y, wx, wy); - - finger_presence = 1; - touch_count++; - break; - case F12_PALM_STATUS: - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Finger %d: x = %d, y = %d, wx = %d, wy = %d\n", - __func__, finger, - x, y, wx, wy); - break; - case F12_STYLUS_STATUS: - case F12_ERASER_STATUS: - if (!rmi4_data->stylus_enable) - break; - /* Stylus has priority over fingers */ - if (finger_presence) { - mutex_unlock(&(rmi4_data->rmi4_report_mutex)); - synaptics_rmi4_free_fingers(rmi4_data); - mutex_lock(&(rmi4_data->rmi4_report_mutex)); - finger_presence = 0; - } - if (stylus_presence) {/* Allow one stylus at a timee */ - if (finger + 1 != stylus_presence) - break; - } - input_report_key(rmi4_data->stylus_dev, - BTN_TOUCH, 1); - if (finger_status == F12_STYLUS_STATUS) { - input_report_key(rmi4_data->stylus_dev, - BTN_TOOL_PEN, 1); - } else { - input_report_key(rmi4_data->stylus_dev, - BTN_TOOL_RUBBER, 1); - } - input_report_abs(rmi4_data->stylus_dev, - ABS_X, x); - input_report_abs(rmi4_data->stylus_dev, - ABS_Y, y); - input_sync(rmi4_data->stylus_dev); - - stylus_presence = finger + 1; - touch_count++; - break; - default: -#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 - break; - } - } - - if (touch_count == 0) { - finger_presence = 0; -#ifdef F12_DATA_15_WORKAROUND - objects_already_present = 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 - - if (rmi4_data->stylus_enable) { - stylus_presence = 0; - input_report_key(rmi4_data->stylus_dev, - BTN_TOUCH, 0); - input_report_key(rmi4_data->stylus_dev, - BTN_TOOL_PEN, 0); - if (rmi4_data->eraser_enable) { - input_report_key(rmi4_data->stylus_dev, - BTN_TOOL_RUBBER, 0); - } - input_sync(rmi4_data->stylus_dev); - } - } - - input_sync(rmi4_data->input_dev); - - mutex_unlock(&(rmi4_data->rmi4_report_mutex)); - - 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; - - mutex_lock(&(rmi4_data->rmi4_report_mutex)); - - 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); - - mutex_unlock(&(rmi4_data->rmi4_report_mutex)); - - return; -} - -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; -} - -static void synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *rmi4_data, - bool report) -{ - int retval; - unsigned char data[MAX_INTR_REGISTERS + 1]; - unsigned char *intr = &data[1]; - bool was_in_bl_mode; - 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); - - if (rmi4_data->stay_awake) { - msleep(30); - return; - } - - /* - * 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.status_code == STATUS_CRC_IN_PROGRESS) { - 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 = 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 device status\n", - __func__); - return; - } - } - if (status.unconfigured && !status.flash_prog) { - pr_notice("%s: spontaneous reset detected\n", __func__); - } - - if (!report) - 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; -} - -static irqreturn_t synaptics_rmi4_irq(int irq, void *data) -{ - struct synaptics_rmi4_data *rmi4_data = data; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - if (synaptics_filter_interrupt(data) == IRQ_HANDLED) - return IRQ_HANDLED; - - if (gpio_get_value(bdata->irq_gpio) != bdata->irq_on_state) - goto exit; - - synaptics_rmi4_sensor_report(rmi4_data, true); - -exit: - return IRQ_HANDLED; -} - -static int synaptics_rmi4_int_enable(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - int retval = 0; - unsigned char ii; - unsigned char zero = 0x00; - unsigned char *intr_mask; - unsigned short intr_addr; - - intr_mask = rmi4_data->intr_mask; - - for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) { - if (intr_mask[ii] != 0x00) { - intr_addr = rmi4_data->f01_ctrl_base_addr + 1 + ii; - if (enable) { - retval = synaptics_rmi4_reg_write(rmi4_data, - intr_addr, - &(intr_mask[ii]), - sizeof(intr_mask[ii])); - if (retval < 0) - return retval; - } else { - retval = synaptics_rmi4_reg_write(rmi4_data, - intr_addr, - &zero, - sizeof(zero)); - if (retval < 0) - return retval; - } - } - } - - return retval; -} - -static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data, - bool enable, bool attn_only) -{ - int retval = 0; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - if (attn_only) { - retval = synaptics_rmi4_int_enable(rmi4_data, enable); - return retval; - } - - if (enable) { - if (rmi4_data->irq_enabled) - return retval; - - retval = synaptics_rmi4_int_enable(rmi4_data, false); - if (retval < 0) - return retval; - - /* Process and clear interrupts */ - synaptics_rmi4_sensor_report(rmi4_data, false); - - 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; - } - - retval = synaptics_rmi4_int_enable(rmi4_data, true); - if (retval < 0) - 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 + 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; -} - -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; - int temp; - unsigned char offset; - unsigned char fingers_supported; - struct synaptics_rmi4_f11_extra_data *extra_data; - struct synaptics_rmi4_f11_query_0_5 query_0_5; - struct synaptics_rmi4_f11_query_7_8 query_7_8; - struct synaptics_rmi4_f11_query_9 query_9; - struct synaptics_rmi4_f11_query_12 query_12; - struct synaptics_rmi4_f11_query_27 query_27; - struct synaptics_rmi4_f11_ctrl_6_9 control_6_9; - 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); - if (!fhandler->extra) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for fhandler->extra\n", - __func__); - return -ENOMEM; - } - extra_data = (struct synaptics_rmi4_f11_extra_data *)fhandler->extra; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base, - query_0_5.data, - sizeof(query_0_5.data)); - if (retval < 0) - return retval; - - /* Maximum number of fingers supported */ - if (query_0_5.num_of_fingers <= 4) - fhandler->num_of_data_points = query_0_5.num_of_fingers + 1; - else if (query_0_5.num_of_fingers == 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 + 6, - control_6_9.data, - sizeof(control_6_9.data)); - if (retval < 0) - return retval; - - /* Maximum x and y */ - rmi4_data->sensor_max_x = control_6_9.sensor_max_x_pos_7_0 | - (control_6_9.sensor_max_x_pos_11_8 << 8); - rmi4_data->sensor_max_y = control_6_9.sensor_max_y_pos_7_0 | - (control_6_9.sensor_max_y_pos_11_8 << 8); - 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; - - if (bdata->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_intr_mask(fhandler, fd, intr_count); - - fhandler->data = NULL; - - offset = sizeof(query_0_5.data); - - /* query 6 */ - if (query_0_5.has_rel) - offset += 1; - - /* queries 7 8 */ - if (query_0_5.has_gestures) { - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + offset, - query_7_8.data, - sizeof(query_7_8.data)); - if (retval < 0) - return retval; - - offset += sizeof(query_7_8.data); - } - - /* query 9 */ - if (query_0_5.has_query_9) { - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + offset, - query_9.data, - sizeof(query_9.data)); - if (retval < 0) - return retval; - - offset += sizeof(query_9.data); - } - - /* query 10 */ - if (query_0_5.has_gestures && query_7_8.has_touch_shapes) - offset += 1; - - /* query 11 */ - if (query_0_5.has_query_11) - offset += 1; - - /* query 12 */ - if (query_0_5.has_query_12) { - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + offset, - query_12.data, - sizeof(query_12.data)); - if (retval < 0) - return retval; - - offset += sizeof(query_12.data); - } - - /* query 13 */ - if (query_0_5.has_jitter_filter) - offset += 1; - - /* query 14 */ - if (query_0_5.has_query_12 && query_12.has_general_information_2) - offset += 1; - - /* queries 15 16 17 18 19 20 21 22 23 24 25 26*/ - if (query_0_5.has_query_12 && query_12.has_physical_properties) - offset += 12; - - /* query 27 */ - if (query_0_5.has_query_27) { - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + offset, - query_27.data, - sizeof(query_27.data)); - if (retval < 0) - return retval; - - rmi4_data->f11_wakeup_gesture = query_27.has_wakeup_gesture; - } - - if (!rmi4_data->f11_wakeup_gesture) - return retval; - - /* data 0 */ - fingers_supported = fhandler->num_of_data_points; - offset = (fingers_supported + 3) / 4; - - /* data 1 2 3 4 5 */ - offset += 5 * fingers_supported; - - /* data 6 7 */ - if (query_0_5.has_rel) - offset += 2 * fingers_supported; - - /* data 8 */ - if (query_0_5.has_gestures && query_7_8.data[0]) - offset += 1; - - /* data 9 */ - if (query_0_5.has_gestures && (query_7_8.data[0] || query_7_8.data[1])) - offset += 1; - - /* data 10 */ - if (query_0_5.has_gestures && - (query_7_8.has_pinch || query_7_8.has_flick)) - offset += 1; - - /* data 11 12 */ - if (query_0_5.has_gestures && - (query_7_8.has_flick || query_7_8.has_rotate)) - offset += 2; - - /* data 13 */ - if (query_0_5.has_gestures && query_7_8.has_touch_shapes) - offset += (fingers_supported + 3) / 4; - - /* data 14 15 */ - if (query_0_5.has_gestures && - (query_7_8.has_scroll_zones || - query_7_8.has_multi_finger_scroll || - query_7_8.has_chiral_scroll)) - offset += 2; - - /* data 16 17 */ - if (query_0_5.has_gestures && - (query_7_8.has_scroll_zones && - query_7_8.individual_scroll_zones)) - offset += 2; - - /* data 18 19 20 21 22 23 24 25 26 27 */ - if (query_0_5.has_query_9 && query_9.has_contact_geometry) - offset += 10 * fingers_supported; - - /* data 28 */ - if (query_0_5.has_bending_correction || - query_0_5.has_large_object_suppression) - offset += 1; - - /* data 29 30 31 */ - if (query_0_5.has_query_9 && query_9.has_pen_hover_discrimination) - offset += 3; - - /* data 32 */ - if (query_0_5.has_query_12 && - query_12.has_small_object_detection_tuning) - offset += 1; - - /* data 33 34 */ - if (query_0_5.has_query_27 && query_27.f11_query27_b0) - offset += 2; - - /* data 35 */ - if (query_0_5.has_query_12 && query_12.has_8bit_w) - offset += fingers_supported; - - /* data 36 */ - if (query_0_5.has_bending_correction) - offset += 1; - - /* data 37 */ - if (query_0_5.has_query_27 && query_27.has_data_37) - offset += 1; - - /* data 38 */ - if (query_0_5.has_query_27 && query_27.has_wakeup_gesture) - extra_data->data38_offset = offset; - - 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; -} - -static int synaptics_rmi4_f12_ctrl_sub(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler, - struct synaptics_rmi4_f12_query_5 *query_5, - unsigned char ctrlreg, unsigned char subpacket) -{ - int retval; - unsigned char cnt; - unsigned char regnum; - unsigned char bitnum; - unsigned char q5_index; - unsigned char q6_index; - unsigned char offset; - unsigned char max_ctrlreg; - unsigned char *query_6; - - max_ctrlreg = (sizeof(query_5->data) - 1) * 8 - 1; - - if (ctrlreg > max_ctrlreg) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Control register number (%d) over limit\n", - __func__, ctrlreg); - return -EINVAL; - } - - q5_index = ctrlreg / 8 + 1; - bitnum = ctrlreg % 8; - if ((query_5->data[q5_index] & (1 << bitnum)) == 0x00) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Control %d is not present\n", - __func__, ctrlreg); - return -EINVAL; - } - - query_6 = kmalloc(query_5->size_of_query6, GFP_KERNEL); - if (!query_6) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for query 6\n", - __func__); - return -ENOMEM; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + 6, - query_6, - query_5->size_of_query6); - if (retval < 0) - goto exit; - - q6_index = 0; - - for (regnum = 0; regnum < ctrlreg; regnum++) { - q5_index = regnum / 8 + 1; - bitnum = regnum % 8; - if ((query_5->data[q5_index] & (1 << bitnum)) == 0x00) - continue; - - if (query_6[q6_index] == 0x00) - q6_index += 3; - else - q6_index++; - - while (query_6[q6_index] & ~MASK_7BIT) - q6_index++; - - q6_index++; - } - - cnt = 0; - q6_index++; - offset = subpacket / 7; - bitnum = subpacket % 7; - - do { - if (cnt == offset) { - if (query_6[q6_index + cnt] & (1 << bitnum)) - retval = 1; - else - retval = 0; - goto exit; - } - cnt++; - } while (query_6[q6_index + cnt - 1] & ~MASK_7BIT); - - retval = 0; - -exit: - kfree(query_6); - - return retval; -} - -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 = 0; - int temp; - unsigned char subpacket; - unsigned char ctrl_23_size; - unsigned char size_of_2d_data; - unsigned char size_of_query8; - unsigned char ctrl_8_offset; - unsigned char ctrl_20_offset; - unsigned char ctrl_23_offset; - unsigned char ctrl_28_offset; - unsigned char ctrl_31_offset; - unsigned char num_of_fingers; - struct synaptics_rmi4_f12_extra_data *extra_data; - struct synaptics_rmi4_f12_query_5 *query_5 = NULL; - struct synaptics_rmi4_f12_query_8 *query_8 = NULL; - struct synaptics_rmi4_f12_ctrl_8 *ctrl_8 = NULL; - struct synaptics_rmi4_f12_ctrl_23 *ctrl_23 = NULL; - struct synaptics_rmi4_f12_ctrl_31 *ctrl_31 = NULL; - 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); - if (!fhandler->extra) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for fhandler->extra\n", - __func__); - return -ENOMEM; - } - extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra; - size_of_2d_data = sizeof(struct synaptics_rmi4_f12_finger_data); - - query_5 = kmalloc(sizeof(*query_5), GFP_KERNEL); - if (!query_5) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for query_5\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - query_8 = kmalloc(sizeof(*query_8), GFP_KERNEL); - if (!query_8) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for query_8\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - ctrl_8 = kmalloc(sizeof(*ctrl_8), GFP_KERNEL); - if (!ctrl_8) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for ctrl_8\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - ctrl_23 = kmalloc(sizeof(*ctrl_23), GFP_KERNEL); - if (!ctrl_23) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for ctrl_23\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - ctrl_31 = kmalloc(sizeof(*ctrl_31), GFP_KERNEL); - if (!ctrl_31) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for ctrl_31\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + 5, - query_5->data, - sizeof(query_5->data)); - if (retval < 0) - goto exit; - - 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_20_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; - - ctrl_23_offset = ctrl_20_offset + - 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; - - ctrl_31_offset = ctrl_28_offset + - query_5->ctrl28_is_present + - query_5->ctrl29_is_present + - query_5->ctrl30_is_present; - - ctrl_23_size = 2; - for (subpacket = 2; subpacket <= 4; subpacket++) { - retval = synaptics_rmi4_f12_ctrl_sub(rmi4_data, - fhandler, query_5, 23, subpacket); - if (retval == 1) - ctrl_23_size++; - else if (retval < 0) - goto exit; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_23_offset, - ctrl_23->data, - ctrl_23_size); - if (retval < 0) - goto exit; - - /* Maximum number of fingers supported */ - fhandler->num_of_data_points = min_t(unsigned char, - 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; - - rmi4_data->stylus_enable = ctrl_23->stylus_enable; - rmi4_data->eraser_enable = ctrl_23->eraser_enable; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + 7, - &size_of_query8, - sizeof(size_of_query8)); - if (retval < 0) - goto exit; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + 8, - query_8->data, - size_of_query8); - if (retval < 0) - goto exit; - - /* 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; - } - -#ifdef REPORT_2D_PRESSURE - if ((size_of_query8 >= 4) && (query_8->data23_is_present)) { - extra_data->data23_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 + - query_8->data15_is_present + - query_8->data16_is_present + - query_8->data17_is_present + - query_8->data18_is_present + - query_8->data19_is_present + - query_8->data20_is_present + - query_8->data21_is_present + - query_8->data22_is_present; - extra_data->data23_size = num_of_fingers; - rmi4_data->report_pressure = true; - } else { - extra_data->data23_size = 0; - rmi4_data->report_pressure = false; - } -#endif - - 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) - goto exit; - - if (query_5->ctrl8_is_present) { - rmi4_data->wedge_sensor = false; - - 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) - goto exit; - - /* Maximum x and y */ - rmi4_data->sensor_max_x = - ((unsigned int)ctrl_8->max_x_coord_lsb << 0) | - ((unsigned int)ctrl_8->max_x_coord_msb << 8); - rmi4_data->sensor_max_y = - ((unsigned int)ctrl_8->max_y_coord_lsb << 0) | - ((unsigned int)ctrl_8->max_y_coord_msb << 8); - - rmi4_data->max_touch_width = MAX_F12_TOUCH_WIDTH; - } else { - rmi4_data->wedge_sensor = true; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.ctrl_base + ctrl_31_offset, - ctrl_31->data, - sizeof(ctrl_31->data)); - if (retval < 0) - goto exit; - - /* Maximum x and y */ - rmi4_data->sensor_max_x = - ((unsigned int)ctrl_31->max_x_coord_lsb << 0) | - ((unsigned int)ctrl_31->max_x_coord_msb << 8); - rmi4_data->sensor_max_y = - ((unsigned int)ctrl_31->max_y_coord_lsb << 0) | - ((unsigned int)ctrl_31->max_y_coord_msb << 8); - - rmi4_data->max_touch_width = MAX_F12_TOUCH_WIDTH; - } - - 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); - - if (bdata->swap_axes) { - temp = rmi4_data->sensor_max_x; - rmi4_data->sensor_max_x = rmi4_data->sensor_max_y; - rmi4_data->sensor_max_y = temp; - } - - rmi4_data->f12_wakeup_gesture = query_5->ctrl27_is_present; - if (rmi4_data->f12_wakeup_gesture) { - extra_data->ctrl20_offset = ctrl_20_offset; - extra_data->data4_offset = query_8->data0_is_present + - query_8->data1_is_present + - query_8->data2_is_present + - query_8->data3_is_present; - } - - 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); - if (!fhandler->data) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for fhandler->data\n", - __func__); - retval = -ENOMEM; - goto exit; - } - -exit: - kfree(query_5); - kfree(query_8); - kfree(ctrl_8); - kfree(ctrl_23); - kfree(ctrl_31); - - 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 offset = 0; - struct synaptics_rmi4_f1a_query_4 query_4; - struct synaptics_rmi4_f1a_handle *f1a = fhandler->data; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - 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 + offset, - f1a->button_control.txrx_map, - f1a->max_count * 2); - 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 (f1a->button_query.has_query4) { - offset = 2 + f1a->button_query.has_query2 + - f1a->button_query.has_query3; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.query_base + offset, - query_4.data, - sizeof(query_4.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read button features 4\n", - __func__); - return retval; - } - - if (query_4.has_ctrl24) - rmi4_data->external_afe_buttons = true; - else - rmi4_data->external_afe_buttons = false; - } - - if (!bdata->cap_button_map) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: cap_button_map is NULL in board file\n", - __func__); - return -ENODEV; - } else if (!bdata->cap_button_map->map) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Button map is missing in board file\n", - __func__); - return -ENODEV; - } 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; - struct synaptics_rmi4_f01_device_status status; - - 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 -EINVAL; - - 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; - } - - 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; -} - -static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char page_number; - unsigned char intr_count; - unsigned char *f01_query; - unsigned short pdt_entry_addr; - bool f01found; - bool f35found; - bool was_in_bl_mode; - struct synaptics_rmi4_fn_desc rmi_fd; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - -rescan_pdt: - f01found = false; - f35found = 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; - case SYNAPTICS_RMI4_F35: - f35found = true; - break; - } - - /* Accumulate the interrupt count */ - intr_count += rmi_fd.intr_src_count; - - 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__); - if (!f35found) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F35\n", - __func__); - return -EINVAL; - } else { - pr_notice("%s: In microbootloader mode\n", - __func__); - return 0; - } - } - -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); - - f01_query = kmalloc(F01_STD_QUERY_LEN, GFP_KERNEL); - if (!f01_query) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for f01_query\n", - __func__); - return -ENOMEM; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_query_base_addr, - f01_query, - F01_STD_QUERY_LEN); - if (retval < 0) { - kfree(f01_query); - 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]; - rmi->product_info[1] = f01_query[3]; - retval = secure_memcpy(rmi->product_id_string, - sizeof(rmi->product_id_string), - &f01_query[11], - F01_STD_QUERY_LEN - 11, - PRODUCT_ID_SIZE); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy product ID string\n", - __func__); - } - - kfree(f01_query); - - 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_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; - } - } - } - - if (rmi4_data->f11_wakeup_gesture || rmi4_data->f12_wakeup_gesture) - rmi4_data->enable_wakeup_gesture = WAKEUP_GESTURE; - else - rmi4_data->enable_wakeup_gesture = false; - - synaptics_rmi4_set_configured(rmi4_data); - - return 0; -} - -static int synaptics_rmi4_gpio_setup(int gpio, bool config, int dir, int state) -{ - int retval = 0; - unsigned char buf[16]; - - if (config) { - retval = snprintf(buf, ARRAY_SIZE(buf), "dsx_gpio_%u\n", gpio); - if (retval >= 16) - return -EINVAL; - - retval = gpio_request(gpio, buf); - if (retval) { - pr_err("%s: Failed to get gpio %d (code: %d)", - __func__, gpio, retval); - return retval; - } - - if (dir == 0) - retval = gpio_direction_input(gpio); - else - retval = gpio_direction_output(gpio, state); - if (retval) { - pr_err("%s: Failed to set gpio %d direction", - __func__, gpio); - return retval; - } - } else { - gpio_free(gpio); - } - - return retval; -} - -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; - - rmi = &(rmi4_data->rmi4_mod_info); - - 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 REPORT_2D_PRESSURE - if (rmi4_data->report_pressure) { - input_set_abs_params(rmi4_data->input_dev, - ABS_MT_PRESSURE, 0, - MAX_F12_TOUCH_PRESSURE, 0, 0); - } -#endif - -#ifdef TYPE_B_PROTOCOL -#ifdef KERNEL_ABOVE_3_6 - input_mt_init_slots(rmi4_data->input_dev, - rmi4_data->num_of_fingers, INPUT_MT_DIRECT); -#else - input_mt_init_slots(rmi4_data->input_dev, - rmi4_data->num_of_fingers); -#endif -#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]); - } - } - - if (vir_button_map->nbuttons) { - for (ii = 0; ii < vir_button_map->nbuttons; ii++) { - set_bit(vir_button_map->map[ii * 5], - rmi4_data->input_dev->keybit); - input_set_capability(rmi4_data->input_dev, - EV_KEY, vir_button_map->map[ii * 5]); - } - } - - if (rmi4_data->f11_wakeup_gesture || rmi4_data->f12_wakeup_gesture) { - set_bit(KEY_WAKEUP, rmi4_data->input_dev->keybit); - input_set_capability(rmi4_data->input_dev, EV_KEY, KEY_WAKEUP); - } - - return; -} - -static int synaptics_rmi4_set_input_dev(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - 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; - } - - 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 (bdata->max_y_for_2d >= 0) - rmi4_data->sensor_max_y = bdata->max_y_for_2d; - - 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; - } - - if (!rmi4_data->stylus_enable) - return 0; - - rmi4_data->stylus_dev = input_allocate_device(); - if (rmi4_data->stylus_dev == NULL) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate stylus device\n", - __func__); - retval = -ENOMEM; - goto err_stylus_device; - } - - rmi4_data->stylus_dev->name = STYLUS_DRIVER_NAME; - rmi4_data->stylus_dev->phys = STYLUS_PHYS_NAME; - rmi4_data->stylus_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; - rmi4_data->stylus_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; - rmi4_data->stylus_dev->dev.parent = rmi4_data->pdev->dev.parent; - input_set_drvdata(rmi4_data->stylus_dev, rmi4_data); - - set_bit(EV_KEY, rmi4_data->stylus_dev->evbit); - set_bit(EV_ABS, rmi4_data->stylus_dev->evbit); - set_bit(BTN_TOUCH, rmi4_data->stylus_dev->keybit); - set_bit(BTN_TOOL_PEN, rmi4_data->stylus_dev->keybit); - if (rmi4_data->eraser_enable) - set_bit(BTN_TOOL_RUBBER, rmi4_data->stylus_dev->keybit); -#ifdef INPUT_PROP_DIRECT - set_bit(INPUT_PROP_DIRECT, rmi4_data->stylus_dev->propbit); -#endif - - input_set_abs_params(rmi4_data->stylus_dev, ABS_X, 0, - rmi4_data->sensor_max_x, 0, 0); - input_set_abs_params(rmi4_data->stylus_dev, ABS_Y, 0, - rmi4_data->sensor_max_y, 0, 0); - - retval = input_register_device(rmi4_data->stylus_dev); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to register stylus device\n", - __func__); - goto err_register_stylus; - } - - return 0; - -err_register_stylus: - rmi4_data->stylus_dev = NULL; - -err_stylus_device: - input_unregister_device(rmi4_data->input_dev); - rmi4_data->input_dev = NULL; - -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; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - retval = synaptics_rmi4_gpio_setup( - 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 = synaptics_rmi4_gpio_setup( - bdata->power_gpio, - true, 1, !bdata->power_on_state); - 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 = synaptics_rmi4_gpio_setup( - bdata->reset_gpio, - true, 1, !bdata->reset_on_state); - 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, bdata->power_on_state); - msleep(bdata->power_delay_ms); - } - - if (bdata->reset_gpio >= 0) { - gpio_set_value(bdata->reset_gpio, bdata->reset_on_state); - msleep(bdata->reset_active_ms); - gpio_set_value(bdata->reset_gpio, !bdata->reset_on_state); - msleep(bdata->reset_delay_ms); - } - - return 0; - -err_gpio_reset: - if (bdata->power_gpio >= 0) - synaptics_rmi4_gpio_setup(bdata->power_gpio, false, 0, 0); - -err_gpio_power: - synaptics_rmi4_gpio_setup(bdata->irq_gpio, false, 0, 0); - -err_gpio_irq: - return retval; -} - -static int synaptics_rmi4_get_reg(struct synaptics_rmi4_data *rmi4_data, - bool get) -{ - int retval; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - if (!get) { - retval = 0; - goto regulator_put; - } - - if ((bdata->pwr_reg_name != NULL) && (*bdata->pwr_reg_name != 0)) { - rmi4_data->pwr_reg = regulator_get(rmi4_data->pdev->dev.parent, - bdata->pwr_reg_name); - if (IS_ERR(rmi4_data->pwr_reg)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to get power regulator\n", - __func__); - retval = PTR_ERR(rmi4_data->pwr_reg); - goto regulator_put; - } - } - - if ((bdata->bus_reg_name != NULL) && (*bdata->bus_reg_name != 0)) { - rmi4_data->bus_reg = regulator_get(rmi4_data->pdev->dev.parent, - bdata->bus_reg_name); - if (IS_ERR(rmi4_data->bus_reg)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to get bus pullup regulator\n", - __func__); - retval = PTR_ERR(rmi4_data->bus_reg); - goto regulator_put; - } - } - - return 0; - -regulator_put: - if (rmi4_data->pwr_reg) { - regulator_put(rmi4_data->pwr_reg); - rmi4_data->pwr_reg = NULL; - } - - if (rmi4_data->bus_reg) { - regulator_put(rmi4_data->bus_reg); - rmi4_data->bus_reg = NULL; - } - - return retval; -} - -static int synaptics_rmi4_enable_reg(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - int retval; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - if (!enable) { - retval = 0; - goto disable_pwr_reg; - } - - if (rmi4_data->bus_reg) { - retval = regulator_enable(rmi4_data->bus_reg); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to enable bus pullup regulator\n", - __func__); - goto exit; - } - } - - if (rmi4_data->pwr_reg) { - retval = regulator_enable(rmi4_data->pwr_reg); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to enable power regulator\n", - __func__); - goto disable_bus_reg; - } - msleep(bdata->power_delay_ms); - } - - return 0; - -disable_pwr_reg: - if (rmi4_data->pwr_reg) - regulator_disable(rmi4_data->pwr_reg); - -disable_bus_reg: - if (rmi4_data->bus_reg) - regulator_disable(rmi4_data->bus_reg); - -exit: - return retval; -} - -static int synaptics_rmi4_free_fingers(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char ii; - - mutex_lock(&(rmi4_data->rmi4_report_mutex)); - -#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); - - if (rmi4_data->stylus_enable) { - input_report_key(rmi4_data->stylus_dev, - BTN_TOUCH, 0); - input_report_key(rmi4_data->stylus_dev, - BTN_TOOL_PEN, 0); - if (rmi4_data->eraser_enable) { - input_report_key(rmi4_data->stylus_dev, - BTN_TOOL_RUBBER, 0); - } - input_sync(rmi4_data->stylus_dev); - } - - mutex_unlock(&(rmi4_data->rmi4_report_mutex)); - - rmi4_data->fingers_on_2d = false; - - return 0; -} - -static int synaptics_rmi4_sw_reset(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char command = 0x01; - - 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); - - if (rmi4_data->hw_if->ui_hw_init) { - retval = rmi4_data->hw_if->ui_hw_init(rmi4_data); - if (retval < 0) - return retval; - } - - return 0; -} - -static void synaptics_rmi4_rebuild_work(struct work_struct *work) -{ - int retval; - unsigned char attr_count; - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct synaptics_rmi4_data *rmi4_data = - container_of(delayed_work, struct synaptics_rmi4_data, - rb_work); - - mutex_lock(&(rmi4_data->rmi4_reset_mutex)); - - mutex_lock(&exp_data.mutex); - - synaptics_rmi4_irq_enable(rmi4_data, false, false); - - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) - if (exp_fhandler->exp_fn->remove != NULL) - exp_fhandler->exp_fn->remove(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); - } - - synaptics_rmi4_free_fingers(rmi4_data); - synaptics_rmi4_empty_fn_list(rmi4_data); - input_unregister_device(rmi4_data->input_dev); - rmi4_data->input_dev = NULL; - if (rmi4_data->stylus_enable) { - input_unregister_device(rmi4_data->stylus_dev); - rmi4_data->stylus_dev = NULL; - } - - retval = synaptics_rmi4_sw_reset(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue reset command\n", - __func__); - goto exit; - } - - retval = synaptics_rmi4_set_input_dev(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set up input device\n", - __func__); - goto exit; - } - - 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; - } - } - - if (!list_empty(&exp_data.list)) { - list_for_each_entry(exp_fhandler, &exp_data.list, link) - if (exp_fhandler->exp_fn->init != NULL) - exp_fhandler->exp_fn->init(rmi4_data); - } - - retval = 0; - -exit: - synaptics_rmi4_irq_enable(rmi4_data, true, false); - - mutex_unlock(&exp_data.mutex); - - mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); - - return; -} - -static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data, - bool rebuild) -{ - int retval; - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - - if (rebuild) { - queue_delayed_work(rmi4_data->rb_workqueue, - &rmi4_data->rb_work, - msecs_to_jiffies(REBUILD_WORK_DELAY_MS)); - return 0; - } - - mutex_lock(&(rmi4_data->rmi4_reset_mutex)); - - synaptics_rmi4_irq_enable(rmi4_data, false, false); - - retval = synaptics_rmi4_sw_reset(rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue reset command\n", - __func__); - goto exit; - } - - 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__); - 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->reset != NULL) - exp_fhandler->exp_fn->reset(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - retval = 0; - -exit: - synaptics_rmi4_irq_enable(rmi4_data, true, false); - - mutex_unlock(&(rmi4_data->rmi4_reset_mutex)); - - return retval; -} - -#ifdef FB_READY_RESET -static void synaptics_rmi4_reset_work(struct work_struct *work) -{ - int retval; - unsigned int timeout; - struct synaptics_rmi4_data *rmi4_data = - container_of(work, struct synaptics_rmi4_data, - reset_work); - - timeout = FB_READY_TIMEOUT_S * 1000 / FB_READY_WAIT_MS + 1; - - while (!rmi4_data->fb_ready) { - msleep(FB_READY_WAIT_MS); - timeout--; - if (timeout == 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Timed out waiting for FB ready\n", - __func__); - return; - } - } - - mutex_lock(&rmi4_data->rmi4_exp_init_mutex); - - retval = synaptics_rmi4_reset_device(rmi4_data, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue reset command\n", - __func__); - } - - mutex_unlock(&rmi4_data->rmi4_exp_init_mutex); - - return; -} -#endif - -static void synaptics_rmi4_sleep_enable(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - 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 read device control\n", - __func__); - return; - } - - device_ctrl = device_ctrl & ~MASK_3BIT; - if (enable) - device_ctrl = device_ctrl | NO_SLEEP_OFF | SENSOR_SLEEP; - else - 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 write device control\n", - __func__); - return; - } - - rmi4_data->sensor_sleep = enable; - - return; -} - -static void synaptics_rmi4_exp_fn_work(struct work_struct *work) -{ - 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(&rmi4_data->rmi4_exp_init_mutex); - mutex_lock(&rmi4_data->rmi4_reset_mutex); - 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) { - exp_fhandler->exp_fn->init(rmi4_data); - 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); - mutex_unlock(&rmi4_data->rmi4_reset_mutex); - mutex_unlock(&rmi4_data->rmi4_exp_init_mutex); - - return; -} - -void synaptics_rmi4_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_new_function); - -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)) { - retval = PTR_ERR(rmi4_data->ts_pinctrl); - dev_err(rmi4_data->pdev->dev.parent, - "Target does not use pinctrl %d\n", retval); - goto err_pinctrl_get; - } - - rmi4_data->pinctrl_state_active - = pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_active"); - if (IS_ERR_OR_NULL(rmi4_data->pinctrl_state_active)) { - retval = PTR_ERR(rmi4_data->pinctrl_state_active); - dev_err(rmi4_data->pdev->dev.parent, - "Can not lookup %s pinstate %d\n", - PINCTRL_STATE_ACTIVE, retval); - goto err_pinctrl_lookup; - } - - rmi4_data->pinctrl_state_suspend - = pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_suspend"); - if (IS_ERR_OR_NULL(rmi4_data->pinctrl_state_suspend)) { - retval = PTR_ERR(rmi4_data->pinctrl_state_suspend); - dev_dbg(rmi4_data->pdev->dev.parent, - "Can not lookup %s pinstate %d\n", - PINCTRL_STATE_SUSPEND, retval); - goto err_pinctrl_lookup; - } - - rmi4_data->pinctrl_state_release - = pinctrl_lookup_state(rmi4_data->ts_pinctrl, "pmx_ts_release"); - if (IS_ERR_OR_NULL(rmi4_data->pinctrl_state_release)) { - retval = PTR_ERR(rmi4_data->pinctrl_state_release); - dev_dbg(rmi4_data->pdev->dev.parent, - "Can not lookup %s pinstate %d\n", - PINCTRL_STATE_RELEASE, retval); - } - - return 0; - -err_pinctrl_lookup: - devm_pinctrl_put(rmi4_data->ts_pinctrl); -err_pinctrl_get: - rmi4_data->ts_pinctrl = NULL; - return retval; -} - -static int synaptics_rmi4_probe(struct platform_device *pdev) -{ - int retval; - 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; - - 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->suspend = false; - rmi4_data->irq_enabled = false; - rmi4_data->fingers_on_2d = false; - - rmi4_data->reset_device = synaptics_rmi4_reset_device; - rmi4_data->irq_enable = synaptics_rmi4_irq_enable; - rmi4_data->sleep_enable = synaptics_rmi4_sleep_enable; - rmi4_data->report_touch = synaptics_rmi4_report_touch; - - mutex_init(&(rmi4_data->rmi4_reset_mutex)); - mutex_init(&(rmi4_data->rmi4_report_mutex)); - mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex)); - mutex_init(&(rmi4_data->rmi4_exp_init_mutex)); - - platform_set_drvdata(pdev, rmi4_data); - - vir_button_map = bdata->vir_button_map; - - retval = synaptics_rmi4_get_reg(rmi4_data, true); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to get regulators\n", - __func__); - goto err_get_reg; - } - - retval = synaptics_rmi4_enable_reg(rmi4_data, true); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to enable regulators\n", - __func__); - goto err_enable_reg; - } - - retval = synaptics_dsx_pinctrl_init(rmi4_data); - if (!retval && rmi4_data->ts_pinctrl) { - /* - * Pinctrl handle is optional. If pinctrl handle is found - * let pins to be configured in active state. If not - * found continue further without error. - */ - retval = pinctrl_select_state(rmi4_data->ts_pinctrl, - rmi4_data->pinctrl_state_active); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to select %s pinstate %d\n", - __func__, PINCTRL_STATE_ACTIVE, retval); - } - } - 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; - } - - if (hw_if->ui_hw_init) { - retval = hw_if->ui_hw_init(rmi4_data); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to initialize hardware interface\n", - __func__); - goto err_ui_hw_init; - } - } - - 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 - INIT_WORK(&rmi4_data->fb_notify_work, - synaptics_rmi4_fb_notify_resume_work); - rmi4_data->fb_notifier.notifier_call = synaptics_rmi4_fb_notifier_cb; - retval = fb_register_client(&rmi4_data->fb_notifier); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to register fb notifier client\n", - __func__); - } -#endif - -#ifdef USE_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 - - if (!exp_data.initialized) { - mutex_init(&exp_data.mutex); - INIT_LIST_HEAD(&exp_data.list); - exp_data.initialized = true; - } - - rmi4_data->irq = gpio_to_irq(bdata->irq_gpio); - - retval = synaptics_rmi4_irq_enable(rmi4_data, true, false); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to enable attention interrupt\n", - __func__); - goto err_enable_irq; - } - - if (vir_button_map->nbuttons) { - rmi4_data->board_prop_dir = kobject_create_and_add( - "board_properties", NULL); - if (!rmi4_data->board_prop_dir) { - dev_err(&pdev->dev, - "%s: Failed to create board_properties directory\n", - __func__); - goto err_virtual_buttons; - } else { - retval = sysfs_create_file(rmi4_data->board_prop_dir, - &virtual_key_map_attr.attr); - if (retval < 0) { - dev_err(&pdev->dev, - "%s: Failed to create virtual key map file\n", - __func__); - goto err_virtual_buttons; - } - } - } - - 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; - } - } - - rmi4_data->rb_workqueue = - create_singlethread_workqueue("dsx_rebuild_workqueue"); - if (!rmi4_data->rb_workqueue) { - retval = -ENOMEM; - goto err_rb_workqueue; - } - INIT_DELAYED_WORK(&rmi4_data->rb_work, synaptics_rmi4_rebuild_work); - - exp_data.workqueue = create_singlethread_workqueue("dsx_exp_workqueue"); - if (!exp_data.workqueue) { - retval = -ENOMEM; - goto err_exp_data_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, 0); - -#ifdef FB_READY_RESET - rmi4_data->reset_workqueue = - create_singlethread_workqueue("dsx_reset_workqueue"); - if (!rmi4_data->reset_workqueue) { - retval = -ENOMEM; - goto err_reset_workqueue; - } - INIT_WORK(&rmi4_data->reset_work, synaptics_rmi4_reset_work); - queue_work(rmi4_data->reset_workqueue, &rmi4_data->reset_work); -#endif - - /* Initialize secure touch */ - synaptics_secure_touch_init(rmi4_data); - synaptics_secure_touch_stop(rmi4_data, true); - - return retval; - -#ifdef FB_READY_RESET -err_reset_workqueue: -#endif - cancel_delayed_work_sync(&exp_data.work); - flush_workqueue(exp_data.workqueue); - destroy_workqueue(exp_data.workqueue); - -err_exp_data_workqueue: - cancel_delayed_work_sync(&rmi4_data->rb_work); - flush_workqueue(rmi4_data->rb_workqueue); - destroy_workqueue(rmi4_data->rb_workqueue); - -err_rb_workqueue: -err_sysfs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - -err_virtual_buttons: - if (rmi4_data->board_prop_dir) { - sysfs_remove_file(rmi4_data->board_prop_dir, - &virtual_key_map_attr.attr); - kobject_put(rmi4_data->board_prop_dir); - } - - synaptics_rmi4_irq_enable(rmi4_data, false, false); - -err_enable_irq: -#ifdef CONFIG_FB - fb_unregister_client(&rmi4_data->fb_notifier); -#endif - -#ifdef USE_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 (rmi4_data->stylus_enable) { - input_unregister_device(rmi4_data->stylus_dev); - rmi4_data->stylus_dev = NULL; - } - -err_set_input_dev: - synaptics_rmi4_gpio_setup(bdata->irq_gpio, false, 0, 0); - - if (bdata->reset_gpio >= 0) - synaptics_rmi4_gpio_setup(bdata->reset_gpio, false, 0, 0); - - if (bdata->power_gpio >= 0) - synaptics_rmi4_gpio_setup(bdata->power_gpio, false, 0, 0); - -err_ui_hw_init: -err_set_gpio: - synaptics_rmi4_enable_reg(rmi4_data, false); - - if (rmi4_data->ts_pinctrl) { - if (IS_ERR_OR_NULL(rmi4_data->pinctrl_state_release)) { - devm_pinctrl_put(rmi4_data->ts_pinctrl); - rmi4_data->ts_pinctrl = NULL; - } else { - retval = pinctrl_select_state( - rmi4_data->ts_pinctrl, - rmi4_data->pinctrl_state_release); - if (retval) - dev_err(&pdev->dev, - "%s: Failed to create sysfs attributes\n", - __func__); - } - } - -err_enable_reg: - synaptics_rmi4_get_reg(rmi4_data, false); - -err_get_reg: - kfree(rmi4_data); - - return retval; -} - -static int synaptics_rmi4_remove(struct platform_device *pdev) -{ - unsigned char attr_count; - int err; - struct synaptics_rmi4_data *rmi4_data = platform_get_drvdata(pdev); - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - -#ifdef FB_READY_RESET - cancel_work_sync(&rmi4_data->reset_work); - flush_workqueue(rmi4_data->reset_workqueue); - destroy_workqueue(rmi4_data->reset_workqueue); -#endif - - cancel_delayed_work_sync(&exp_data.work); - flush_workqueue(exp_data.workqueue); - destroy_workqueue(exp_data.workqueue); - - cancel_delayed_work_sync(&rmi4_data->rb_work); - flush_workqueue(rmi4_data->rb_workqueue); - destroy_workqueue(rmi4_data->rb_workqueue); - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - if (rmi4_data->board_prop_dir) { - sysfs_remove_file(rmi4_data->board_prop_dir, - &virtual_key_map_attr.attr); - kobject_put(rmi4_data->board_prop_dir); - } - - synaptics_rmi4_irq_enable(rmi4_data, false, false); - -#ifdef CONFIG_FB - fb_unregister_client(&rmi4_data->fb_notifier); -#endif - -#ifdef USE_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 (rmi4_data->stylus_enable) { - input_unregister_device(rmi4_data->stylus_dev); - rmi4_data->stylus_dev = NULL; - } - - synaptics_rmi4_gpio_setup(bdata->irq_gpio, false, 0, 0); - - if (bdata->reset_gpio >= 0) - synaptics_rmi4_gpio_setup(bdata->reset_gpio, false, 0, 0); - - if (bdata->power_gpio >= 0) - synaptics_rmi4_gpio_setup(bdata->power_gpio, false, 0, 0); - - - if (rmi4_data->ts_pinctrl) { - if (IS_ERR_OR_NULL(rmi4_data->pinctrl_state_release)) { - devm_pinctrl_put(rmi4_data->ts_pinctrl); - rmi4_data->ts_pinctrl = NULL; - } else { - err = pinctrl_select_state( - rmi4_data->ts_pinctrl, - rmi4_data->pinctrl_state_release); - if (err) - dev_err(&pdev->dev, - "Failed to select release pinctrl state %d\n", - err); - } - } - - synaptics_rmi4_enable_reg(rmi4_data, false); - synaptics_rmi4_get_reg(rmi4_data, false); - - kfree(rmi4_data); - - return 0; -} - -static void synaptics_rmi4_f11_wg(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - int retval; - unsigned char reporting_control; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F11) - break; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.ctrl_base, - &reporting_control, - sizeof(reporting_control)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to change reporting mode\n", - __func__); - return; - } - - reporting_control = (reporting_control & ~MASK_3BIT); - if (enable) - reporting_control |= F11_WAKEUP_GESTURE_MODE; - else - reporting_control |= F11_CONTINUOUS_MODE; - - retval = synaptics_rmi4_reg_write(rmi4_data, - fhandler->full_addr.ctrl_base, - &reporting_control, - sizeof(reporting_control)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to change reporting mode\n", - __func__); - return; - } - - return; -} - -static void synaptics_rmi4_f12_wg(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - int retval; - unsigned char offset; - unsigned char reporting_control[3]; - struct synaptics_rmi4_f12_extra_data *extra_data; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_device_info *rmi; - - rmi = &(rmi4_data->rmi4_mod_info); - - list_for_each_entry(fhandler, &rmi->support_fn_list, link) { - if (fhandler->fn_number == SYNAPTICS_RMI4_F12) - break; - } - - extra_data = (struct synaptics_rmi4_f12_extra_data *)fhandler->extra; - offset = extra_data->ctrl20_offset; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fhandler->full_addr.ctrl_base + offset, - reporting_control, - sizeof(reporting_control)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to change reporting mode\n", - __func__); - return; - } - - if (enable) - reporting_control[2] = F12_WAKEUP_GESTURE_MODE; - else - reporting_control[2] = F12_CONTINUOUS_MODE; - - retval = synaptics_rmi4_reg_write(rmi4_data, - fhandler->full_addr.ctrl_base + offset, - reporting_control, - sizeof(reporting_control)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to change reporting mode\n", - __func__); - return; - } - - return; -} - -static void synaptics_rmi4_wakeup_gesture(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - if (rmi4_data->f11_wakeup_gesture) - synaptics_rmi4_f11_wg(rmi4_data, enable); - else if (rmi4_data->f12_wakeup_gesture) - synaptics_rmi4_f12_wg(rmi4_data, enable); - - return; -} - -#ifdef CONFIG_FB -static void synaptics_rmi4_fb_notify_resume_work(struct work_struct *work) -{ - struct synaptics_rmi4_data *rmi4_data = - container_of(work, struct synaptics_rmi4_data, fb_notify_work); - synaptics_rmi4_resume(&(rmi4_data->input_dev->dev)); - rmi4_data->fb_ready = true; -} - -static int synaptics_rmi4_fb_notifier_cb(struct notifier_block *self, - unsigned long event, void *data) -{ - int *transition; - struct fb_event *evdata = data; - struct synaptics_rmi4_data *rmi4_data = - container_of(self, struct synaptics_rmi4_data, - fb_notifier); - - if (evdata && evdata->data && rmi4_data) { - if (rmi4_data->hw_if->board_data->resume_in_workqueue) { - if (event == FB_EARLY_EVENT_BLANK) { - synaptics_secure_touch_stop(rmi4_data, false); - } else if (event == FB_EVENT_BLANK) { - transition = evdata->data; - if (*transition == FB_BLANK_POWERDOWN) { - flush_work( - &(rmi4_data->fb_notify_work)); - synaptics_rmi4_suspend( - &rmi4_data->pdev->dev); - rmi4_data->fb_ready = false; - } else if (*transition == FB_BLANK_UNBLANK) { - schedule_work( - &(rmi4_data->fb_notify_work)); - } - } - } else { - if (event == FB_EARLY_EVENT_BLANK) { - synaptics_secure_touch_stop(rmi4_data, false); - } else if (event == FB_EVENT_BLANK) { - transition = evdata->data; - if (*transition == FB_BLANK_POWERDOWN) { - synaptics_rmi4_suspend( - &rmi4_data->pdev->dev); - rmi4_data->fb_ready = false; - } else if (*transition == FB_BLANK_UNBLANK) { - synaptics_rmi4_resume( - &rmi4_data->pdev->dev); - rmi4_data->fb_ready = true; - } - } - } - } - - return 0; -} -#endif - -#ifdef USE_EARLYSUSPEND -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) - return; - - /* - * During early suspend/late resume, the driver doesn't access xPU/SMMU - * protected HW resources. So, there is no compelling need to block, - * but notifying the userspace that a power event has occurred is - * enough. Hence 'blocking' variable can be set to false. - */ - synaptics_secure_touch_stop(rmi4_data, false); - - if (rmi4_data->enable_wakeup_gesture) { - synaptics_rmi4_wakeup_gesture(rmi4_data, true); - enable_irq_wake(rmi4_data->irq); - goto exit; - } - - synaptics_rmi4_irq_enable(rmi4_data, false, false); - synaptics_rmi4_sleep_enable(rmi4_data, true); - synaptics_rmi4_free_fingers(rmi4_data); - -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->early_suspend != NULL) - exp_fhandler->exp_fn->early_suspend(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - rmi4_data->suspend = true; - - return; -} - -static void synaptics_rmi4_late_resume(struct early_suspend *h) -{ -#ifdef FB_READY_RESET - int retval; -#endif - 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) - return; - - synaptics_secure_touch_stop(rmi4_data, false); - - if (rmi4_data->enable_wakeup_gesture) { - synaptics_rmi4_wakeup_gesture(rmi4_data, false); - disable_irq_wake(rmi4_data->irq); - goto exit; - } - - rmi4_data->current_page = MASK_8BIT; - - if (rmi4_data->suspend) { - synaptics_rmi4_sleep_enable(rmi4_data, false); - synaptics_rmi4_irq_enable(rmi4_data, true, false); - } - -exit: -#ifdef FB_READY_RESET - if (rmi4_data->suspend) { - retval = synaptics_rmi4_reset_device(rmi4_data, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue reset command\n", - __func__); - } - } -#endif - 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->suspend = false; - - return; -} -#endif - -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); - int retval; - - if (rmi4_data->stay_awake) - return 0; - - synaptics_secure_touch_stop(rmi4_data, true); - - if (rmi4_data->enable_wakeup_gesture) { - synaptics_rmi4_wakeup_gesture(rmi4_data, true); - enable_irq_wake(rmi4_data->irq); - goto exit; - } - - if (!rmi4_data->suspend) { - synaptics_rmi4_irq_enable(rmi4_data, false, false); - synaptics_rmi4_sleep_enable(rmi4_data, true); - synaptics_rmi4_free_fingers(rmi4_data); - } - - if (rmi4_data->ts_pinctrl) { - retval = pinctrl_select_state(rmi4_data->ts_pinctrl, - rmi4_data->pinctrl_state_suspend); - if (retval < 0) - dev_err(dev, "Cannot get idle pinctrl state\n"); - goto err_pinctrl; - } -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->suspend != NULL) - exp_fhandler->exp_fn->suspend(rmi4_data); - } - mutex_unlock(&exp_data.mutex); - - if (!rmi4_data->suspend) { - synaptics_rmi4_enable_reg(rmi4_data, false); - synaptics_rmi4_get_reg(rmi4_data, false); - } - rmi4_data->suspend = true; - - return 0; - -err_pinctrl: - synaptics_rmi4_sleep_enable(rmi4_data, false); - synaptics_rmi4_irq_enable(rmi4_data, true, false); - return retval; - -} - -static int synaptics_rmi4_resume(struct device *dev) -{ -#ifdef FB_READY_RESET - int retval; -#endif - struct synaptics_rmi4_exp_fhandler *exp_fhandler; - struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - - if (rmi4_data->stay_awake) - return 0; - - synaptics_secure_touch_stop(rmi4_data, true); - - if (rmi4_data->enable_wakeup_gesture) { - synaptics_rmi4_wakeup_gesture(rmi4_data, false); - disable_irq_wake(rmi4_data->irq); - goto exit; - } - - rmi4_data->current_page = MASK_8BIT; - - if (rmi4_data->suspend) { - synaptics_rmi4_get_reg(rmi4_data, true); - synaptics_rmi4_enable_reg(rmi4_data, true); - } - - synaptics_rmi4_sleep_enable(rmi4_data, false); - synaptics_rmi4_irq_enable(rmi4_data, true, false); - if (rmi4_data->ts_pinctrl) { - retval = pinctrl_select_state(rmi4_data->ts_pinctrl, - rmi4_data->pinctrl_state_active); - if (retval < 0) - dev_err(dev, "Cannot get default pinctrl state\n"); - } - -exit: -#ifdef FB_READY_RESET - retval = synaptics_rmi4_reset_device(rmi4_data, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue reset command\n", - __func__); - } -#endif - 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->suspend = false; - - return 0; -} - -#ifdef CONFIG_PM -static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = { -#ifndef CONFIG_FB - .suspend = synaptics_rmi4_suspend, - .resume = synaptics_rmi4_resume, -#endif -}; -#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, -}; - -static int __init synaptics_rmi4_init(void) -{ - int retval; - - retval = synaptics_rmi4_bus_init_v26(); - if (retval) - return retval; - - return platform_driver_register(&synaptics_rmi4_driver); -} - -static void __exit synaptics_rmi4_exit(void) -{ - platform_driver_unregister(&synaptics_rmi4_driver); - - synaptics_rmi4_bus_exit_v26(); - - return; -} - -module_init(synaptics_rmi4_init); -module_exit(synaptics_rmi4_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX Touch Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.h b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.h deleted file mode 100644 index 7d92791afb25..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * Copyright (C) 2016 The Linux Foundation. All rights reserved. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#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 0x2061 - -#include -#ifdef CONFIG_FB -#include -#include -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - -#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26) -#include -#include -#include -#include -#endif - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)) -#define KERNEL_ABOVE_2_6_38 -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) -#define KERNEL_ABOVE_3_6 -#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_F35 (0x35) -#define SYNAPTICS_RMI4_F38 (0x38) -#define SYNAPTICS_RMI4_F51 (0x51) -#define SYNAPTICS_RMI4_F54 (0x54) -#define SYNAPTICS_RMI4_F55 (0x55) -#define SYNAPTICS_RMI4_FDB (0xDB) - -#define PRODUCT_INFO_SIZE 2 -#define PRODUCT_ID_SIZE 10 -#define BUILD_ID_SIZE 3 - -#define F12_FINGERS_TO_SUPPORT 10 -#define F12_NO_OBJECT_STATUS 0x00 -#define F12_FINGER_STATUS 0x01 -#define F12_ACTIVE_STYLUS_STATUS 0x02 -#define F12_PALM_STATUS 0x03 -#define F12_HOVERING_FINGER_STATUS 0x05 -#define F12_GLOVED_FINGER_STATUS 0x06 -#define F12_NARROW_OBJECT_STATUS 0x07 -#define F12_HAND_EDGE_STATUS 0x08 -#define F12_COVER_STATUS 0x0A -#define F12_STYLUS_STATUS 0x0B -#define F12_ERASER_STATUS 0x0C -#define F12_SMALL_OBJECT_STATUS 0x0D - -#define F12_GESTURE_DETECTION_LEN 5 - -#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 PINCTRL_STATE_ACTIVE "pmx_ts_active" -#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" -#define PINCTRL_STATE_RELEASE "pmx_ts_release" -enum exp_fn { - RMI_DEV = 0, - RMI_FW_UPDATER, - RMI_TEST_REPORTING, - RMI_PROXIMITY, - RMI_ACTIVE_PEN, - RMI_GESTURE, - RMI_VIDEO, - RMI_DEBUG, - RMI_LAST, -}; - -/* - * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT entry - * @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_version: version of function - * @fn_number: function number - */ -struct synaptics_rmi4_fn_desc { - union { - struct { - 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_1:2; - unsigned char fn_version:2; - unsigned char reserved_2:1; - unsigned char fn_number; - } __packed; - unsigned char data[6]; - }; -}; - -/* - * 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 command registers - * @ctrl_base: 16-bit base address for control registers - * @data_base: 16-bit base address for data 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_f11_extra_data - extra data of F$11 - * @data38_offset: offset to F11_2D_DATA38 register - */ -struct synaptics_rmi4_f11_extra_data { - unsigned char data38_offset; -}; - -/* - * struct synaptics_rmi4_f12_extra_data - extra data of F$12 - * @data1_offset: offset to F12_2D_DATA01 register - * @data4_offset: offset to F12_2D_DATA04 register - * @data15_offset: offset to F12_2D_DATA15 register - * @data15_size: size of F12_2D_DATA15 register - * @data15_data: buffer for reading F12_2D_DATA15 register - * @data23_offset: offset to F12_2D_DATA23 register - * @data23_size: size of F12_2D_DATA23 register - * @data23_data: buffer for reading F12_2D_DATA23 register - * @ctrl20_offset: offset to F12_2D_CTRL20 register - */ -struct synaptics_rmi4_f12_extra_data { - unsigned char data1_offset; - unsigned char data4_offset; - unsigned char data15_offset; - unsigned char data15_size; - unsigned char data15_data[(F12_FINGERS_TO_SUPPORT + 7) / 8]; - unsigned char data23_offset; - unsigned char data23_size; - unsigned char data23_data[F12_FINGERS_TO_SUPPORT]; - unsigned char ctrl20_offset; -}; - -/* - * struct synaptics_rmi4_fn - RMI function handler - * @fn_number: function number - * @num_of_data_sources: number of data sources - * @num_of_data_points: maximum number of fingers supported - * @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 - * @extra: pointer to extra data - */ -struct synaptics_rmi4_fn { - unsigned char fn_number; - unsigned char num_of_data_sources; - unsigned char num_of_data_points; - 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 - * @product_info: product information - * @product_id_string: product ID - * @build_id: firmware build 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[PRODUCT_INFO_SIZE]; - unsigned char product_id_string[PRODUCT_ID_SIZE + 1]; - unsigned char build_id[BUILD_ID_SIZE]; - struct list_head support_fn_list; -}; - -/* - * struct synaptics_rmi4_data - RMI4 device instance data - * @pdev: pointer to platform device - * @input_dev: pointer to associated input device - * @stylus_dev: pointer to associated stylus device - * @hw_if: pointer to hardware interface data - * @rmi4_mod_info: device information - * @board_prop_dir: /sys/board_properties directory for virtual key map file - * @pwr_reg: pointer to regulator for power control - * @bus_reg: pointer to regulator for bus pullup control - * @rmi4_reset_mutex: mutex for software reset - * @rmi4_report_mutex: mutex for input event reporting - * @rmi4_io_ctrl_mutex: mutex for communication interface I/O - * @rmi4_exp_init_mutex: mutex for expansion function module initialization - * @rb_work: work for rebuilding input device - * @rb_workqueue: workqueue for rebuilding input device - * @fb_notifier: framebuffer notifier client - * @reset_work: work for issuing reset after display framebuffer ready - * @reset_workqueue: workqueue for issuing reset after display framebuffer ready - * @early_suspend: early suspend power management - * @current_page: current RMI page for register access - * @button_0d_enabled: switch for enabling 0d button support - * @num_of_tx: number of Tx channels for 2D touch - * @num_of_rx: number of Rx channels for 2D touch - * @num_of_fingers: maximum number of fingers for 2D touch - * @max_touch_width: maximum touch width - * @report_enable: input data to report for F$12 - * @no_sleep_setting: default setting of NoSleep in F01_RMI_CTRL00 register - * @gesture_detection: detected gesture type and properties - * @intr_mask: interrupt enable mask - * @button_txrx_mapping: Tx Rx mapping of 0D buttons - * @num_of_intr_regs: number of interrupt registers - * @f01_query_base_addr: query base address for f$01 - * @f01_cmd_base_addr: command base address for f$01 - * @f01_ctrl_base_addr: control base address for f$01 - * @f01_data_base_addr: data base address for f$01 - * @firmware_id: firmware build ID - * @irq: attention interrupt - * @sensor_max_x: maximum x coordinate for 2D touch - * @sensor_max_y: maximum y coordinate for 2D touch - * @flash_prog_mode: flag to indicate flash programming mode status - * @irq_enabled: flag to indicate attention interrupt enable status - * @fingers_on_2d: flag to indicate presence of fingers in 2D area - * @suspend: flag to indicate whether in suspend state - * @sensor_sleep: flag to indicate sleep state of sensor - * @stay_awake: flag to indicate whether to stay awake during suspend - * @fb_ready: flag to indicate whether display framebuffer in ready state - * @f11_wakeup_gesture: flag to indicate support for wakeup gestures in F$11 - * @f12_wakeup_gesture: flag to indicate support for wakeup gestures in F$12 - * @enable_wakeup_gesture: flag to indicate usage of wakeup gestures - * @wedge_sensor: flag to indicate use of wedge sensor - * @report_pressure: flag to indicate reporting of pressure data - * @stylus_enable: flag to indicate reporting of stylus data - * @eraser_enable: flag to indicate reporting of eraser data - * @external_afe_buttons: flag to indicate presence of external AFE buttons - * @reset_device: pointer to device reset function - * @irq_enable: pointer to interrupt enable function - * @sleep_enable: pointer to sleep enable function - * @report_touch: pointer to touch reporting function - */ -struct synaptics_rmi4_data { - struct platform_device *pdev; - struct input_dev *input_dev; - struct input_dev *stylus_dev; - const struct synaptics_dsx_hw_interface *hw_if; - struct synaptics_rmi4_device_info rmi4_mod_info; - struct kobject *board_prop_dir; - struct regulator *pwr_reg; - struct regulator *bus_reg; - struct mutex rmi4_reset_mutex; - struct mutex rmi4_report_mutex; - struct mutex rmi4_io_ctrl_mutex; - struct mutex rmi4_exp_init_mutex; - struct delayed_work rb_work; - struct workqueue_struct *rb_workqueue; -#ifdef CONFIG_FB - struct work_struct fb_notify_work; - struct notifier_block fb_notifier; - struct work_struct reset_work; - struct workqueue_struct *reset_workqueue; -#endif -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif - unsigned char current_page; - unsigned char button_0d_enabled; - unsigned char num_of_tx; - unsigned char num_of_rx; - unsigned char num_of_fingers; - unsigned char max_touch_width; - unsigned char report_enable; - unsigned char no_sleep_setting; - unsigned char gesture_detection[F12_GESTURE_DETECTION_LEN]; - 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 fingers_on_2d; - bool suspend; - bool sensor_sleep; - bool stay_awake; - bool fb_ready; - bool f11_wakeup_gesture; - bool f12_wakeup_gesture; - bool enable_wakeup_gesture; - bool wedge_sensor; - bool report_pressure; - bool stylus_enable; - bool eraser_enable; - bool external_afe_buttons; - int (*reset_device)(struct synaptics_rmi4_data *rmi4_data, - bool rebuild); - int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable, - bool attn_only); - void (*sleep_enable)(struct synaptics_rmi4_data *rmi4_data, - bool enable); - void (*report_touch)(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn *fhandler); - struct pinctrl *ts_pinctrl; - struct pinctrl_state *pinctrl_state_active; - struct pinctrl_state *pinctrl_state_suspend; - struct pinctrl_state *pinctrl_state_release; -#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26) - atomic_t st_enabled; - atomic_t st_pending_irqs; - struct completion st_powerdown; - struct completion st_irq_processed; - bool st_initialized; - struct clk *core_clk; - struct clk *iface_clk; -#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_SYNAPTICS_DSX_V26) - int (*get)(struct synaptics_rmi4_data *rmi4_data); - void (*put)(struct synaptics_rmi4_data *rmi4_data); -#endif -}; - -struct synaptics_dsx_hw_interface { - struct synaptics_dsx_board_data *board_data; - const struct synaptics_dsx_bus_access *bus_access; - int (*bl_hw_init)(struct synaptics_rmi4_data *rmi4_data); - int (*ui_hw_init)(struct synaptics_rmi4_data *rmi4_data); -}; - -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_v26(void); - -void synaptics_rmi4_bus_exit_v26(void); - -void synaptics_rmi4_new_function(struct synaptics_rmi4_exp_fn *exp_fn_module, - bool insert); - -int synaptics_fw_updater(const unsigned char *fw_data); - -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_SYNAPTICS_DSX_V26) -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 int secure_memcpy(unsigned char *dest, unsigned int dest_size, - const unsigned char *src, unsigned int src_size, - unsigned int count) -{ - if (dest == NULL || src == NULL) - return -EINVAL; - - if (count > dest_size || count > src_size) - return -EINVAL; - - memcpy((void *)dest, (const void *)src, count); - - return 0; -} - -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_2.6/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_fw_update.c deleted file mode 100644 index 168318f85e53..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_fw_update.c +++ /dev/null @@ -1,4440 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define FW_IMAGE_NAME "synaptics/startup_fw_update.img" -/* -#define DO_STARTUP_FW_UPDATE -*/ -/* -#ifdef DO_STARTUP_FW_UPDATE -#ifdef CONFIG_FB -#define WAIT_FOR_FB_READY -#define FB_READY_WAIT_MS 100 -#define FB_READY_TIMEOUT_S 30 -#endif -#endif -*/ -#define FORCE_UPDATE false -#define DO_LOCKDOWN false - -#define MAX_IMAGE_NAME_LEN 256 -#define MAX_FIRMWARE_ID_LEN 10 - -#define IMAGE_HEADER_VERSION_05 0x05 -#define IMAGE_HEADER_VERSION_06 0x06 -#define IMAGE_HEADER_VERSION_10 0x10 - -#define IMAGE_AREA_OFFSET 0x100 -#define LOCKDOWN_SIZE 0x50 - -#define V5V6_BOOTLOADER_ID_OFFSET 0 -#define V5V6_CONFIG_ID_SIZE 4 - -#define V5_PROPERTIES_OFFSET 2 -#define V5_BLOCK_SIZE_OFFSET 3 -#define V5_BLOCK_COUNT_OFFSET 5 -#define V5_BLOCK_NUMBER_OFFSET 0 -#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_PROPERTIES_2_OFFSET 4 -#define V6_GUEST_CODE_BLOCK_COUNT_OFFSET 5 -#define V6_BLOCK_NUMBER_OFFSET 0 -#define V6_BLOCK_DATA_OFFSET 1 -#define V6_FLASH_COMMAND_OFFSET 2 -#define V6_FLASH_STATUS_OFFSET 3 - -#define V7_CONFIG_ID_SIZE 32 - -#define V7_FLASH_STATUS_OFFSET 0 -#define V7_PARTITION_ID_OFFSET 1 -#define V7_BLOCK_NUMBER_OFFSET 2 -#define V7_TRANSFER_LENGTH_OFFSET 3 -#define V7_COMMAND_OFFSET 4 -#define V7_PAYLOAD_OFFSET 5 - -#define V7_PARTITION_SUPPORT_BYTES 4 - -#define F35_ERROR_CODE_OFFSET 0 -#define F35_CHUNK_NUM_LSB_OFFSET 0 -#define F35_CHUNK_NUM_MSB_OFFSET 1 -#define F35_CHUNK_DATA_OFFSET 2 -#define F35_CHUNK_COMMAND_OFFSET 18 - -#define F35_CHUNK_SIZE 16 -#define F35_ERASE_ALL_WAIT_MS 3000 -#define F35_RESET_WAIT_MS 250 - -#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 - -#define INT_DISABLE_WAIT_MS 20 -#define ENTER_FLASH_PROG_WAIT_MS 20 - -static int fwu_do_reflash(void); - -static int fwu_recovery_check_status(void); - -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_do_recovery_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_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_disp_config_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_guest_code_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t fwu_sysfs_write_guest_code_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -enum f34_version { - F34_V0 = 0, - F34_V1, - F34_V2, -}; - -enum bl_version { - BL_V5 = 5, - BL_V6 = 6, - BL_V7 = 7, - BL_V8 = 8, -}; - -enum flash_area { - NONE = 0, - UI_FIRMWARE, - UI_CONFIG, -}; - -enum update_mode { - NORMAL = 1, - FORCE = 2, - LOCKDOWN = 8, -}; - -enum config_area { - UI_CONFIG_AREA = 0, - PM_CONFIG_AREA, - BL_CONFIG_AREA, - DP_CONFIG_AREA, - FLASH_CONFIG_AREA, -}; - -enum v7_status { - SUCCESS = 0x00, - DEVICE_NOT_IN_BOOTLOADER_MODE, - INVALID_PARTITION, - INVALID_COMMAND, - INVALID_BLOCK_OFFSET, - INVALID_TRANSFER, - NOT_ERASED, - FLASH_PROGRAMMING_KEY_INCORRECT, - BAD_PARTITION_TABLE, - CHECKSUM_FAILED, - FLASH_HARDWARE_FAILURE = 0x1f, -}; - -enum v7_partition_id { - BOOTLOADER_PARTITION = 0x01, - DEVICE_CONFIG_PARTITION, - FLASH_CONFIG_PARTITION, - MANUFACTURING_BLOCK_PARTITION, - GUEST_SERIALIZATION_PARTITION, - GLOBAL_PARAMETERS_PARTITION, - CORE_CODE_PARTITION, - CORE_CONFIG_PARTITION, - GUEST_CODE_PARTITION, - DISPLAY_CONFIG_PARTITION, -}; - -enum v7_flash_command { - CMD_V7_IDLE = 0x00, - CMD_V7_ENTER_BL, - CMD_V7_READ, - CMD_V7_WRITE, - CMD_V7_ERASE, - CMD_V7_ERASE_AP, - CMD_V7_SENSOR_ID, -}; - -enum v5v6_flash_command { - CMD_V5V6_IDLE = 0x0, - CMD_V5V6_WRITE_FW = 0x2, - CMD_V5V6_ERASE_ALL = 0x3, - CMD_V5V6_WRITE_LOCKDOWN = 0x4, - CMD_V5V6_READ_CONFIG = 0x5, - CMD_V5V6_WRITE_CONFIG = 0x6, - CMD_V5V6_ERASE_UI_CONFIG = 0x7, - CMD_V5V6_ERASE_BL_CONFIG = 0x9, - CMD_V5V6_ERASE_DISP_CONFIG = 0xa, - CMD_V5V6_ERASE_GUEST_CODE = 0xb, - CMD_V5V6_WRITE_GUEST_CODE = 0xc, - CMD_V5V6_ENABLE_FLASH_PROG = 0xf, -}; - -enum flash_command { - CMD_IDLE = 0, - CMD_WRITE_FW, - CMD_WRITE_CONFIG, - CMD_WRITE_LOCKDOWN, - CMD_WRITE_GUEST_CODE, - CMD_READ_CONFIG, - CMD_ERASE_ALL, - CMD_ERASE_UI_FIRMWARE, - CMD_ERASE_UI_CONFIG, - CMD_ERASE_BL_CONFIG, - CMD_ERASE_DISP_CONFIG, - CMD_ERASE_FLASH_CONFIG, - CMD_ERASE_GUEST_CODE, - CMD_ENABLE_FLASH_PROG, -}; - -enum f35_flash_command { - CMD_F35_IDLE = 0x0, - CMD_F35_RESERVED = 0x1, - CMD_F35_WRITE_CHUNK = 0x2, - CMD_F35_ERASE_ALL = 0x3, - CMD_F35_RESET = 0x10, -}; - -enum container_id { - TOP_LEVEL_CONTAINER = 0, - UI_CONTAINER, - UI_CONFIG_CONTAINER, - BL_CONTAINER, - BL_IMAGE_CONTAINER, - BL_CONFIG_CONTAINER, - BL_LOCKDOWN_INFO_CONTAINER, - PERMANENT_CONFIG_CONTAINER, - GUEST_CODE_CONTAINER, - BL_PROTOCOL_DESCRIPTOR_CONTAINER, - UI_PROTOCOL_DESCRIPTOR_CONTAINER, - RMI_SELF_DISCOVERY_CONTAINER, - RMI_PAGE_CONTENT_CONTAINER, - GENERAL_INFORMATION_CONTAINER, - DEVICE_CONFIG_CONTAINER, - FLASH_CONFIG_CONTAINER, - GUEST_SERIALIZATION_CONTAINER, - GLOBAL_PARAMETERS_CONTAINER, - CORE_CODE_CONTAINER, - CORE_CONFIG_CONTAINER, - DISPLAY_CONFIG_CONTAINER, -}; - -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 partition_table { - unsigned char partition_id:5; - unsigned char byte_0_reserved:3; - unsigned char byte_1_reserved; - unsigned char partition_length_7_0; - unsigned char partition_length_15_8; - unsigned char start_physical_address_7_0; - unsigned char start_physical_address_15_8; - unsigned char partition_properties_7_0; - unsigned char partition_properties_15_8; -} __packed; - -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_v7_query_0 { - union { - struct { - unsigned char subpacket_1_size:3; - unsigned char has_config_id:1; - unsigned char f34_query0_b4:1; - unsigned char has_thqa:1; - unsigned char f34_query0_b6__7:2; - } __packed; - unsigned char data[1]; - }; -}; - -struct f34_v7_query_1_7 { - union { - struct { - /* query 1 */ - unsigned char bl_minor_revision; - unsigned char bl_major_revision; - - /* query 2 */ - unsigned char bl_fw_id_7_0; - unsigned char bl_fw_id_15_8; - unsigned char bl_fw_id_23_16; - unsigned char bl_fw_id_31_24; - - /* query 3 */ - unsigned char minimum_write_size; - unsigned char block_size_7_0; - unsigned char block_size_15_8; - unsigned char flash_page_size_7_0; - unsigned char flash_page_size_15_8; - - /* query 4 */ - unsigned char adjustable_partition_area_size_7_0; - unsigned char adjustable_partition_area_size_15_8; - - /* query 5 */ - unsigned char flash_config_length_7_0; - unsigned char flash_config_length_15_8; - - /* query 6 */ - unsigned char payload_length_7_0; - unsigned char payload_length_15_8; - - /* query 7 */ - unsigned char f34_query7_b0:1; - unsigned char has_bootloader:1; - unsigned char has_device_config:1; - unsigned char has_flash_config:1; - unsigned char has_manufacturing_block:1; - unsigned char has_guest_serialization:1; - unsigned char has_global_parameters:1; - unsigned char has_core_code:1; - unsigned char has_core_config:1; - unsigned char has_guest_code:1; - unsigned char has_display_config:1; - unsigned char f34_query7_b11__15:5; - unsigned char f34_query7_b16__23; - unsigned char f34_query7_b24__31; - } __packed; - unsigned char data[21]; - }; -}; - -struct f34_v7_data0 { - union { - struct { - unsigned char operation_status:5; - unsigned char device_cfg_status:2; - unsigned char bl_mode:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f34_v7_data_1_5 { - union { - struct { - unsigned char partition_id:5; - unsigned char f34_data1_b5__7:3; - unsigned char block_offset_7_0; - unsigned char block_offset_15_8; - unsigned char transfer_length_7_0; - unsigned char transfer_length_15_8; - unsigned char command; - unsigned char payload_0; - unsigned char payload_1; - } __packed; - unsigned char data[8]; - }; -}; - -struct f34_v5v6_flash_properties { - union { - struct { - unsigned char reg_map:1; - unsigned char unlocked:1; - unsigned char has_config_id:1; - unsigned char has_pm_config:1; - unsigned char has_bl_config:1; - unsigned char has_disp_config:1; - unsigned char has_ctrl1:1; - unsigned char has_query4:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f34_v5v6_flash_properties_2 { - union { - struct { - unsigned char has_guest_code:1; - unsigned char reserved:7; - } __packed; - unsigned char data[1]; - }; -}; - -struct register_offset { - unsigned char properties; - unsigned char properties_2; - unsigned char block_size; - unsigned char block_count; - unsigned char gc_block_count; - unsigned char flash_status; - unsigned char partition_id; - unsigned char block_number; - unsigned char transfer_length; - unsigned char flash_cmd; - unsigned char payload; -}; - -struct block_count { - unsigned short ui_firmware; - unsigned short ui_config; - unsigned short dp_config; - unsigned short pm_config; - unsigned short fl_config; - unsigned short bl_image; - unsigned short bl_config; - unsigned short lockdown; - unsigned short guest_code; - unsigned short total_count; -}; - -struct physical_address { - unsigned short ui_firmware; - unsigned short ui_config; - unsigned short dp_config; - unsigned short fl_config; - unsigned short guest_code; -}; - -struct container_descriptor { - unsigned char content_checksum[4]; - unsigned char container_id[2]; - unsigned char minor_version; - unsigned char major_version; - unsigned char reserved_08; - unsigned char reserved_09; - unsigned char reserved_0a; - unsigned char reserved_0b; - unsigned char container_option_flags[4]; - unsigned char content_options_length[4]; - unsigned char content_options_address[4]; - unsigned char content_length[4]; - unsigned char content_address[4]; -}; - -struct image_header_10 { - unsigned char checksum[4]; - unsigned char reserved_04; - unsigned char reserved_05; - unsigned char minor_header_version; - unsigned char major_header_version; - unsigned char reserved_08; - unsigned char reserved_09; - unsigned char reserved_0a; - unsigned char reserved_0b; - unsigned char top_level_container_start_addr[4]; -}; - -struct image_header_05_06 { - /* 0x00 - 0x0f */ - unsigned char checksum[4]; - unsigned char reserved_04; - unsigned char reserved_05; - unsigned char options_firmware_id:1; - unsigned char options_bootloader:1; - unsigned char options_guest_code:1; - unsigned char options_tddi:1; - unsigned char options_reserved:4; - unsigned char header_version; - unsigned char firmware_size[4]; - unsigned char config_size[4]; - /* 0x10 - 0x1f */ - unsigned char product_id[PRODUCT_ID_SIZE]; - unsigned char package_id[2]; - unsigned char package_id_revision[2]; - unsigned char product_info[PRODUCT_INFO_SIZE]; - /* 0x20 - 0x2f */ - unsigned char bootloader_addr[4]; - unsigned char bootloader_size[4]; - unsigned char ui_addr[4]; - unsigned char ui_size[4]; - /* 0x30 - 0x3f */ - unsigned char ds_id[16]; - /* 0x40 - 0x4f */ - union { - struct { - unsigned char cstmr_product_id[PRODUCT_ID_SIZE]; - unsigned char reserved_4a_4f[6]; - }; - struct { - unsigned char dsp_cfg_addr[4]; - unsigned char dsp_cfg_size[4]; - unsigned char reserved_48_4f[8]; - }; - }; - /* 0x50 - 0x53 */ - unsigned char firmware_id[4]; -}; - -struct block_data { - unsigned int size; - const unsigned char *data; -}; - -struct image_metadata { - bool contains_firmware_id; - bool contains_bootloader; - bool contains_guest_code; - bool contains_disp_config; - bool contains_perm_config; - bool contains_flash_config; - unsigned int firmware_id; - unsigned int checksum; - unsigned int bootloader_size; - unsigned int disp_config_offset; - unsigned char bl_version; - unsigned char product_id[PRODUCT_ID_SIZE + 1]; - unsigned char cstmr_product_id[PRODUCT_ID_SIZE + 1]; - struct block_data bootloader; - struct block_data ui_firmware; - struct block_data ui_config; - struct block_data dp_config; - struct block_data pm_config; - struct block_data fl_config; - struct block_data bl_image; - struct block_data bl_config; - struct block_data lockdown; - struct block_data guest_code; - struct block_count blkcount; - struct physical_address phyaddr; -}; - -struct synaptics_rmi4_fwu_handle { - enum bl_version bl_version; - bool initialized; - bool in_bl_mode; - bool in_ub_mode; - bool force_update; - bool do_lockdown; - bool has_guest_code; - bool new_partition_table; - unsigned int data_pos; - unsigned char *ext_data_source; - unsigned char *read_config_buf; - unsigned char intr_mask; - unsigned char command; - unsigned char bootloader_id[2]; - unsigned char config_id[32]; - unsigned char flash_status; - unsigned char partitions; - unsigned short block_size; - unsigned short config_size; - unsigned short config_area; - unsigned short config_block_count; - unsigned short flash_config_length; - unsigned short payload_length; - unsigned short partition_table_bytes; - unsigned short read_config_buf_size; - const unsigned char *config_data; - const unsigned char *image; - unsigned char *image_name; - unsigned int image_size; - struct image_metadata img; - struct register_offset off; - struct block_count blkcount; - struct physical_address phyaddr; - struct f34_v5v6_flash_properties flash_properties; - struct synaptics_rmi4_fn_desc f34_fd; - struct synaptics_rmi4_fn_desc f35_fd; - struct synaptics_rmi4_data *rmi4_data; - struct workqueue_struct *fwu_workqueue; - struct work_struct fwu_work; -}; - -static struct bin_attribute dev_attr_data = { - .attr = { - .name = "data", - .mode = (S_IRUGO | S_IWUGO), - }, - .size = 0, - .read = fwu_sysfs_show_image, - .write = fwu_sysfs_store_image, -}; - -static struct device_attribute attrs[] = { - __ATTR(dorecovery, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_do_recovery_store), - __ATTR(doreflash, 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(imagename, S_IWUSR | S_IWGRP, - NULL, - 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, - NULL), - __ATTR(fwblockcount, S_IRUGO, - fwu_sysfs_firmware_block_count_show, - NULL), - __ATTR(configblockcount, S_IRUGO, - fwu_sysfs_configuration_block_count_show, - NULL), - __ATTR(dispconfigblockcount, S_IRUGO, - fwu_sysfs_disp_config_block_count_show, - NULL), - __ATTR(permconfigblockcount, S_IRUGO, - fwu_sysfs_perm_config_block_count_show, - NULL), - __ATTR(blconfigblockcount, S_IRUGO, - fwu_sysfs_bl_config_block_count_show, - NULL), - __ATTR(guestcodeblockcount, S_IRUGO, - fwu_sysfs_guest_code_block_count_show, - NULL), - __ATTR(writeguestcode, S_IWUSR | S_IWGRP, - NULL, - fwu_sysfs_write_guest_code_store), -}; - -static struct synaptics_rmi4_fwu_handle *fwu; - -DECLARE_COMPLETION(fwu_remove_complete); - -static unsigned int le_to_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 int fwu_allocate_read_config_buf(unsigned int count) -{ - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (count > fwu->read_config_buf_size) { - kfree(fwu->read_config_buf); - fwu->read_config_buf = kzalloc(count, GFP_KERNEL); - if (!fwu->read_config_buf) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for fwu->read_config_buf\n", - __func__); - fwu->read_config_buf_size = 0; - return -ENOMEM; - } - fwu->read_config_buf_size = count; - } - - return 0; -} - -static void fwu_compare_partition_tables(void) -{ - if (fwu->phyaddr.ui_firmware != fwu->img.phyaddr.ui_firmware) { - fwu->new_partition_table = true; - return; - } - - if (fwu->phyaddr.ui_config != fwu->img.phyaddr.ui_config) { - fwu->new_partition_table = true; - return; - } - - if (fwu->flash_properties.has_disp_config) { - if (fwu->phyaddr.dp_config != fwu->img.phyaddr.dp_config) { - fwu->new_partition_table = true; - return; - } - } - - if (fwu->has_guest_code) { - if (fwu->phyaddr.guest_code != fwu->img.phyaddr.guest_code) { - fwu->new_partition_table = true; - return; - } - } - - fwu->new_partition_table = false; - - return; -} - -static void fwu_parse_partition_table(const unsigned char *partition_table, - struct block_count *blkcount, struct physical_address *phyaddr) -{ - unsigned char ii; - unsigned char index; - unsigned char offset; - unsigned short partition_length; - unsigned short physical_address; - struct partition_table *ptable; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - for (ii = 0; ii < fwu->partitions; ii++) { - index = ii * 8 + 2; - ptable = (struct partition_table *)&partition_table[index]; - partition_length = ptable->partition_length_15_8 << 8 | - ptable->partition_length_7_0; - physical_address = ptable->start_physical_address_15_8 << 8 | - ptable->start_physical_address_7_0; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Partition entry %d:\n", - __func__, ii); - for (offset = 0; offset < 8; offset++) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: 0x%02x\n", - __func__, - partition_table[index + offset]); - } - switch (ptable->partition_id) { - case CORE_CODE_PARTITION: - blkcount->ui_firmware = partition_length; - phyaddr->ui_firmware = physical_address; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Core code block count: %d\n", - __func__, blkcount->ui_firmware); - blkcount->total_count += partition_length; - break; - case CORE_CONFIG_PARTITION: - blkcount->ui_config = partition_length; - phyaddr->ui_config = physical_address; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Core config block count: %d\n", - __func__, blkcount->ui_config); - blkcount->total_count += partition_length; - break; - case BOOTLOADER_PARTITION: - blkcount->bl_image = partition_length; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Core config block count: %d\n", - __func__, blkcount->ui_config); - blkcount->total_count += partition_length; - break; - case DISPLAY_CONFIG_PARTITION: - blkcount->dp_config = partition_length; - phyaddr->dp_config = physical_address; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Display config block count: %d\n", - __func__, blkcount->dp_config); - blkcount->total_count += partition_length; - break; - case FLASH_CONFIG_PARTITION: - blkcount->fl_config = partition_length; - phyaddr->fl_config = physical_address; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Flash config block count: %d\n", - __func__, blkcount->fl_config); - blkcount->total_count += partition_length; - break; - case GUEST_CODE_PARTITION: - blkcount->guest_code = partition_length; - phyaddr->guest_code = physical_address; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Guest code block count: %d\n", - __func__, blkcount->guest_code); - blkcount->total_count += partition_length; - break; - case GUEST_SERIALIZATION_PARTITION: - blkcount->pm_config = partition_length; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Guest serialization block count: %d\n", - __func__, blkcount->pm_config); - blkcount->total_count += partition_length; - break; - case GLOBAL_PARAMETERS_PARTITION: - blkcount->bl_config = partition_length; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Global parameters block count: %d\n", - __func__, blkcount->bl_config); - blkcount->total_count += partition_length; - break; - case DEVICE_CONFIG_PARTITION: - blkcount->lockdown = partition_length; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Device config block count: %d\n", - __func__, blkcount->lockdown); - blkcount->total_count += partition_length; - break; - }; - } - - return; -} - -static void fwu_parse_image_header_10_bl_container(const unsigned char *image) -{ - unsigned char ii; - unsigned char num_of_containers; - unsigned int addr; - unsigned int container_id; - unsigned int length; - const unsigned char *content; - struct container_descriptor *descriptor; - - num_of_containers = (fwu->img.bootloader.size - 4) / 4; - - for (ii = 1; ii <= num_of_containers; ii++) { - addr = le_to_uint(fwu->img.bootloader.data + (ii * 4)); - descriptor = (struct container_descriptor *)(image + addr); - container_id = descriptor->container_id[0] | - descriptor->container_id[1] << 8; - content = image + le_to_uint(descriptor->content_address); - length = le_to_uint(descriptor->content_length); - switch (container_id) { - case BL_IMAGE_CONTAINER: - fwu->img.bl_image.data = content; - fwu->img.bl_image.size = length; - break; - case BL_CONFIG_CONTAINER: - case GLOBAL_PARAMETERS_CONTAINER: - fwu->img.bl_config.data = content; - fwu->img.bl_config.size = length; - break; - case BL_LOCKDOWN_INFO_CONTAINER: - case DEVICE_CONFIG_CONTAINER: - fwu->img.lockdown.data = content; - fwu->img.lockdown.size = length; - break; - default: - break; - }; - } - - return; -} - -static void fwu_parse_image_header_10(void) -{ - unsigned char ii; - unsigned char num_of_containers; - unsigned int addr; - unsigned int offset; - unsigned int container_id; - unsigned int length; - const unsigned char *image; - const unsigned char *content; - struct container_descriptor *descriptor; - struct image_header_10 *header; - - image = fwu->image; - header = (struct image_header_10 *)image; - - fwu->img.checksum = le_to_uint(header->checksum); - - /* address of top level container */ - offset = le_to_uint(header->top_level_container_start_addr); - descriptor = (struct container_descriptor *)(image + offset); - - /* address of top level container content */ - offset = le_to_uint(descriptor->content_address); - num_of_containers = le_to_uint(descriptor->content_length) / 4; - - for (ii = 0; ii < num_of_containers; ii++) { - addr = le_to_uint(image + offset); - offset += 4; - descriptor = (struct container_descriptor *)(image + addr); - container_id = descriptor->container_id[0] | - descriptor->container_id[1] << 8; - content = image + le_to_uint(descriptor->content_address); - length = le_to_uint(descriptor->content_length); - switch (container_id) { - case UI_CONTAINER: - case CORE_CODE_CONTAINER: - fwu->img.ui_firmware.data = content; - fwu->img.ui_firmware.size = length; - break; - case UI_CONFIG_CONTAINER: - case CORE_CONFIG_CONTAINER: - fwu->img.ui_config.data = content; - fwu->img.ui_config.size = length; - break; - case BL_CONTAINER: - fwu->img.bl_version = *content; - fwu->img.bootloader.data = content; - fwu->img.bootloader.size = length; - fwu_parse_image_header_10_bl_container(image); - break; - case GUEST_CODE_CONTAINER: - fwu->img.contains_guest_code = true; - fwu->img.guest_code.data = content; - fwu->img.guest_code.size = length; - break; - case DISPLAY_CONFIG_CONTAINER: - fwu->img.contains_disp_config = true; - fwu->img.dp_config.data = content; - fwu->img.dp_config.size = length; - break; - case PERMANENT_CONFIG_CONTAINER: - case GUEST_SERIALIZATION_CONTAINER: - fwu->img.contains_perm_config = true; - fwu->img.pm_config.data = content; - fwu->img.pm_config.size = length; - break; - case FLASH_CONFIG_CONTAINER: - fwu->img.contains_flash_config = true; - fwu->img.fl_config.data = content; - fwu->img.fl_config.size = length; - break; - case GENERAL_INFORMATION_CONTAINER: - fwu->img.contains_firmware_id = true; - fwu->img.firmware_id = le_to_uint(content + 4); - break; - default: - break; - } - } - - return; -} - -static void fwu_parse_image_header_05_06(void) -{ - int retval; - const unsigned char *image; - struct image_header_05_06 *header; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - image = fwu->image; - header = (struct image_header_05_06 *)image; - - fwu->img.checksum = le_to_uint(header->checksum); - - fwu->img.bl_version = header->header_version; - - fwu->img.contains_bootloader = header->options_bootloader; - if (fwu->img.contains_bootloader) - fwu->img.bootloader_size = le_to_uint(header->bootloader_size); - - fwu->img.ui_firmware.size = le_to_uint(header->firmware_size); - if (fwu->img.ui_firmware.size) { - fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET; - if (fwu->img.contains_bootloader) - fwu->img.ui_firmware.data += fwu->img.bootloader_size; - } - - if ((fwu->img.bl_version == BL_V6) && header->options_tddi) - fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET; - - fwu->img.ui_config.size = le_to_uint(header->config_size); - if (fwu->img.ui_config.size) { - fwu->img.ui_config.data = fwu->img.ui_firmware.data + - fwu->img.ui_firmware.size; - } - - if ((fwu->img.bl_version == BL_V5 && fwu->img.contains_bootloader) || - (fwu->img.bl_version == BL_V6 && header->options_tddi)) - fwu->img.contains_disp_config = true; - else - fwu->img.contains_disp_config = false; - - if (fwu->img.contains_disp_config) { - fwu->img.disp_config_offset = le_to_uint(header->dsp_cfg_addr); - fwu->img.dp_config.size = le_to_uint(header->dsp_cfg_size); - fwu->img.dp_config.data = image + fwu->img.disp_config_offset; - } else { - retval = secure_memcpy(fwu->img.cstmr_product_id, - sizeof(fwu->img.cstmr_product_id), - header->cstmr_product_id, - sizeof(header->cstmr_product_id), - PRODUCT_ID_SIZE); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy custom product ID string\n", - __func__); - } - fwu->img.cstmr_product_id[PRODUCT_ID_SIZE] = 0; - } - - fwu->img.contains_firmware_id = header->options_firmware_id; - if (fwu->img.contains_firmware_id) - fwu->img.firmware_id = le_to_uint(header->firmware_id); - - retval = secure_memcpy(fwu->img.product_id, - sizeof(fwu->img.product_id), - header->product_id, - sizeof(header->product_id), - PRODUCT_ID_SIZE); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy product ID string\n", - __func__); - } - fwu->img.product_id[PRODUCT_ID_SIZE] = 0; - - fwu->img.lockdown.size = LOCKDOWN_SIZE; - fwu->img.lockdown.data = image + IMAGE_AREA_OFFSET - LOCKDOWN_SIZE; - - return; -} - -static int fwu_parse_image_info(void) -{ - struct image_header_10 *header; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - header = (struct image_header_10 *)fwu->image; - - memset(&fwu->img, 0x00, sizeof(fwu->img)); - - switch (header->major_header_version) { - case IMAGE_HEADER_VERSION_10: - fwu_parse_image_header_10(); - break; - case IMAGE_HEADER_VERSION_05: - case IMAGE_HEADER_VERSION_06: - fwu_parse_image_header_05_06(); - break; - default: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Unsupported image file format (0x%02x)\n", - __func__, header->major_header_version); - return -EINVAL; - } - - if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) { - if (!fwu->img.contains_flash_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: No flash config found in firmware image\n", - __func__); - return -EINVAL; - } - - fwu_parse_partition_table(fwu->img.fl_config.data, - &fwu->img.blkcount, &fwu->img.phyaddr); - - fwu_compare_partition_tables(); - } else { - fwu->new_partition_table = false; - } - - return 0; -} - -static int fwu_read_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->off.flash_status, - &status, - sizeof(status)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read flash status\n", - __func__); - return retval; - } - - fwu->in_bl_mode = status >> 7; - - if (fwu->bl_version == BL_V5) - fwu->flash_status = (status >> 4) & MASK_3BIT; - else if (fwu->bl_version == BL_V6) - fwu->flash_status = status & MASK_3BIT; - else if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) - fwu->flash_status = status & MASK_5BIT; - - if (fwu->flash_status != 0x00) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Flash status = %d, command = 0x%02x\n", - __func__, fwu->flash_status, fwu->command); - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.data_base_addr + fwu->off.flash_cmd, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read flash command\n", - __func__); - return retval; - } - - if (fwu->bl_version == BL_V5) - fwu->command = command & MASK_4BIT; - else if (fwu->bl_version == BL_V6) - fwu->command = command & MASK_6BIT; - else if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) - fwu->command = command; - - return 0; -} - -static int fwu_wait_for_idle(int timeout_ms, bool poll) -{ - 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 (poll || (count == timeout_count)) - fwu_read_flash_status(); - - if ((fwu->command == CMD_IDLE) && (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 int fwu_write_f34_v7_command_single_transaction(unsigned char cmd) -{ - int retval; - unsigned char base; - struct f34_v7_data_1_5 data_1_5; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - memset(data_1_5.data, 0x00, sizeof(data_1_5.data)); - - switch (cmd) { - case CMD_ERASE_ALL: - data_1_5.partition_id = CORE_CODE_PARTITION; - data_1_5.command = CMD_V7_ERASE_AP; - break; - case CMD_ERASE_UI_FIRMWARE: - data_1_5.partition_id = CORE_CODE_PARTITION; - data_1_5.command = CMD_V7_ERASE; - break; - case CMD_ERASE_BL_CONFIG: - data_1_5.partition_id = GLOBAL_PARAMETERS_PARTITION; - data_1_5.command = CMD_V7_ERASE; - break; - case CMD_ERASE_UI_CONFIG: - data_1_5.partition_id = CORE_CONFIG_PARTITION; - data_1_5.command = CMD_V7_ERASE; - break; - case CMD_ERASE_DISP_CONFIG: - data_1_5.partition_id = DISPLAY_CONFIG_PARTITION; - data_1_5.command = CMD_V7_ERASE; - break; - case CMD_ERASE_FLASH_CONFIG: - data_1_5.partition_id = FLASH_CONFIG_PARTITION; - data_1_5.command = CMD_V7_ERASE; - break; - case CMD_ERASE_GUEST_CODE: - data_1_5.partition_id = GUEST_CODE_PARTITION; - data_1_5.command = CMD_V7_ERASE; - break; - case CMD_ENABLE_FLASH_PROG: - data_1_5.partition_id = BOOTLOADER_PARTITION; - data_1_5.command = CMD_V7_ENTER_BL; - break; - }; - - data_1_5.payload_0 = fwu->bootloader_id[0]; - data_1_5.payload_1 = fwu->bootloader_id[1]; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.partition_id, - data_1_5.data, - sizeof(data_1_5.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write single transaction command\n", - __func__); - return retval; - } - - return 0; -} - -static int fwu_write_f34_v7_command(unsigned char cmd) -{ - int retval; - unsigned char base; - unsigned char command; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - switch (cmd) { - case CMD_WRITE_FW: - case CMD_WRITE_CONFIG: - case CMD_WRITE_LOCKDOWN: - case CMD_WRITE_GUEST_CODE: - command = CMD_V7_WRITE; - break; - case CMD_READ_CONFIG: - command = CMD_V7_READ; - break; - case CMD_ERASE_ALL: - command = CMD_V7_ERASE_AP; - break; - case CMD_ERASE_UI_FIRMWARE: - case CMD_ERASE_BL_CONFIG: - case CMD_ERASE_UI_CONFIG: - case CMD_ERASE_DISP_CONFIG: - case CMD_ERASE_FLASH_CONFIG: - case CMD_ERASE_GUEST_CODE: - command = CMD_V7_ERASE; - break; - case CMD_ENABLE_FLASH_PROG: - command = CMD_V7_ENTER_BL; - break; - default: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid command 0x%02x\n", - __func__, cmd); - return -EINVAL; - }; - - fwu->command = command; - - switch (cmd) { - case CMD_ERASE_ALL: - case CMD_ERASE_UI_FIRMWARE: - case CMD_ERASE_BL_CONFIG: - case CMD_ERASE_UI_CONFIG: - case CMD_ERASE_DISP_CONFIG: - case CMD_ERASE_FLASH_CONFIG: - case CMD_ERASE_GUEST_CODE: - case CMD_ENABLE_FLASH_PROG: - retval = fwu_write_f34_v7_command_single_transaction(cmd); - if (retval < 0) - return retval; - else - return 0; - default: - break; - }; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.flash_cmd, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write flash command\n", - __func__); - return retval; - } - - return 0; -} - -static int fwu_write_f34_v5v6_command(unsigned char cmd) -{ - int retval; - unsigned char base; - unsigned char command; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - switch (cmd) { - case CMD_IDLE: - command = CMD_V5V6_IDLE; - break; - case CMD_WRITE_FW: - command = CMD_V5V6_WRITE_FW; - break; - case CMD_WRITE_CONFIG: - command = CMD_V5V6_WRITE_CONFIG; - break; - case CMD_WRITE_LOCKDOWN: - command = CMD_V5V6_WRITE_LOCKDOWN; - break; - case CMD_WRITE_GUEST_CODE: - command = CMD_V5V6_WRITE_GUEST_CODE; - break; - case CMD_READ_CONFIG: - command = CMD_V5V6_READ_CONFIG; - break; - case CMD_ERASE_ALL: - command = CMD_V5V6_ERASE_ALL; - break; - case CMD_ERASE_UI_CONFIG: - command = CMD_V5V6_ERASE_UI_CONFIG; - break; - case CMD_ERASE_DISP_CONFIG: - command = CMD_V5V6_ERASE_DISP_CONFIG; - break; - case CMD_ERASE_GUEST_CODE: - command = CMD_V5V6_ERASE_GUEST_CODE; - break; - case CMD_ENABLE_FLASH_PROG: - command = CMD_V5V6_ENABLE_FLASH_PROG; - break; - default: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid command 0x%02x\n", - __func__, cmd); - return -EINVAL; - } - - switch (cmd) { - case CMD_ERASE_ALL: - case CMD_ERASE_UI_CONFIG: - case CMD_ERASE_DISP_CONFIG: - case CMD_ERASE_GUEST_CODE: - case CMD_ENABLE_FLASH_PROG: - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.payload, - 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; - } - break; - default: - break; - }; - - fwu->command = command; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.flash_cmd, - &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_write_f34_command(unsigned char cmd) -{ - int retval; - - if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) - retval = fwu_write_f34_v7_command(cmd); - else - retval = fwu_write_f34_v5v6_command(cmd); - - return retval; -} - -static int fwu_write_f34_v7_partition_id(unsigned char cmd) -{ - int retval; - unsigned char base; - unsigned char partition; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - switch (cmd) { - case CMD_WRITE_FW: - partition = CORE_CODE_PARTITION; - break; - case CMD_WRITE_CONFIG: - case CMD_READ_CONFIG: - if (fwu->config_area == UI_CONFIG_AREA) - partition = CORE_CONFIG_PARTITION; - else if (fwu->config_area == DP_CONFIG_AREA) - partition = DISPLAY_CONFIG_PARTITION; - else if (fwu->config_area == PM_CONFIG_AREA) - partition = GUEST_SERIALIZATION_PARTITION; - else if (fwu->config_area == BL_CONFIG_AREA) - partition = GLOBAL_PARAMETERS_PARTITION; - else if (fwu->config_area == FLASH_CONFIG_AREA) - partition = FLASH_CONFIG_PARTITION; - break; - case CMD_WRITE_LOCKDOWN: - partition = DEVICE_CONFIG_PARTITION; - break; - case CMD_WRITE_GUEST_CODE: - partition = GUEST_CODE_PARTITION; - break; - case CMD_ERASE_ALL: - partition = CORE_CODE_PARTITION; - break; - case CMD_ERASE_BL_CONFIG: - partition = GLOBAL_PARAMETERS_PARTITION; - break; - case CMD_ERASE_UI_CONFIG: - partition = CORE_CONFIG_PARTITION; - break; - case CMD_ERASE_DISP_CONFIG: - partition = DISPLAY_CONFIG_PARTITION; - break; - case CMD_ERASE_FLASH_CONFIG: - partition = FLASH_CONFIG_PARTITION; - break; - case CMD_ERASE_GUEST_CODE: - partition = GUEST_CODE_PARTITION; - break; - case CMD_ENABLE_FLASH_PROG: - partition = BOOTLOADER_PARTITION; - break; - default: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid command 0x%02x\n", - __func__, cmd); - return -EINVAL; - }; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.partition_id, - &partition, - sizeof(partition)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write partition ID\n", - __func__); - return retval; - } - - return 0; -} - -static int fwu_write_f34_partition_id(unsigned char cmd) -{ - int retval; - - if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) - retval = fwu_write_f34_v7_partition_id(cmd); - else - retval = 0; - - return retval; -} - -static int fwu_read_f34_v7_partition_table(unsigned char *partition_table) -{ - int retval; - unsigned char base; - unsigned char length[2]; - unsigned short block_number = 0; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - fwu->config_area = FLASH_CONFIG_AREA; - - retval = fwu_write_f34_partition_id(CMD_READ_CONFIG); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.block_number, - (unsigned char *)&block_number, - sizeof(block_number)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write block number\n", - __func__); - return retval; - } - - length[0] = (unsigned char)(fwu->flash_config_length & MASK_8BIT); - length[1] = (unsigned char)(fwu->flash_config_length >> 8); - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.transfer_length, - length, - sizeof(length)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write transfer length\n", - __func__); - return retval; - } - - retval = fwu_write_f34_command(CMD_READ_CONFIG); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write command\n", - __func__); - return retval; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS, true); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wait for idle status\n", - __func__); - return retval; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + fwu->off.payload, - partition_table, - fwu->partition_table_bytes); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read block data\n", - __func__); - return retval; - } - - return 0; -} - -static int fwu_read_f34_v7_queries(void) -{ - int retval; - unsigned char ii; - unsigned char base; - unsigned char index; - unsigned char offset; - unsigned char *ptable; - struct f34_v7_query_0 query_0; - struct f34_v7_query_1_7 query_1_7; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.query_base_addr; - - retval = synaptics_rmi4_reg_read(rmi4_data, - base, - query_0.data, - sizeof(query_0.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read query 0\n", - __func__); - return retval; - } - - offset = query_0.subpacket_1_size + 1; - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + offset, - query_1_7.data, - sizeof(query_1_7.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read queries 1 to 7\n", - __func__); - return retval; - } - - fwu->bootloader_id[0] = query_1_7.bl_minor_revision; - fwu->bootloader_id[1] = query_1_7.bl_major_revision; - - if (fwu->bootloader_id[1] == BL_V8) - fwu->bl_version = BL_V8; - - fwu->block_size = query_1_7.block_size_15_8 << 8 | - query_1_7.block_size_7_0; - - fwu->flash_config_length = query_1_7.flash_config_length_15_8 << 8 | - query_1_7.flash_config_length_7_0; - - fwu->payload_length = query_1_7.payload_length_15_8 << 8 | - query_1_7.payload_length_7_0; - - fwu->off.flash_status = V7_FLASH_STATUS_OFFSET; - fwu->off.partition_id = V7_PARTITION_ID_OFFSET; - fwu->off.block_number = V7_BLOCK_NUMBER_OFFSET; - fwu->off.transfer_length = V7_TRANSFER_LENGTH_OFFSET; - fwu->off.flash_cmd = V7_COMMAND_OFFSET; - fwu->off.payload = V7_PAYLOAD_OFFSET; - - index = sizeof(query_1_7.data) - V7_PARTITION_SUPPORT_BYTES; - - fwu->partitions = 0; - for (offset = 0; offset < V7_PARTITION_SUPPORT_BYTES; offset++) { - for (ii = 0; ii < 8; ii++) { - if (query_1_7.data[index + offset] & (1 << ii)) - fwu->partitions++; - } - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Supported partitions: 0x%02x\n", - __func__, query_1_7.data[index + offset]); - } - - fwu->partition_table_bytes = fwu->partitions * 8 + 2; - - ptable = kzalloc(fwu->partition_table_bytes, GFP_KERNEL); - if (!ptable) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for partition table\n", - __func__); - return -ENOMEM; - } - - retval = fwu_read_f34_v7_partition_table(ptable); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read partition table\n", - __func__); - kfree(ptable); - return retval; - } - - fwu_parse_partition_table(ptable, &fwu->blkcount, &fwu->phyaddr); - - if (fwu->blkcount.dp_config) - fwu->flash_properties.has_disp_config = 1; - else - fwu->flash_properties.has_disp_config = 0; - - if (fwu->blkcount.pm_config) - fwu->flash_properties.has_pm_config = 1; - else - fwu->flash_properties.has_pm_config = 0; - - if (fwu->blkcount.bl_config) - fwu->flash_properties.has_bl_config = 1; - else - fwu->flash_properties.has_bl_config = 0; - - if (fwu->blkcount.guest_code) - fwu->has_guest_code = 1; - else - fwu->has_guest_code = 0; - - kfree(ptable); - - return 0; -} - -static int fwu_read_f34_v5v6_queries(void) -{ - int retval; - unsigned char count; - unsigned char base; - unsigned char buf[10]; - struct f34_v5v6_flash_properties_2 properties_2; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.query_base_addr; - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + V5V6_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->bl_version == BL_V5) { - fwu->off.properties = V5_PROPERTIES_OFFSET; - fwu->off.block_size = V5_BLOCK_SIZE_OFFSET; - fwu->off.block_count = V5_BLOCK_COUNT_OFFSET; - fwu->off.block_number = V5_BLOCK_NUMBER_OFFSET; - fwu->off.payload = V5_BLOCK_DATA_OFFSET; - } else if (fwu->bl_version == BL_V6) { - fwu->off.properties = V6_PROPERTIES_OFFSET; - fwu->off.properties_2 = V6_PROPERTIES_2_OFFSET; - fwu->off.block_size = V6_BLOCK_SIZE_OFFSET; - fwu->off.block_count = V6_BLOCK_COUNT_OFFSET; - fwu->off.gc_block_count = V6_GUEST_CODE_BLOCK_COUNT_OFFSET; - fwu->off.block_number = V6_BLOCK_NUMBER_OFFSET; - fwu->off.payload = V6_BLOCK_DATA_OFFSET; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + fwu->off.block_size, - 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 == BL_V5) { - fwu->off.flash_cmd = fwu->off.payload + fwu->block_size; - fwu->off.flash_status = fwu->off.flash_cmd; - } else if (fwu->bl_version == BL_V6) { - fwu->off.flash_cmd = V6_FLASH_COMMAND_OFFSET; - fwu->off.flash_status = V6_FLASH_STATUS_OFFSET; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + fwu->off.properties, - fwu->flash_properties.data, - sizeof(fwu->flash_properties.data)); - 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_pm_config) - count += 2; - - if (fwu->flash_properties.has_bl_config) - count += 2; - - if (fwu->flash_properties.has_disp_config) - count += 2; - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + fwu->off.block_count, - 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->blkcount.ui_firmware, &(buf[0])); - batohs(&fwu->blkcount.ui_config, &(buf[2])); - - count = 4; - - if (fwu->flash_properties.has_pm_config) { - batohs(&fwu->blkcount.pm_config, &(buf[count])); - count += 2; - } - - if (fwu->flash_properties.has_bl_config) { - batohs(&fwu->blkcount.bl_config, &(buf[count])); - count += 2; - } - - if (fwu->flash_properties.has_disp_config) - batohs(&fwu->blkcount.dp_config, &(buf[count])); - - fwu->has_guest_code = false; - - if (fwu->flash_properties.has_query4) { - retval = synaptics_rmi4_reg_read(rmi4_data, - base + fwu->off.properties_2, - properties_2.data, - sizeof(properties_2.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read flash properties 2\n", - __func__); - return retval; - } - - if (properties_2.has_guest_code) { - retval = synaptics_rmi4_reg_read(rmi4_data, - base + fwu->off.gc_block_count, - buf, - 2); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read guest code block count\n", - __func__); - return retval; - } - - batohs(&fwu->blkcount.guest_code, &(buf[0])); - fwu->has_guest_code = true; - } - } - - return 0; -} - -static int fwu_read_f34_queries(void) -{ - int retval; - - memset(&fwu->blkcount, 0x00, sizeof(fwu->blkcount)); - memset(&fwu->phyaddr, 0x00, sizeof(fwu->phyaddr)); - - if (fwu->bl_version == BL_V7) - retval = fwu_read_f34_v7_queries(); - else - retval = fwu_read_f34_v5v6_queries(); - - return retval; -} - -static int fwu_write_f34_v7_blocks(unsigned char *block_ptr, - unsigned short block_cnt, unsigned char command) -{ - int retval; - unsigned char base; - unsigned char length[2]; - unsigned short transfer; - unsigned short max_transfer; - unsigned short remaining = block_cnt; - unsigned short block_number = 0; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - retval = fwu_write_f34_partition_id(command); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.block_number, - (unsigned char *)&block_number, - sizeof(block_number)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write block number\n", - __func__); - return retval; - } - - if (fwu->payload_length > (PAGE_SIZE / fwu->block_size)) - max_transfer = PAGE_SIZE / fwu->block_size; - else - max_transfer = fwu->payload_length; - - do { - if (remaining / max_transfer) - transfer = max_transfer; - else - transfer = remaining; - - length[0] = (unsigned char)(transfer & MASK_8BIT); - length[1] = (unsigned char)(transfer >> 8); - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.transfer_length, - length, - sizeof(length)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write transfer length (%d blocks remaining)\n", - __func__, remaining); - return retval; - } - - retval = fwu_write_f34_command(command); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write command (%d blocks remaining)\n", - __func__, remaining); - return retval; - } - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.payload, - block_ptr, - transfer * fwu->block_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write block data (%d blocks remaining)\n", - __func__, remaining); - return retval; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wait for idle status (%d blocks remaining)\n", - __func__, remaining); - return retval; - } - - block_ptr += (transfer * fwu->block_size); - remaining -= transfer; - } while (remaining); - - return 0; -} - -static int fwu_write_f34_v5v6_blocks(unsigned char *block_ptr, - unsigned short block_cnt, unsigned char command) -{ - int retval; - unsigned char base; - unsigned char block_number[] = {0, 0}; - unsigned short blk; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - block_number[1] |= (fwu->config_area << 5); - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.block_number, - block_number, - sizeof(block_number)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write block number\n", - __func__); - return retval; - } - - for (blk = 0; blk < block_cnt; blk++) { - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.payload, - 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__, blk); - 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__, blk); - return retval; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wait for idle status (block %d)\n", - __func__, blk); - return retval; - } - - block_ptr += fwu->block_size; - } - - return 0; -} - -static int fwu_write_f34_blocks(unsigned char *block_ptr, - unsigned short block_cnt, unsigned char cmd) -{ - int retval; - - if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) - retval = fwu_write_f34_v7_blocks(block_ptr, block_cnt, cmd); - else - retval = fwu_write_f34_v5v6_blocks(block_ptr, block_cnt, cmd); - - return retval; -} - -static int fwu_read_f34_v7_blocks(unsigned short block_cnt, - unsigned char command) -{ - int retval; - unsigned char base; - unsigned char length[2]; - unsigned short transfer; - unsigned short max_transfer; - unsigned short remaining = block_cnt; - unsigned short block_number = 0; - unsigned short index = 0; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - retval = fwu_write_f34_partition_id(command); - if (retval < 0) - return retval; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.block_number, - (unsigned char *)&block_number, - sizeof(block_number)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write block number\n", - __func__); - return retval; - } - - if (fwu->payload_length > (PAGE_SIZE / fwu->block_size)) - max_transfer = PAGE_SIZE / fwu->block_size; - else - max_transfer = fwu->payload_length; - - do { - if (remaining / max_transfer) - transfer = max_transfer; - else - transfer = remaining; - - length[0] = (unsigned char)(transfer & MASK_8BIT); - length[1] = (unsigned char)(transfer >> 8); - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.transfer_length, - length, - sizeof(length)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write transfer length (%d blocks remaining)\n", - __func__, remaining); - return retval; - } - - retval = fwu_write_f34_command(command); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write command (%d blocks remaining)\n", - __func__, remaining); - return retval; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wait for idle status (%d blocks remaining)\n", - __func__, remaining); - return retval; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + fwu->off.payload, - &fwu->read_config_buf[index], - transfer * fwu->block_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read block data (%d blocks remaining)\n", - __func__, remaining); - return retval; - } - - index += (transfer * fwu->block_size); - remaining -= transfer; - } while (remaining); - - return 0; -} - -static int fwu_read_f34_v5v6_blocks(unsigned short block_cnt, - unsigned char command) -{ - int retval; - unsigned char base; - unsigned char block_number[] = {0, 0}; - unsigned short blk; - unsigned short index = 0; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f34_fd.data_base_addr; - - block_number[1] |= (fwu->config_area << 5); - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + fwu->off.block_number, - block_number, - sizeof(block_number)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write block number\n", - __func__); - return retval; - } - - for (blk = 0; blk < block_cnt; blk++) { - retval = fwu_write_f34_command(command); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write read config command\n", - __func__); - return retval; - } - - retval = fwu_wait_for_idle(WRITE_WAIT_MS, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to wait for idle status\n", - __func__); - return retval; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + fwu->off.payload, - &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__, blk); - return retval; - } - - index += fwu->block_size; - } - - return 0; -} - -static int fwu_read_f34_blocks(unsigned short block_cnt, unsigned char cmd) -{ - int retval; - - if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) - retval = fwu_read_f34_v7_blocks(block_cnt, cmd); - else - retval = fwu_read_f34_v5v6_blocks(block_cnt, cmd); - - return retval; -} - -static int fwu_get_image_firmware_id(unsigned int *fw_id) -{ - int retval; - unsigned char index = 0; - char *strptr; - char *firmware_id; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (fwu->img.contains_firmware_id) { - *fw_id = fwu->img.firmware_id; - } else { - strptr = strnstr(fwu->image_name, "PR", MAX_IMAGE_NAME_LEN); - 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); - return -EINVAL; - } - - strptr += 2; - firmware_id = kzalloc(MAX_FIRMWARE_ID_LEN, GFP_KERNEL); - if (!firmware_id) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for firmware_id\n", - __func__); - return -ENOMEM; - } - while ((index < MAX_FIRMWARE_ID_LEN - 1) && strptr[index] >= '0' - && strptr[index] <= '9') { - firmware_id[index] = strptr[index]; - index++; - } - firmware_id[index] = '\0'; - - retval = sstrtoul(firmware_id, 10, (unsigned long *)fw_id); - kfree(firmware_id); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to obtain image firmware ID\n", - __func__); - return -EINVAL; - } - } - - return 0; -} - -static int fwu_get_device_config_id(void) -{ - int retval; - unsigned char config_id_size; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) - config_id_size = V7_CONFIG_ID_SIZE; - else - config_id_size = V5V6_CONFIG_ID_SIZE; - - retval = synaptics_rmi4_reg_read(rmi4_data, - fwu->f34_fd.ctrl_base_addr, - fwu->config_id, - config_id_size); - if (retval < 0) - return retval; - - return 0; -} - -static enum flash_area fwu_go_nogo(void) -{ - int retval; - enum flash_area flash_area = NONE; - unsigned char ii; - unsigned char config_id_size; - unsigned int device_fw_id; - unsigned int image_fw_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_bl_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 */ - retval = fwu_get_image_firmware_id(&image_fw_id); - if (retval < 0) { - flash_area = NONE; - goto exit; - } - dev_info(rmi4_data->pdev->dev.parent, - "%s: Image firmware ID = %d\n", - __func__, 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 = fwu_get_device_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; - } - - if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) - config_id_size = V7_CONFIG_ID_SIZE; - else - config_id_size = V5V6_CONFIG_ID_SIZE; - - for (ii = 0; ii < config_id_size; ii++) { - if (fwu->img.ui_config.data[ii] > fwu->config_id[ii]) { - flash_area = UI_CONFIG; - goto exit; - } else if (fwu->img.ui_config.data[ii] < fwu->config_id[ii]) { - flash_area = NONE; - 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 and config" : - "UI 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; - bool f35found = false; - struct synaptics_rmi4_fn_desc rmi_fd; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - fwu->in_ub_mode = false; - - 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; - - switch (rmi_fd.fn_version) { - case F34_V0: - fwu->bl_version = BL_V5; - break; - case F34_V1: - fwu->bl_version = BL_V6; - break; - case F34_V2: - fwu->bl_version = BL_V7; - break; - default: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Unrecognized F34 version\n", - __func__); - return -EINVAL; - } - - fwu->intr_mask = 0; - intr_src = rmi_fd.intr_src_count; - intr_off = intr_count % 8; - for (ii = intr_off; - ii < (intr_src + intr_off); - ii++) { - fwu->intr_mask |= 1 << ii; - } - break; - case SYNAPTICS_RMI4_F35: - f35found = true; - fwu->f35_fd.query_base_addr = - rmi_fd.query_base_addr; - fwu->f35_fd.ctrl_base_addr = - rmi_fd.ctrl_base_addr; - fwu->f35_fd.data_base_addr = - rmi_fd.data_base_addr; - break; - } - } else { - break; - } - - intr_count += rmi_fd.intr_src_count; - } - - if (!f01found || !f34found) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find both F01 and F34\n", - __func__); - if (!f35found) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F35\n", - __func__); - return -EINVAL; - } else { - fwu->in_ub_mode = true; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: In microbootloader mode\n", - __func__); - fwu_recovery_check_status(); - return 0; - } - } - - rmi4_data->intr_mask[0] |= fwu->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 int fwu_enter_flash_prog(void) -{ - int retval; - struct f01_device_control f01_device_control; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_read_flash_status(); - if (retval < 0) - return retval; - - if (fwu->in_bl_mode) - return 0; - - retval = rmi4_data->irq_enable(rmi4_data, false, true); - if (retval < 0) - return retval; - - msleep(INT_DISABLE_WAIT_MS); - - retval = fwu_write_f34_command(CMD_ENABLE_FLASH_PROG); - if (retval < 0) - return retval; - - retval = fwu_wait_for_idle(ENABLE_WAIT_MS, false); - if (retval < 0) - return retval; - - if (!fwu->in_bl_mode) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: BL mode not entered\n", - __func__); - return -EINVAL; - } - - if (rmi4_data->hw_if->bl_hw_init) { - retval = rmi4_data->hw_if->bl_hw_init(rmi4_data); - if (retval < 0) - return retval; - } - - retval = fwu_scan_pdt(); - if (retval < 0) - return retval; - - 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; - } - - msleep(ENTER_FLASH_PROG_WAIT_MS); - - return retval; -} - -static int fwu_check_ui_firmware_size(void) -{ - unsigned short block_count; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - block_count = fwu->img.ui_firmware.size / fwu->block_size; - - if (block_count != fwu->blkcount.ui_firmware) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: UI firmware size mismatch\n", - __func__); - return -EINVAL; - } - - return 0; -} - -static int fwu_check_ui_configuration_size(void) -{ - unsigned short block_count; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - block_count = fwu->img.ui_config.size / fwu->block_size; - - if (block_count != fwu->blkcount.ui_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: UI configuration size mismatch\n", - __func__); - return -EINVAL; - } - - return 0; -} - -static int fwu_check_dp_configuration_size(void) -{ - unsigned short block_count; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - block_count = fwu->img.dp_config.size / fwu->block_size; - - if (block_count != fwu->blkcount.dp_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Display configuration size mismatch\n", - __func__); - return -EINVAL; - } - - return 0; -} - -static int fwu_check_pm_configuration_size(void) -{ - unsigned short block_count; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - block_count = fwu->img.pm_config.size / fwu->block_size; - - if (block_count != fwu->blkcount.pm_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Permanent configuration size mismatch\n", - __func__); - return -EINVAL; - } - - return 0; -} - -static int fwu_check_bl_configuration_size(void) -{ - unsigned short block_count; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - block_count = fwu->img.bl_config.size / fwu->block_size; - - if (block_count != fwu->blkcount.bl_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Bootloader configuration size mismatch\n", - __func__); - return -EINVAL; - } - - return 0; -} - -static int fwu_check_guest_code_size(void) -{ - unsigned short block_count; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - block_count = fwu->img.guest_code.size / fwu->block_size; - if (block_count != fwu->blkcount.guest_code) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Guest code size mismatch\n", - __func__); - return -EINVAL; - } - - return 0; -} - -static int fwu_write_firmware(void) -{ - unsigned short firmware_block_count; - - firmware_block_count = fwu->img.ui_firmware.size / fwu->block_size; - - return fwu_write_f34_blocks((unsigned char *)fwu->img.ui_firmware.data, - firmware_block_count, CMD_WRITE_FW); -} - -static int fwu_erase_configuration(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_UI_CONFIG); - if (retval < 0) - return retval; - break; - case DP_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_DISP_CONFIG); - if (retval < 0) - return retval; - break; - case BL_CONFIG_AREA: - retval = fwu_write_f34_command(CMD_ERASE_BL_CONFIG); - if (retval < 0) - return retval; - break; - } - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Erase command written\n", - __func__); - - retval = fwu_wait_for_idle(ERASE_WAIT_MS, false); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Idle status detected\n", - __func__); - - return retval; -} - -static int fwu_erase_guest_code(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_write_f34_command(CMD_ERASE_GUEST_CODE); - 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, false); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Idle status detected\n", - __func__); - - return 0; -} - -static int fwu_erase_all(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - if (fwu->bl_version == BL_V7) { - retval = fwu_write_f34_command(CMD_ERASE_UI_FIRMWARE); - 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, false); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Idle status detected\n", - __func__); - - fwu->config_area = UI_CONFIG_AREA; - retval = fwu_erase_configuration(); - if (retval < 0) - return retval; - } else { - 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, false); - if (!(fwu->bl_version == BL_V8 && - fwu->flash_status == BAD_PARTITION_TABLE)) { - if (retval < 0) - return retval; - } - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Idle status detected\n", - __func__); - - if (fwu->bl_version == BL_V8) - return 0; - } - - if (fwu->flash_properties.has_disp_config && - fwu->img.contains_disp_config) { - fwu->config_area = DP_CONFIG_AREA; - retval = fwu_erase_configuration(); - if (retval < 0) - return retval; - } - - if (fwu->has_guest_code && fwu->img.contains_guest_code) { - retval = fwu_erase_guest_code(); - if (retval < 0) - return retval; - } - - return 0; -} - -static int fwu_write_configuration(void) -{ - return fwu_write_f34_blocks((unsigned char *)fwu->config_data, - fwu->config_block_count, CMD_WRITE_CONFIG); -} - -static int fwu_write_ui_configuration(void) -{ - fwu->config_area = UI_CONFIG_AREA; - fwu->config_data = fwu->img.ui_config.data; - fwu->config_size = fwu->img.ui_config.size; - fwu->config_block_count = fwu->config_size / fwu->block_size; - - return fwu_write_configuration(); -} - -static int fwu_write_dp_configuration(void) -{ - fwu->config_area = DP_CONFIG_AREA; - fwu->config_data = fwu->img.dp_config.data; - fwu->config_size = fwu->img.dp_config.size; - fwu->config_block_count = fwu->config_size / fwu->block_size; - - return fwu_write_configuration(); -} - -static int fwu_write_pm_configuration(void) -{ - fwu->config_area = PM_CONFIG_AREA; - fwu->config_data = fwu->img.pm_config.data; - fwu->config_size = fwu->img.pm_config.size; - fwu->config_block_count = fwu->config_size / fwu->block_size; - - return fwu_write_configuration(); -} - -static int fwu_write_flash_configuration(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - fwu->config_area = FLASH_CONFIG_AREA; - fwu->config_data = fwu->img.fl_config.data; - fwu->config_size = fwu->img.fl_config.size; - fwu->config_block_count = fwu->config_size / fwu->block_size; - - if (fwu->config_block_count != fwu->blkcount.fl_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Flash configuration size mismatch\n", - __func__); - return -EINVAL; - } - - retval = fwu_write_f34_command(CMD_ERASE_FLASH_CONFIG); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Erase flash configuration command written\n", - __func__); - - retval = fwu_wait_for_idle(ERASE_WAIT_MS, false); - if (retval < 0) - return retval; - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Idle status detected\n", - __func__); - - retval = fwu_write_configuration(); - if (retval < 0) - return retval; - - rmi4_data->reset_device(rmi4_data, false); - - return 0; -} - -static int fwu_write_guest_code(void) -{ - int retval; - unsigned short guest_code_block_count; - - guest_code_block_count = fwu->img.guest_code.size / fwu->block_size; - - retval = fwu_write_f34_blocks((unsigned char *)fwu->img.guest_code.data, - guest_code_block_count, CMD_WRITE_GUEST_CODE); - if (retval < 0) - return retval; - - return 0; -} - -static int fwu_write_lockdown(void) -{ - unsigned short lockdown_block_count; - - lockdown_block_count = fwu->img.lockdown.size / fwu->block_size; - - return fwu_write_f34_blocks((unsigned char *)fwu->img.lockdown.data, - lockdown_block_count, CMD_WRITE_LOCKDOWN); -} - -static int fwu_write_partition_table_v8(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - fwu->config_area = FLASH_CONFIG_AREA; - fwu->config_data = fwu->img.fl_config.data; - fwu->config_size = fwu->img.fl_config.size; - fwu->config_block_count = fwu->config_size / fwu->block_size; - - if (fwu->config_block_count != fwu->blkcount.fl_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Flash configuration size mismatch\n", - __func__); - return -EINVAL; - } - - retval = fwu_write_configuration(); - if (retval < 0) - return retval; - - rmi4_data->reset_device(rmi4_data, false); - - return 0; -} - -static int fwu_write_partition_table_v7(void) -{ - int retval; - unsigned short block_count; - - block_count = fwu->blkcount.bl_config; - fwu->config_area = BL_CONFIG_AREA; - fwu->config_size = fwu->block_size * block_count; - - retval = fwu_allocate_read_config_buf(fwu->config_size); - if (retval < 0) - return retval; - - retval = fwu_read_f34_blocks(block_count, CMD_READ_CONFIG); - if (retval < 0) - return retval; - - retval = fwu_erase_configuration(); - if (retval < 0) - return retval; - - retval = fwu_write_flash_configuration(); - if (retval < 0) - return retval; - - fwu->config_area = BL_CONFIG_AREA; - fwu->config_data = fwu->read_config_buf; - fwu->config_size = fwu->img.bl_config.size; - fwu->config_block_count = fwu->config_size / fwu->block_size; - - retval = fwu_write_configuration(); - if (retval < 0) - return retval; - - return 0; -} - -static int fwu_do_reflash(void) -{ - int retval; - - if (!fwu->new_partition_table) { - retval = fwu_check_ui_firmware_size(); - if (retval < 0) - return retval; - - retval = fwu_check_ui_configuration_size(); - if (retval < 0) - return retval; - - if (fwu->flash_properties.has_disp_config && - fwu->img.contains_disp_config) { - retval = fwu_check_dp_configuration_size(); - if (retval < 0) - return retval; - } - - if (fwu->has_guest_code && fwu->img.contains_guest_code) { - retval = fwu_check_guest_code_size(); - if (retval < 0) - return retval; - } - } else if (fwu->bl_version == BL_V7) { - retval = fwu_check_bl_configuration_size(); - if (retval < 0) - return retval; - } - - retval = fwu_erase_all(); - if (retval < 0) - return retval; - - if (fwu->bl_version == BL_V7 && fwu->new_partition_table) { - retval = fwu_write_partition_table_v7(); - if (retval < 0) - return retval; - pr_notice("%s: Partition table programmed\n", __func__); - } else if (fwu->bl_version == BL_V8) { - retval = fwu_write_partition_table_v8(); - if (retval < 0) - return retval; - pr_notice("%s: Partition table programmed\n", __func__); - } - - retval = fwu_write_firmware(); - if (retval < 0) - return retval; - pr_notice("%s: Firmware programmed\n", __func__); - - fwu->config_area = UI_CONFIG_AREA; - retval = fwu_write_ui_configuration(); - if (retval < 0) - return retval; - pr_notice("%s: Configuration programmed\n", __func__); - - if (fwu->flash_properties.has_disp_config && - fwu->img.contains_disp_config) { - retval = fwu_write_dp_configuration(); - if (retval < 0) - return retval; - pr_notice("%s: Display configuration programmed\n", __func__); - } - - if (fwu->has_guest_code && fwu->img.contains_guest_code) { - retval = fwu_write_guest_code(); - if (retval < 0) - return retval; - pr_notice("%s: Guest code programmed\n", __func__); - } - - return retval; -} - -static int fwu_do_read_config(void) -{ - int retval; - unsigned short block_count; - unsigned short config_area; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - block_count = fwu->blkcount.ui_config; - break; - case DP_CONFIG_AREA: - if (!fwu->flash_properties.has_disp_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Display configuration not supported\n", - __func__); - return -EINVAL; - } - block_count = fwu->blkcount.dp_config; - break; - case PM_CONFIG_AREA: - if (!fwu->flash_properties.has_pm_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Permanent configuration not supported\n", - __func__); - return -EINVAL; - } - block_count = fwu->blkcount.pm_config; - break; - case BL_CONFIG_AREA: - if (!fwu->flash_properties.has_bl_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Bootloader configuration not supported\n", - __func__); - return -EINVAL; - } - block_count = fwu->blkcount.bl_config; - break; - default: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid config area\n", - __func__); - return -EINVAL; - } - - if (block_count == 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid block count\n", - __func__); - return -EINVAL; - } - - mutex_lock(&rmi4_data->rmi4_exp_init_mutex); - - config_area = fwu->config_area; - - retval = fwu_enter_flash_prog(); - if (retval < 0) - goto exit; - - fwu->config_area = config_area; - - fwu->config_size = fwu->block_size * block_count; - - retval = fwu_allocate_read_config_buf(fwu->config_size); - if (retval < 0) - goto exit; - - retval = fwu_read_f34_blocks(block_count, CMD_READ_CONFIG); - -exit: - rmi4_data->reset_device(rmi4_data, false); - - mutex_unlock(&rmi4_data->rmi4_exp_init_mutex); - - return retval; -} - -static int fwu_do_lockdown_v7(void) -{ - int retval; - struct f34_v7_data0 status; - 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.data_base_addr + fwu->off.flash_status, - status.data, - sizeof(status.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read flash status\n", - __func__); - return retval; - } - - if (status.device_cfg_status == 2) { - dev_info(rmi4_data->pdev->dev.parent, - "%s: Device already locked down\n", - __func__); - return 0; - } - - retval = fwu_write_lockdown(); - if (retval < 0) - return retval; - - pr_notice("%s: Lockdown programmed\n", __func__); - - return retval; -} - -static int fwu_do_lockdown_v5v6(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->off.properties, - fwu->flash_properties.data, - sizeof(fwu->flash_properties.data)); - 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 0; - } - - retval = fwu_write_lockdown(); - if (retval < 0) - return retval; - - pr_notice("%s: Lockdown programmed\n", __func__); - - return retval; -} - -static int fwu_start_write_guest_code(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_parse_image_info(); - if (retval < 0) - return -EINVAL; - - if (!fwu->has_guest_code) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Guest code not supported\n", - __func__); - return -EINVAL; - } - - if (!fwu->img.contains_guest_code) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: No guest code in firmware image\n", - __func__); - return -EINVAL; - } - - if (rmi4_data->sensor_sleep) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Sensor sleeping\n", - __func__); - return -ENODEV; - } - - rmi4_data->stay_awake = true; - - mutex_lock(&rmi4_data->rmi4_exp_init_mutex); - - pr_notice("%s: Start of write guest code process\n", __func__); - - retval = fwu_enter_flash_prog(); - if (retval < 0) - goto exit; - - retval = fwu_check_guest_code_size(); - if (retval < 0) - goto exit; - - retval = fwu_erase_guest_code(); - if (retval < 0) - goto exit; - - retval = fwu_write_guest_code(); - if (retval < 0) - goto exit; - - pr_notice("%s: Guest code programmed\n", __func__); - -exit: - rmi4_data->reset_device(rmi4_data, false); - - pr_notice("%s: End of write guest code process\n", __func__); - - mutex_unlock(&rmi4_data->rmi4_exp_init_mutex); - - rmi4_data->stay_awake = false; - - return retval; -} - -static int fwu_start_write_config(void) -{ - int retval; - unsigned short config_area; - unsigned int device_fw_id; - unsigned int image_fw_id; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = fwu_parse_image_info(); - if (retval < 0) - return -EINVAL; - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - device_fw_id = rmi4_data->firmware_id; - retval = fwu_get_image_firmware_id(&image_fw_id); - if (retval < 0) - return retval; - if (device_fw_id != image_fw_id) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Device and image firmware IDs don't match\n", - __func__); - return -EINVAL; - } - retval = fwu_check_ui_configuration_size(); - if (retval < 0) - return retval; - break; - case DP_CONFIG_AREA: - if (!fwu->flash_properties.has_disp_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Display configuration not supported\n", - __func__); - return -EINVAL; - } - if (!fwu->img.contains_disp_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: No display configuration in firmware image\n", - __func__); - return -EINVAL; - } - retval = fwu_check_dp_configuration_size(); - if (retval < 0) - return retval; - break; - case PM_CONFIG_AREA: - if (!fwu->flash_properties.has_pm_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Permanent configuration not supported\n", - __func__); - return -EINVAL; - } - if (!fwu->img.contains_perm_config) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: No permanent configuration in firmware image\n", - __func__); - return -EINVAL; - } - retval = fwu_check_pm_configuration_size(); - if (retval < 0) - return retval; - break; - default: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Configuration not supported\n", - __func__); - return -EINVAL; - } - - if (rmi4_data->sensor_sleep) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Sensor sleeping\n", - __func__); - return -ENODEV; - } - - rmi4_data->stay_awake = true; - - mutex_lock(&rmi4_data->rmi4_exp_init_mutex); - - pr_notice("%s: Start of write config process\n", __func__); - - config_area = fwu->config_area; - - retval = fwu_enter_flash_prog(); - if (retval < 0) - goto exit; - - fwu->config_area = config_area; - - if (fwu->config_area != PM_CONFIG_AREA) { - retval = fwu_erase_configuration(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to erase config\n", - __func__); - goto exit; - } - } - - switch (fwu->config_area) { - case UI_CONFIG_AREA: - retval = fwu_write_ui_configuration(); - if (retval < 0) - goto exit; - break; - case DP_CONFIG_AREA: - retval = fwu_write_dp_configuration(); - if (retval < 0) - goto exit; - break; - case PM_CONFIG_AREA: - retval = fwu_write_pm_configuration(); - if (retval < 0) - goto exit; - break; - } - - pr_notice("%s: Config written\n", __func__); - -exit: - switch (fwu->config_area) { - case UI_CONFIG_AREA: - rmi4_data->reset_device(rmi4_data, true); - break; - case DP_CONFIG_AREA: - case PM_CONFIG_AREA: - rmi4_data->reset_device(rmi4_data, false); - break; - } - - pr_notice("%s: End of write config process\n", __func__); - - mutex_unlock(&rmi4_data->rmi4_exp_init_mutex); - - rmi4_data->stay_awake = false; - - return retval; -} - -static int fwu_start_reflash(void) -{ - int retval = 0; - enum flash_area flash_area; - 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; - - mutex_lock(&rmi4_data->rmi4_exp_init_mutex); - - pr_notice("%s: Start of reflash process\n", __func__); - - if (fwu->image == NULL) { - retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN, - FW_IMAGE_NAME, sizeof(FW_IMAGE_NAME), - sizeof(FW_IMAGE_NAME)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy image file name\n", - __func__); - goto exit; - } - 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 = %d\n", - __func__, (unsigned int)fw_entry->size); - - fwu->image = fw_entry->data; - } - - retval = fwu_parse_image_info(); - if (retval < 0) - goto exit; - - if (fwu->blkcount.total_count != fwu->img.blkcount.total_count) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Flash size mismatch\n", - __func__); - retval = -EINVAL; - goto exit; - } - - if (fwu->bl_version != fwu->img.bl_version) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Bootloader version mismatch\n", - __func__); - retval = -EINVAL; - goto exit; - } - - if (!fwu->force_update && fwu->new_partition_table) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Partition table mismatch\n", - __func__); - retval = -EINVAL; - goto exit; - } - - retval = fwu_read_flash_status(); - if (retval < 0) - goto exit; - - if (fwu->in_bl_mode) { - dev_info(rmi4_data->pdev->dev.parent, - "%s: Device in bootloader mode\n", - __func__); - } - - flash_area = fwu_go_nogo(); - - if (flash_area != NONE) { - retval = fwu_enter_flash_prog(); - if (retval < 0) { - rmi4_data->reset_device(rmi4_data, false); - goto exit; - } - } - - switch (flash_area) { - case UI_FIRMWARE: - retval = fwu_do_reflash(); - rmi4_data->reset_device(rmi4_data, true); - break; - case UI_CONFIG: - retval = fwu_check_ui_configuration_size(); - if (retval < 0) - break; - fwu->config_area = UI_CONFIG_AREA; - retval = fwu_erase_configuration(); - if (retval < 0) - break; - retval = fwu_write_ui_configuration(); - rmi4_data->reset_device(rmi4_data, true); - break; - case NONE: - default: - rmi4_data->reset_device(rmi4_data, false); - break; - } - - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do reflash\n", - __func__); - goto exit; - } - - if (fwu->do_lockdown && (fwu->img.lockdown.data != NULL)) { - switch (fwu->bl_version) { - case BL_V5: - case BL_V6: - retval = fwu_do_lockdown_v5v6(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do lockdown\n", - __func__); - } - rmi4_data->reset_device(rmi4_data, false); - break; - case BL_V7: - case BL_V8: - retval = fwu_do_lockdown_v7(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do lockdown\n", - __func__); - } - rmi4_data->reset_device(rmi4_data, false); - break; - default: - break; - } - } - -exit: - if (fw_entry) - release_firmware(fw_entry); - - pr_notice("%s: End of reflash process\n", __func__); - - mutex_unlock(&rmi4_data->rmi4_exp_init_mutex); - - rmi4_data->stay_awake = false; - - return retval; -} - -static int fwu_recovery_check_status(void) -{ - int retval; - unsigned char base; - unsigned char status; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f35_fd.data_base_addr; - - retval = synaptics_rmi4_reg_read(rmi4_data, - base + F35_ERROR_CODE_OFFSET, - &status, - 1); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read status\n", - __func__); - return retval; - } - - status = status & MASK_7BIT; - - if (status != 0x00) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Recovery mode status = %d\n", - __func__, status); - return -EINVAL; - } - - return 0; -} - -static int fwu_recovery_erase_all(void) -{ - int retval; - unsigned char base; - unsigned char command = CMD_F35_ERASE_ALL; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f35_fd.ctrl_base_addr; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + F35_CHUNK_COMMAND_OFFSET, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue erase all command\n", - __func__); - return retval; - } - - msleep(F35_ERASE_ALL_WAIT_MS); - - retval = fwu_recovery_check_status(); - if (retval < 0) - return retval; - - return 0; -} - -static int fwu_recovery_write_chunk(void) -{ - int retval; - unsigned char base; - unsigned char chunk_number[] = {0, 0}; - unsigned char chunk_spare; - unsigned char chunk_size; - unsigned char buf[F35_CHUNK_SIZE + 1]; - unsigned short chunk; - unsigned short chunk_total; - unsigned short bytes_written = 0; - unsigned char *chunk_ptr = (unsigned char *)fwu->image; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f35_fd.ctrl_base_addr; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + F35_CHUNK_NUM_LSB_OFFSET, - chunk_number, - sizeof(chunk_number)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write chunk number\n", - __func__); - return retval; - } - - buf[sizeof(buf) - 1] = CMD_F35_WRITE_CHUNK; - - chunk_total = fwu->image_size / F35_CHUNK_SIZE; - chunk_spare = fwu->image_size % F35_CHUNK_SIZE; - if (chunk_spare) - chunk_total++; - - for (chunk = 0; chunk < chunk_total; chunk++) { - if (chunk_spare && chunk == chunk_total - 1) - chunk_size = chunk_spare; - else - chunk_size = F35_CHUNK_SIZE; - - memset(buf, 0x00, F35_CHUNK_SIZE); - secure_memcpy(buf, sizeof(buf), chunk_ptr, - fwu->image_size - bytes_written, - chunk_size); - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + F35_CHUNK_DATA_OFFSET, - buf, - sizeof(buf)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write chunk data (chunk %d)\n", - __func__, chunk); - return retval; - } - chunk_ptr += chunk_size; - bytes_written += chunk_size; - } - - retval = fwu_recovery_check_status(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write chunk data\n", - __func__); - return retval; - } - - return 0; -} - -static int fwu_recovery_reset(void) -{ - int retval; - unsigned char base; - unsigned char command = CMD_F35_RESET; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - base = fwu->f35_fd.ctrl_base_addr; - - retval = synaptics_rmi4_reg_write(rmi4_data, - base + F35_CHUNK_COMMAND_OFFSET, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to issue reset command\n", - __func__); - return retval; - } - - msleep(F35_RESET_WAIT_MS); - - return 0; -} - -static int fwu_start_recovery(void) -{ - int retval; - 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; - - mutex_lock(&rmi4_data->rmi4_exp_init_mutex); - - pr_notice("%s: Start of recovery process\n", __func__); - - retval = rmi4_data->irq_enable(rmi4_data, false, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to disable interrupt\n", - __func__); - goto exit; - } - - retval = fwu_recovery_erase_all(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do erase all in recovery mode\n", - __func__); - goto exit; - } - - pr_notice("%s: External flash erased\n", __func__); - - retval = fwu_recovery_write_chunk(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write chunk data in recovery mode\n", - __func__); - goto exit; - } - - pr_notice("%s: Chunk data programmed\n", __func__); - - retval = fwu_recovery_reset(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to reset device in recovery mode\n", - __func__); - goto exit; - } - - pr_notice("%s: Recovery mode reset issued\n", __func__); - - rmi4_data->reset_device(rmi4_data, true); - - retval = 0; - -exit: - pr_notice("%s: End of recovery process\n", __func__); - - mutex_unlock(&rmi4_data->rmi4_exp_init_mutex); - - rmi4_data->stay_awake = false; - - return retval; -} - -int synaptics_fw_updater(const unsigned char *fw_data) -{ - int retval; - - if (!fwu) - return -ENODEV; - - if (!fwu->initialized) - return -ENODEV; - - if (fwu->in_ub_mode) - return -ENODEV; - - fwu->image = fw_data; - - retval = fwu_start_reflash(); - - fwu->image = NULL; - - return retval; -} -EXPORT_SYMBOL(synaptics_fw_updater); - -#ifdef DO_STARTUP_FW_UPDATE -static void fwu_startup_fw_update_work(struct work_struct *work) -{ - static unsigned char do_once = 1; -#ifdef WAIT_FOR_FB_READY - unsigned int timeout; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; -#endif - - if (!do_once) - return; - do_once = 0; - -#ifdef WAIT_FOR_FB_READY - timeout = FB_READY_TIMEOUT_S * 1000 / FB_READY_WAIT_MS + 1; - - while (!rmi4_data->fb_ready) { - msleep(FB_READY_WAIT_MS); - timeout--; - if (timeout == 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Timed out waiting for FB ready\n", - __func__); - return; - } - } -#endif - - synaptics_fw_updater(NULL); - - return; -} -#endif - -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) -{ - int retval; - 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 (%d bytes) in buffer\n", - __func__, (unsigned int)count); - return -EINVAL; - } - - retval = secure_memcpy(buf, count, fwu->read_config_buf, - fwu->read_config_buf_size, fwu->config_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy config data\n", - __func__); - return retval; - } - - 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) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = secure_memcpy(&fwu->ext_data_source[fwu->data_pos], - fwu->image_size - fwu->data_pos, buf, count, count); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy image data\n", - __func__); - return retval; - } - - fwu->data_pos += count; - - return count; -} - -static ssize_t fwu_sysfs_do_recovery_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 (!fwu->in_ub_mode) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Not in microbootloader mode\n", - __func__); - retval = -EINVAL; - goto exit; - } - - if (!fwu->ext_data_source) - return -EINVAL; - else - fwu->image = fwu->ext_data_source; - - retval = fwu_start_recovery(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do recovery\n", - __func__); - goto exit; - } - - retval = count; - -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - fwu->image = NULL; - 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 (fwu->in_ub_mode) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: In microbootloader mode\n", - __func__); - retval = -EINVAL; - goto exit; - } - - if (!fwu->ext_data_source) - return -EINVAL; - else - fwu->image = fwu->ext_data_source; - - 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(fwu->image); - 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->image = 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; - } - - if (fwu->in_ub_mode) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: In microbootloader mode\n", - __func__); - retval = -EINVAL; - goto exit; - } - - if (!fwu->ext_data_source) - return -EINVAL; - else - fwu->image = fwu->ext_data_source; - - 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; - fwu->image = 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; - - if (fwu->in_ub_mode) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: In microbootloader mode\n", - __func__); - 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_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; - - retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN, - buf, count, count); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy image file name\n", - __func__); - return retval; - } - - 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->blkcount.ui_firmware); -} - -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->blkcount.ui_config); -} - -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->blkcount.dp_config); -} - -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->blkcount.pm_config); -} - -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->blkcount.bl_config); -} - -static ssize_t fwu_sysfs_guest_code_block_count_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", fwu->blkcount.guest_code); -} - -static ssize_t fwu_sysfs_write_guest_code_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 (fwu->in_ub_mode) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: In microbootloader mode\n", - __func__); - retval = -EINVAL; - goto exit; - } - - if (!fwu->ext_data_source) - return -EINVAL; - else - fwu->image = fwu->ext_data_source; - - retval = fwu_start_write_guest_code(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write guest code\n", - __func__); - goto exit; - } - - retval = count; - -exit: - kfree(fwu->ext_data_source); - fwu->ext_data_source = NULL; - fwu->image = NULL; - return retval; -} - -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_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; - - if (fwu) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Handle already exists\n", - __func__); - return 0; - } - - 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 = kzalloc(MAX_IMAGE_NAME_LEN, GFP_KERNEL); - if (!fwu->image_name) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for image name\n", - __func__); - retval = -ENOMEM; - goto exit_free_fwu; - } - - 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_mem; - } - - retval = fwu_scan_pdt(); - if (retval < 0) - goto exit_free_mem; - - if (!fwu->in_ub_mode) { - retval = fwu_read_f34_queries(); - if (retval < 0) - goto exit_free_mem; - - retval = fwu_get_device_config_id(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read device config ID\n", - __func__); - goto exit_free_mem; - } - } - - 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_mem; - } - - 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; - } - } - -#ifdef DO_STARTUP_FW_UPDATE - fwu->fwu_workqueue = create_singlethread_workqueue("fwu_workqueue"); - INIT_WORK(&fwu->fwu_work, fwu_startup_fw_update_work); - queue_work(fwu->fwu_workqueue, - &fwu->fwu_work); -#endif - - 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_mem: - kfree(fwu->image_name); - -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; - -#ifdef DO_STARTUP_FW_UPDATE - cancel_work_sync(&fwu->fwu_work); - flush_workqueue(fwu->fwu_workqueue); - destroy_workqueue(fwu->fwu_workqueue); -#endif - - 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->image_name); - kfree(fwu); - fwu = NULL; - -exit: - complete(&fwu_remove_complete); - - return; -} - -static void synaptics_rmi4_fwu_reset(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - - if (!fwu) { - synaptics_rmi4_fwu_init(rmi4_data); - return; - } - - retval = fwu_scan_pdt(); - if (retval < 0) - return; - - if (!fwu->in_ub_mode) - fwu_read_f34_queries(); - - 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 = synaptics_rmi4_fwu_reset, - .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_new_function(&fwu_module, true); - - return 0; -} - -static void __exit rmi4_fw_update_module_exit(void) -{ - synaptics_rmi4_new_function(&fwu_module, false); - - 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("Synaptics DSX FW Update Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_gesture.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_gesture.c deleted file mode 100644 index de8656389cad..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_gesture.c +++ /dev/null @@ -1,2308 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define GESTURE_PHYS_NAME "synaptics_dsx/gesture" - -#define TUNING_SYSFS_DIR_NAME "tuning" - -#define STORE_GESTURES -#ifdef STORE_GESTURES -#define GESTURES_TO_STORE 10 -#endif - -#define CTRL23_FINGER_REPORT_ENABLE_BIT 0 -#define CTRL27_UDG_ENABLE_BIT 4 -#define WAKEUP_GESTURE_MODE 0x02 - -static ssize_t udg_sysfs_engine_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_detection_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_detection_score_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_detection_index_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_registration_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_registration_begin_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_registration_status_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_template_size_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_template_max_index_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_template_detection_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_template_index_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_template_valid_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_template_valid_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_template_clear_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_trace_size_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_template_data_show(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t udg_sysfs_template_data_store(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t udg_sysfs_trace_data_show(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t udg_sysfs_template_displacement_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_template_displacement_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_rotation_invariance_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_rotation_invariance_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_scale_invariance_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_scale_invariance_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_threshold_factor_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_threshold_factor_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_match_metric_threshold_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_match_metric_threshold_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t udg_sysfs_max_inter_stroke_time_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t udg_sysfs_max_inter_stroke_time_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static int udg_read_tuning_params(void); - -static int udg_write_tuning_params(void); - -static int udg_detection_enable(bool enable); - -static int udg_engine_enable(bool enable); - -static int udg_set_index(unsigned char index); - -#ifdef STORE_GESTURES -static int udg_read_valid_data(void); -static int udg_write_valid_data(void); -static int udg_read_template_data(unsigned char index); -static int udg_write_template_data(void); -#endif - -enum gesture_type { - DETECTION = 0x0f, - REGISTRATION = 0x10, -}; - -struct udg_tuning { - union { - struct { - unsigned char maximum_number_of_templates; - unsigned char template_size; - unsigned char template_disp_lsb; - unsigned char template_disp_msb; - unsigned char rotation_inv_lsb; - unsigned char rotation_inv_msb; - unsigned char scale_inv_lsb; - unsigned char scale_inv_msb; - unsigned char thres_factor_lsb; - unsigned char thres_factor_msb; - unsigned char metric_thres_lsb; - unsigned char metric_thres_msb; - unsigned char inter_stroke_lsb; - unsigned char inter_stroke_msb; - } __packed; - unsigned char data[14]; - }; -}; - -struct udg_addr { - unsigned short data_4; - unsigned short ctrl_18; - unsigned short ctrl_20; - unsigned short ctrl_23; - unsigned short ctrl_27; - unsigned short ctrl_41; - unsigned short trace_x; - unsigned short trace_y; - unsigned short trace_segment; - unsigned short template_helper; - unsigned short template_data; - unsigned short template_flags; -}; - -struct synaptics_rmi4_f12_query_0 { - union { - struct { - struct { - unsigned char has_register_descriptors:1; - unsigned char has_closed_cover:1; - unsigned char has_fast_glove_detect:1; - unsigned char has_dribble:1; - unsigned char has_4p4_jitter_filter_strength:1; - unsigned char f12_query0_s0_b5__7:3; - } __packed; - struct { - unsigned char max_num_templates:4; - unsigned char f12_query0_s1_b4__7:4; - unsigned char template_size_lsb; - unsigned char template_size_msb; - } __packed; - }; - unsigned char data[4]; - }; -}; - -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; - struct { - unsigned char ctrl32_is_present:1; - unsigned char ctrl33_is_present:1; - unsigned char ctrl34_is_present:1; - unsigned char ctrl35_is_present:1; - unsigned char ctrl36_is_present:1; - unsigned char ctrl37_is_present:1; - unsigned char ctrl38_is_present:1; - unsigned char ctrl39_is_present:1; - } __packed; - struct { - unsigned char ctrl40_is_present:1; - unsigned char ctrl41_is_present:1; - unsigned char ctrl42_is_present:1; - unsigned char ctrl43_is_present:1; - unsigned char ctrl44_is_present:1; - unsigned char ctrl45_is_present:1; - unsigned char ctrl46_is_present:1; - unsigned char ctrl47_is_present:1; - } __packed; - }; - unsigned char data[7]; - }; -}; - -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; - struct { - unsigned char data16_is_present:1; - unsigned char data17_is_present:1; - unsigned char data18_is_present:1; - unsigned char data19_is_present:1; - unsigned char data20_is_present:1; - unsigned char data21_is_present:1; - unsigned char data22_is_present:1; - unsigned char data23_is_present:1; - } __packed; - }; - unsigned char data[4]; - }; -}; - -struct synaptics_rmi4_f12_control_41 { - union { - struct { - unsigned char enable_registration:1; - unsigned char template_index:4; - unsigned char begin:1; - unsigned char f12_ctrl41_b6__7:2; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_udg_handle { - atomic_t attn_event; - unsigned char intr_mask; - unsigned char report_flags; - unsigned char object_type_enable1; - unsigned char object_type_enable2; - unsigned char trace_size; - unsigned char template_index; - unsigned char max_num_templates; - unsigned char detection_score; - unsigned char detection_index; - unsigned char detection_status; - unsigned char registration_status; - unsigned char *ctrl_buf; - unsigned char *trace_data_buf; - unsigned char *template_data_buf; -#ifdef STORE_GESTURES - unsigned char gestures_to_store; - unsigned char *storage_buf; - unsigned char valid_buf[2]; -#endif - unsigned short trace_data_buf_size; - unsigned short template_size; - unsigned short template_data_size; - unsigned short query_base_addr; - unsigned short control_base_addr; - unsigned short data_base_addr; - unsigned short command_base_addr; - unsigned short ctrl_18_sub10_off; - unsigned short ctrl_20_sub1_off; - unsigned short ctrl_23_sub3_off; - unsigned short ctrl_27_sub5_off; - struct input_dev *udg_dev; - struct kobject *tuning_dir; - struct udg_addr addr; - struct udg_tuning tuning; - struct synaptics_rmi4_data *rmi4_data; -}; - -static struct device_attribute attrs[] = { - __ATTR(engine_enable, S_IWUGO, - NULL, - udg_sysfs_engine_enable_store), - __ATTR(detection_enable, S_IWUGO, - NULL, - udg_sysfs_detection_enable_store), - __ATTR(detection_score, S_IRUGO, - udg_sysfs_detection_score_show, - NULL), - __ATTR(detection_index, S_IRUGO, - udg_sysfs_detection_index_show, - NULL), - __ATTR(registration_enable, S_IWUGO, - NULL, - udg_sysfs_registration_enable_store), - __ATTR(registration_begin, S_IWUGO, - NULL, - udg_sysfs_registration_begin_store), - __ATTR(registration_status, S_IRUGO, - udg_sysfs_registration_status_show, - NULL), - __ATTR(template_size, S_IRUGO, - udg_sysfs_template_size_show, - NULL), - __ATTR(template_max_index, S_IRUGO, - udg_sysfs_template_max_index_show, - NULL), - __ATTR(template_detection, S_IRUGO, - udg_sysfs_template_detection_show, - NULL), - __ATTR(template_index, S_IWUGO, - NULL, - udg_sysfs_template_index_store), - __ATTR(template_valid, (S_IRUGO | S_IWUGO), - udg_sysfs_template_valid_show, - udg_sysfs_template_valid_store), - __ATTR(template_clear, S_IWUGO, - NULL, - udg_sysfs_template_clear_store), - __ATTR(trace_size, S_IRUGO, - udg_sysfs_trace_size_show, - NULL), -}; - -static struct bin_attribute template_data = { - .attr = { - .name = "template_data", - .mode = (S_IRUGO | S_IWUGO), - }, - .size = 0, - .read = udg_sysfs_template_data_show, - .write = udg_sysfs_template_data_store, -}; - -static struct bin_attribute trace_data = { - .attr = { - .name = "trace_data", - .mode = S_IRUGO, - }, - .size = 0, - .read = udg_sysfs_trace_data_show, - .write = NULL, -}; - -static struct device_attribute params[] = { - __ATTR(template_displacement, (S_IRUGO | S_IWUGO), - udg_sysfs_template_displacement_show, - udg_sysfs_template_displacement_store), - __ATTR(rotation_invariance, (S_IRUGO | S_IWUGO), - udg_sysfs_rotation_invariance_show, - udg_sysfs_rotation_invariance_store), - __ATTR(scale_invariance, (S_IRUGO | S_IWUGO), - udg_sysfs_scale_invariance_show, - udg_sysfs_scale_invariance_store), - __ATTR(threshold_factor, (S_IRUGO | S_IWUGO), - udg_sysfs_threshold_factor_show, - udg_sysfs_threshold_factor_store), - __ATTR(match_metric_threshold, (S_IRUGO | S_IWUGO), - udg_sysfs_match_metric_threshold_show, - udg_sysfs_match_metric_threshold_store), - __ATTR(max_inter_stroke_time, (S_IRUGO | S_IWUGO), - udg_sysfs_max_inter_stroke_time_show, - udg_sysfs_max_inter_stroke_time_store), -}; - -static struct synaptics_rmi4_udg_handle *udg; - -static unsigned char ctrl_18_sub_size[] = {10, 10, 10, 2, 3, 4, 3, 3, 1, 1}; -static unsigned char ctrl_20_sub_size[] = {2}; -static unsigned char ctrl_23_sub_size[] = {1, 1, 1}; -static unsigned char ctrl_27_sub_size[] = {1, 5, 2, 1, 7}; - -DECLARE_COMPLETION(udg_remove_complete); - -static ssize_t udg_sysfs_engine_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - bool enable; - unsigned int input; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input == 1) - enable = true; - else if (input == 0) - enable = false; - else - return -EINVAL; - - retval = udg_engine_enable(enable); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_detection_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - bool enable; - unsigned int input; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input == 1) - enable = true; - else if (input == 0) - enable = false; - else - return -EINVAL; - - udg->detection_status = 0; - - retval = udg_detection_enable(enable); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_detection_score_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", udg->detection_score); -} - -static ssize_t udg_sysfs_detection_index_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", udg->detection_index); -} - -static ssize_t udg_sysfs_registration_enable_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - bool enable; - unsigned int input; - struct synaptics_rmi4_f12_control_41 control_41; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input == 1) - enable = true; - else if (input == 0) - enable = false; - else - return -EINVAL; - - if (enable) { - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_23, - udg->ctrl_buf, - udg->ctrl_23_sub3_off + 1); - if (retval < 0) - return retval; - - udg->ctrl_buf[0] = 0; - udg->ctrl_buf[0] |= (1 << CTRL23_FINGER_REPORT_ENABLE_BIT); - if (udg->ctrl_23_sub3_off) - udg->ctrl_buf[udg->ctrl_23_sub3_off] = 0; - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_23, - udg->ctrl_buf, - udg->ctrl_23_sub3_off + 1); - if (retval < 0) - return retval; - } else { - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_23, - udg->ctrl_buf, - udg->ctrl_23_sub3_off + 1); - if (retval < 0) - return retval; - - udg->ctrl_buf[0] = udg->object_type_enable1; - if (udg->ctrl_23_sub3_off) { - udg->ctrl_buf[udg->ctrl_23_sub3_off] = - udg->object_type_enable2; - } - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_23, - udg->ctrl_buf, - udg->ctrl_23_sub3_off + 1); - if (retval < 0) - return retval; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_41, - control_41.data, - sizeof(control_41.data)); - if (retval < 0) - return retval; - - control_41.enable_registration = enable ? 1 : 0; - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_41, - control_41.data, - sizeof(control_41.data)); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_registration_begin_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - bool begin; - unsigned int input; - struct synaptics_rmi4_f12_control_41 control_41; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input == 1) - begin = true; - else if (input == 0) - begin = false; - else - return -EINVAL; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_41, - control_41.data, - sizeof(control_41.data)); - if (retval < 0) - return retval; - - control_41.begin = begin ? 1 : 0; - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_41, - control_41.data, - sizeof(control_41.data)); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_registration_status_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "0x%02x\n", udg->registration_status); -} - -static ssize_t udg_sysfs_template_size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", udg->template_size); -} - -static ssize_t udg_sysfs_template_max_index_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", udg->max_num_templates - 1); -} - -static ssize_t udg_sysfs_template_detection_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - int attn_event; - unsigned char detection_status; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - attn_event = atomic_read(&udg->attn_event); - atomic_set(&udg->attn_event, 0); - - if (attn_event == 0) - return snprintf(buf, PAGE_SIZE, "0\n"); - - if (udg->detection_status == 0) { - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.data_4, - rmi4_data->gesture_detection, - sizeof(rmi4_data->gesture_detection)); - if (retval < 0) - return retval; - - udg->detection_status = rmi4_data->gesture_detection[0]; - } - - detection_status = udg->detection_status; - udg->detection_status = 0; - - switch (detection_status) { - case DETECTION: - udg->detection_score = rmi4_data->gesture_detection[1]; - udg->detection_index = rmi4_data->gesture_detection[4]; - udg->trace_size = rmi4_data->gesture_detection[3]; - break; - case REGISTRATION: - udg->registration_status = rmi4_data->gesture_detection[1]; - udg->trace_size = rmi4_data->gesture_detection[3]; - break; - default: - return snprintf(buf, PAGE_SIZE, "0\n"); - } - - return snprintf(buf, PAGE_SIZE, "0x%02x\n", detection_status); -} - -static ssize_t udg_sysfs_template_index_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long index; - - retval = sstrtoul(buf, 10, &index); - if (retval) - return retval; - - retval = udg_set_index((unsigned char)index); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_template_valid_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned char valid; - unsigned char offset; - unsigned char byte_num; - unsigned char template_flags[2]; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - byte_num = udg->template_index / 8; - offset = udg->template_index % 8; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.template_flags, - template_flags, - sizeof(template_flags)); - if (retval < 0) - return retval; - - valid = (template_flags[byte_num] & (1 << offset)) >> offset; - - return snprintf(buf, PAGE_SIZE, "%u\n", valid); -} - -static ssize_t udg_sysfs_template_valid_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long valid; - unsigned char offset; - unsigned char byte_num; - unsigned char template_flags[2]; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - retval = sstrtoul(buf, 10, &valid); - if (retval) - return retval; - - if (valid > 0) - valid = 1; - - byte_num = udg->template_index / 8; - offset = udg->template_index % 8; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.template_flags, - template_flags, - sizeof(template_flags)); - if (retval < 0) - return retval; - - if (valid) - template_flags[byte_num] |= (1 << offset); - else - template_flags[byte_num] &= ~(1 << offset); - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.template_flags, - template_flags, - sizeof(template_flags)); - if (retval < 0) - return retval; - -#ifdef STORE_GESTURES - udg_read_valid_data(); -#endif - - return count; -} - -static ssize_t udg_sysfs_template_clear_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - const char cmd[] = {'0', 0}; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - memset(udg->template_data_buf, 0x00, udg->template_data_size); - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.template_data, - udg->template_data_buf, - udg->template_data_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to clear template data\n", - __func__); - return retval; - } - - retval = udg_sysfs_template_valid_store(dev, attr, cmd, 1); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to clear valid bit\n", - __func__); - return retval; - } - -#ifdef STORE_GESTURES - udg_read_template_data(udg->template_index); - udg_read_valid_data(); -#endif - - return count; -} - -static ssize_t udg_sysfs_trace_size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", udg->trace_size); -} - -static ssize_t udg_sysfs_trace_data_show(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - int retval; - unsigned short index = 0; - unsigned short trace_data_size; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - trace_data_size = udg->trace_size * 5; - - if (trace_data_size == 0) - return -EINVAL; - - if (count < trace_data_size) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Not enough space (%d bytes) in buffer\n", - __func__, (unsigned int)count); - return -EINVAL; - } - - if (udg->trace_data_buf_size < trace_data_size) { - if (udg->trace_data_buf_size) - kfree(udg->trace_data_buf); - udg->trace_data_buf = kzalloc(trace_data_size, GFP_KERNEL); - if (!udg->trace_data_buf) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for trace data buffer\n", - __func__); - udg->trace_data_buf_size = 0; - return -ENOMEM; - } - udg->trace_data_buf_size = trace_data_size; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.trace_x, - &udg->trace_data_buf[index], - udg->trace_size * 2); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read trace X data\n", - __func__); - return retval; - } else { - index += udg->trace_size * 2; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.trace_y, - &udg->trace_data_buf[index], - udg->trace_size * 2); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read trace Y data\n", - __func__); - return retval; - } else { - index += udg->trace_size * 2; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.trace_segment, - &udg->trace_data_buf[index], - udg->trace_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read trace segment data\n", - __func__); - return retval; - } - - retval = secure_memcpy(buf, count, udg->trace_data_buf, - udg->trace_data_buf_size, trace_data_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy trace data\n", - __func__); - return retval; - } - - return trace_data_size; -} - -static ssize_t udg_sysfs_template_data_show(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - if (count < udg->template_data_size) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Not enough space (%d bytes) in buffer\n", - __func__, (unsigned int)count); - return -EINVAL; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.template_data, - udg->template_data_buf, - udg->template_data_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read template data\n", - __func__); - return retval; - } - - retval = secure_memcpy(buf, count, udg->template_data_buf, - udg->template_data_size, udg->template_data_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy template data\n", - __func__); - return retval; - } - -#ifdef STORE_GESTURES - udg_read_template_data(udg->template_index); - udg_read_valid_data(); -#endif - - return udg->template_data_size; -} - -static ssize_t udg_sysfs_template_data_store(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - retval = secure_memcpy(udg->template_data_buf, udg->template_data_size, - buf, count, count); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy template data\n", - __func__); - return retval; - } - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.template_data, - udg->template_data_buf, - count); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write template data\n", - __func__); - return retval; - } - -#ifdef STORE_GESTURES - udg_read_template_data(udg->template_index); - udg_read_valid_data(); -#endif - - return count; -} - -static ssize_t udg_sysfs_template_displacement_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned short template_displacement; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - template_displacement = - ((unsigned short)udg->tuning.template_disp_lsb << 0) | - ((unsigned short)udg->tuning.template_disp_msb << 8); - - return snprintf(buf, PAGE_SIZE, "%u\n", template_displacement); -} - -static ssize_t udg_sysfs_template_displacement_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long input; - - retval = sstrtoul(buf, 10, &input); - if (retval) - return retval; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - udg->tuning.template_disp_lsb = (unsigned char)(input >> 0); - udg->tuning.template_disp_msb = (unsigned char)(input >> 8); - - retval = udg_write_tuning_params(); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_rotation_invariance_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned short rotation_invariance; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - rotation_invariance = - ((unsigned short)udg->tuning.rotation_inv_lsb << 0) | - ((unsigned short)udg->tuning.rotation_inv_msb << 8); - - return snprintf(buf, PAGE_SIZE, "%u\n", rotation_invariance); -} - -static ssize_t udg_sysfs_rotation_invariance_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long input; - - retval = sstrtoul(buf, 10, &input); - if (retval) - return retval; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - udg->tuning.rotation_inv_lsb = (unsigned char)(input >> 0); - udg->tuning.rotation_inv_msb = (unsigned char)(input >> 8); - - retval = udg_write_tuning_params(); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_scale_invariance_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned short scale_invariance; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - scale_invariance = - ((unsigned short)udg->tuning.scale_inv_lsb << 0) | - ((unsigned short)udg->tuning.scale_inv_msb << 8); - - return snprintf(buf, PAGE_SIZE, "%u\n", scale_invariance); -} - -static ssize_t udg_sysfs_scale_invariance_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long input; - - retval = sstrtoul(buf, 10, &input); - if (retval) - return retval; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - udg->tuning.scale_inv_lsb = (unsigned char)(input >> 0); - udg->tuning.scale_inv_msb = (unsigned char)(input >> 8); - - retval = udg_write_tuning_params(); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_threshold_factor_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned short threshold_factor; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - threshold_factor = - ((unsigned short)udg->tuning.thres_factor_lsb << 0) | - ((unsigned short)udg->tuning.thres_factor_msb << 8); - - return snprintf(buf, PAGE_SIZE, "%u\n", threshold_factor); -} - -static ssize_t udg_sysfs_threshold_factor_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long input; - - retval = sstrtoul(buf, 10, &input); - if (retval) - return retval; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - udg->tuning.thres_factor_lsb = (unsigned char)(input >> 0); - udg->tuning.thres_factor_msb = (unsigned char)(input >> 8); - - retval = udg_write_tuning_params(); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_match_metric_threshold_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned short match_metric_threshold; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - match_metric_threshold = - ((unsigned short)udg->tuning.metric_thres_lsb << 0) | - ((unsigned short)udg->tuning.metric_thres_msb << 8); - - return snprintf(buf, PAGE_SIZE, "%u\n", match_metric_threshold); -} - -static ssize_t udg_sysfs_match_metric_threshold_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long input; - - retval = sstrtoul(buf, 10, &input); - if (retval) - return retval; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - udg->tuning.metric_thres_lsb = (unsigned char)(input >> 0); - udg->tuning.metric_thres_msb = (unsigned char)(input >> 8); - - retval = udg_write_tuning_params(); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t udg_sysfs_max_inter_stroke_time_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned short max_inter_stroke_time; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - max_inter_stroke_time = - ((unsigned short)udg->tuning.inter_stroke_lsb << 0) | - ((unsigned short)udg->tuning.inter_stroke_msb << 8); - - return snprintf(buf, PAGE_SIZE, "%u\n", max_inter_stroke_time); -} - -static ssize_t udg_sysfs_max_inter_stroke_time_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long input; - - retval = sstrtoul(buf, 10, &input); - if (retval) - return retval; - - retval = udg_read_tuning_params(); - if (retval < 0) - return retval; - - udg->tuning.inter_stroke_lsb = (unsigned char)(input >> 0); - udg->tuning.inter_stroke_msb = (unsigned char)(input >> 8); - - retval = udg_write_tuning_params(); - if (retval < 0) - return retval; - - return count; -} - -static int udg_ctrl_subpacket(unsigned char ctrlreg, - unsigned char subpacket, - struct synaptics_rmi4_f12_query_5 *query_5) -{ - int retval; - unsigned char cnt; - unsigned char regnum; - unsigned char bitnum; - unsigned char q5_index; - unsigned char q6_index; - unsigned char offset; - unsigned char max_ctrlreg; - unsigned char *query_6; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - max_ctrlreg = (sizeof(query_5->data) - 1) * 8 - 1; - - if (ctrlreg > max_ctrlreg) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Control register number (%d) over limit\n", - __func__, ctrlreg); - return -EINVAL; - } - - q5_index = ctrlreg / 8 + 1; - bitnum = ctrlreg % 8; - if ((query_5->data[q5_index] & (1 << bitnum)) == 0x00) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Control %d is not present\n", - __func__, ctrlreg); - return -EINVAL; - } - - query_6 = kmalloc(query_5->size_of_query6, GFP_KERNEL); - if (!query_6) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for query 6\n", - __func__); - return -ENOMEM; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->query_base_addr + 6, - query_6, - query_5->size_of_query6); - if (retval < 0) - goto exit; - - q6_index = 0; - - for (regnum = 0; regnum < ctrlreg; regnum++) { - q5_index = regnum / 8 + 1; - bitnum = regnum % 8; - if ((query_5->data[q5_index] & (1 << bitnum)) == 0x00) - continue; - - if (query_6[q6_index] == 0x00) - q6_index += 3; - else - q6_index++; - - while (query_6[q6_index] & ~MASK_7BIT) - q6_index++; - - q6_index++; - } - - cnt = 0; - q6_index++; - offset = subpacket / 7; - bitnum = subpacket % 7; - - do { - if (cnt == offset) { - if (query_6[q6_index + cnt] & (1 << bitnum)) - retval = 1; - else - retval = 0; - goto exit; - } - cnt++; - } while (query_6[q6_index + cnt - 1] & ~MASK_7BIT); - - retval = 0; - -exit: - kfree(query_6); - - return retval; -} - -static int udg_read_tuning_params(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_18, - udg->ctrl_buf, - udg->ctrl_18_sub10_off + sizeof(struct udg_tuning)); - if (retval < 0) - return retval; - - secure_memcpy(udg->tuning.data, - sizeof(udg->tuning.data), - (unsigned char *)&udg->ctrl_buf[udg->ctrl_18_sub10_off], - sizeof(struct udg_tuning), - sizeof(struct udg_tuning)); - - return 0; -} - -static int udg_write_tuning_params(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - secure_memcpy((unsigned char *)&udg->ctrl_buf[udg->ctrl_18_sub10_off], - sizeof(struct udg_tuning), - udg->tuning.data, - sizeof(udg->tuning.data), - sizeof(struct udg_tuning)); - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_18, - udg->ctrl_buf, - udg->ctrl_18_sub10_off + sizeof(struct udg_tuning)); - if (retval < 0) - return retval; - - return 0; -} - -static int udg_detection_enable(bool enable) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_20, - udg->ctrl_buf, - udg->ctrl_20_sub1_off + 1); - if (retval < 0) - return retval; - - if (enable) - udg->ctrl_buf[udg->ctrl_20_sub1_off] = WAKEUP_GESTURE_MODE; - else - udg->ctrl_buf[udg->ctrl_20_sub1_off] = udg->report_flags; - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_20, - udg->ctrl_buf, - udg->ctrl_20_sub1_off + 1); - if (retval < 0) - return retval; - - return 0; -} - -static int udg_engine_enable(bool enable) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - if (enable) { - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_27, - udg->ctrl_buf, - udg->ctrl_27_sub5_off + 1); - if (retval < 0) - return retval; - - udg->ctrl_buf[udg->ctrl_27_sub5_off] |= - (1 << CTRL27_UDG_ENABLE_BIT); - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_27, - udg->ctrl_buf, - udg->ctrl_27_sub5_off + 1); - if (retval < 0) - return retval; - } else { - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_27, - udg->ctrl_buf, - udg->ctrl_27_sub5_off + 1); - if (retval < 0) - return retval; - - udg->ctrl_buf[udg->ctrl_27_sub5_off] &= - ~(1 << CTRL27_UDG_ENABLE_BIT); - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_27, - udg->ctrl_buf, - udg->ctrl_27_sub5_off + 1); - if (retval < 0) - return retval; - } - - return 0; -} - -static void udg_report(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - atomic_set(&udg->attn_event, 1); - - if (rmi4_data->suspend) { - if (rmi4_data->gesture_detection[0] == 0) { - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.data_4, - rmi4_data->gesture_detection, - sizeof(rmi4_data->gesture_detection)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read gesture detection\n", - __func__); - return; - } - } - - udg->detection_status = rmi4_data->gesture_detection[0]; - rmi4_data->gesture_detection[0] = 0; - - if (udg->detection_status == DETECTION) { - input_report_key(udg->udg_dev, KEY_WAKEUP, 1); - input_sync(udg->udg_dev); - input_report_key(udg->udg_dev, KEY_WAKEUP, 0); - input_sync(udg->udg_dev); - rmi4_data->suspend = false; - } - } - - return; -} - -static int udg_set_index(unsigned char index) -{ - int retval; - struct synaptics_rmi4_f12_control_41 control_41; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - if (index >= udg->max_num_templates) - return -EINVAL; - - udg->template_index = index; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_41, - control_41.data, - sizeof(control_41.data)); - if (retval < 0) - return retval; - - control_41.template_index = udg->template_index; - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.ctrl_41, - control_41.data, - sizeof(control_41.data)); - if (retval < 0) - return retval; - - return 0; -} - -#ifdef STORE_GESTURES -static int udg_read_valid_data(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.template_flags, - udg->valid_buf, - sizeof(udg->valid_buf)); - if (retval < 0) - return retval; - - return 0; -} - -static int udg_write_valid_data(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.template_flags, - udg->valid_buf, - sizeof(udg->valid_buf)); - if (retval < 0) - return retval; - - return 0; -} - -static int udg_read_template_data(unsigned char index) -{ - int retval; - unsigned char *storage; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - udg_set_index(index); - storage = &(udg->storage_buf[index * udg->template_data_size]); - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.template_data, - storage, - udg->template_data_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read template data\n", - __func__); - return retval; - } - - return 0; -} - -static int udg_write_template_data(void) -{ - int retval; - unsigned char ii; - unsigned char *storage; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - for (ii = 0; ii < udg->gestures_to_store; ii++) { - udg_set_index(ii); - storage = &(udg->storage_buf[ii * udg->template_data_size]); - - retval = synaptics_rmi4_reg_write(rmi4_data, - udg->addr.template_data, - storage, - udg->template_data_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write template data\n", - __func__); - return retval; - } - } - - return 0; -} -#endif - -static int udg_reg_init(void) -{ - int retval; - unsigned char ii; - unsigned char data_offset; - unsigned char size_of_query; - unsigned char ctrl_18_offset; - unsigned char ctrl_20_offset; - unsigned char ctrl_23_offset; - unsigned char ctrl_27_offset; - unsigned char ctrl_41_offset; - struct synaptics_rmi4_f12_query_0 query_0; - struct synaptics_rmi4_f12_query_5 query_5; - struct synaptics_rmi4_f12_query_8 query_8; - struct synaptics_rmi4_data *rmi4_data = udg->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->query_base_addr + 7, - &size_of_query, - sizeof(size_of_query)); - if (retval < 0) - return retval; - - if (size_of_query < 4) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: User defined gesture support unavailable (missing data registers)\n", - __func__); - retval = -ENODEV; - return retval; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->query_base_addr + 8, - query_8.data, - sizeof(query_8.data)); - if (retval < 0) - return retval; - - if ((query_8.data16_is_present) && - (query_8.data17_is_present) && - (query_8.data18_is_present) && - (query_8.data19_is_present) && - (query_8.data20_is_present) && - (query_8.data21_is_present)) { - data_offset = query_8.data0_is_present + - query_8.data1_is_present + - query_8.data2_is_present + - query_8.data3_is_present; - udg->addr.data_4 = udg->data_base_addr + data_offset; - data_offset = data_offset + - 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 + - query_8.data15_is_present; - udg->addr.trace_x = udg->data_base_addr + data_offset; - udg->addr.trace_y = udg->addr.trace_x + 1; - udg->addr.trace_segment = udg->addr.trace_y + 1; - udg->addr.template_helper = udg->addr.trace_segment + 1; - udg->addr.template_data = udg->addr.template_helper + 1; - udg->addr.template_flags = udg->addr.template_data + 1; - } else { - dev_err(rmi4_data->pdev->dev.parent, - "%s: User defined gesture support unavailable (missing data registers)\n", - __func__); - retval = -ENODEV; - return retval; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->query_base_addr + 4, - &size_of_query, - sizeof(size_of_query)); - if (retval < 0) - return retval; - - if (size_of_query < 7) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: User defined gesture support unavailable (missing control registers)\n", - __func__); - retval = -ENODEV; - return retval; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->query_base_addr + 5, - query_5.data, - sizeof(query_5.data)); - if (retval < 0) - return retval; - - ctrl_18_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; - - ctrl_20_offset = ctrl_18_offset + - query_5.ctrl18_is_present + - query_5.ctrl19_is_present; - - ctrl_23_offset = ctrl_20_offset + - query_5.ctrl20_is_present + - query_5.ctrl21_is_present + - query_5.ctrl22_is_present; - - ctrl_27_offset = ctrl_23_offset+ - query_5.ctrl23_is_present + - query_5.ctrl24_is_present + - query_5.ctrl25_is_present + - query_5.ctrl26_is_present; - - ctrl_41_offset = ctrl_27_offset+ - query_5.ctrl27_is_present + - query_5.ctrl28_is_present + - query_5.ctrl29_is_present + - query_5.ctrl30_is_present + - query_5.ctrl31_is_present + - query_5.ctrl32_is_present + - query_5.ctrl33_is_present + - query_5.ctrl34_is_present + - query_5.ctrl35_is_present + - query_5.ctrl36_is_present + - query_5.ctrl37_is_present + - query_5.ctrl38_is_present + - query_5.ctrl39_is_present + - query_5.ctrl40_is_present; - - udg->addr.ctrl_18 = udg->control_base_addr + ctrl_18_offset; - udg->addr.ctrl_20 = udg->control_base_addr + ctrl_20_offset; - udg->addr.ctrl_23 = udg->control_base_addr + ctrl_23_offset; - udg->addr.ctrl_27 = udg->control_base_addr + ctrl_27_offset; - udg->addr.ctrl_41 = udg->control_base_addr + ctrl_41_offset; - - udg->ctrl_18_sub10_off = 0; - for (ii = 0; ii < 10; ii++) { - retval = udg_ctrl_subpacket(18, ii, &query_5); - if (retval == 1) - udg->ctrl_18_sub10_off += ctrl_18_sub_size[ii]; - else if (retval < 0) - return retval; - } - - udg->ctrl_20_sub1_off = 0; - for (ii = 0; ii < 1; ii++) { - retval = udg_ctrl_subpacket(20, ii, &query_5); - if (retval == 1) - udg->ctrl_20_sub1_off += ctrl_20_sub_size[ii]; - else if (retval < 0) - return retval; - } - - udg->ctrl_23_sub3_off = 0; - for (ii = 0; ii < 3; ii++) { - retval = udg_ctrl_subpacket(23, ii, &query_5); - if (retval == 1) - udg->ctrl_23_sub3_off += ctrl_23_sub_size[ii]; - else if (retval < 0) - return retval; - } - - retval = udg_ctrl_subpacket(23, 3, &query_5); - if (retval == 0) - udg->ctrl_23_sub3_off = 0; - else if (retval < 0) - return retval; - - udg->ctrl_27_sub5_off = 0; - for (ii = 0; ii < 5; ii++) { - retval = udg_ctrl_subpacket(27, ii, &query_5); - if (retval == 1) - udg->ctrl_27_sub5_off += ctrl_27_sub_size[ii]; - else if (retval < 0) - return retval; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->query_base_addr + 0, - query_0.data, - sizeof(query_0.data)); - if (retval < 0) - return retval; - - udg->max_num_templates = query_0.max_num_templates; - udg->template_size = - ((unsigned short)query_0.template_size_lsb << 0) | - ((unsigned short)query_0.template_size_msb << 8); - udg->template_data_size = udg->template_size * 4 * 2 + 4 + 1; - -#ifdef STORE_GESTURES - udg->gestures_to_store = udg->max_num_templates; - if (GESTURES_TO_STORE < udg->gestures_to_store) - udg->gestures_to_store = GESTURES_TO_STORE; -#endif - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_20, - udg->ctrl_buf, - udg->ctrl_20_sub1_off + 1); - if (retval < 0) - return retval; - - udg->report_flags = udg->ctrl_buf[udg->ctrl_20_sub1_off]; - - retval = synaptics_rmi4_reg_read(rmi4_data, - udg->addr.ctrl_23, - udg->ctrl_buf, - udg->ctrl_23_sub3_off + 1); - if (retval < 0) - return retval; - - udg->object_type_enable1 = udg->ctrl_buf[0]; - if (udg->ctrl_23_sub3_off) - udg->object_type_enable2 = udg->ctrl_buf[udg->ctrl_23_sub3_off]; - - return retval; -} - -static int udg_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 = udg->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; - } - } - - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F12\n", - __func__); - return -EINVAL; - -f12_found: - udg->query_base_addr = fd.query_base_addr | (page << 8); - udg->control_base_addr = fd.ctrl_base_addr | (page << 8); - udg->data_base_addr = fd.data_base_addr | (page << 8); - udg->command_base_addr = fd.cmd_base_addr | (page << 8); - - retval = udg_reg_init(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to initialize user defined gesture registers\n", - __func__); - return retval; - } - - udg->intr_mask = 0; - intr_src = fd.intr_src_count; - intr_off = intr_count % 8; - for (ii = intr_off; - ii < (intr_src + intr_off); - ii++) { - udg->intr_mask |= 1 << ii; - } - - rmi4_data->intr_mask[0] |= udg->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 void synaptics_rmi4_udg_attn(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask) -{ - if (!udg) - return; - - if (udg->intr_mask & intr_mask) - udg_report(); - - return; -} - -static int synaptics_rmi4_udg_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char ii; - unsigned char size; - unsigned char attr_count; - unsigned char param_count; - - if (udg) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Handle already exists\n", - __func__); - return 0; - } - - udg = kzalloc(sizeof(*udg), GFP_KERNEL); - if (!udg) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for udg\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - size = 0; - for (ii = 0; ii < sizeof(ctrl_18_sub_size); ii++) - size += ctrl_18_sub_size[ii]; - size += sizeof(struct udg_tuning); - udg->ctrl_buf = kzalloc(size, GFP_KERNEL); - if (!udg->ctrl_buf) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for ctrl_buf\n", - __func__); - retval = -ENOMEM; - goto exit_free_udg; - } - - udg->rmi4_data = rmi4_data; - - retval = udg_scan_pdt(); - if (retval < 0) - goto exit_free_ctrl_buf; - - udg->template_data_buf = kzalloc(udg->template_data_size, GFP_KERNEL); - if (!udg->template_data_buf) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for template_data_buf\n", - __func__); - retval = -ENOMEM; - goto exit_free_ctrl_buf; - } - -#ifdef STORE_GESTURES - udg->storage_buf = kzalloc( - udg->template_data_size * udg->gestures_to_store, - GFP_KERNEL); - if (!udg->storage_buf) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for storage_buf\n", - __func__); - kfree(udg->template_data_buf); - retval = -ENOMEM; - goto exit_free_ctrl_buf; - } -#endif - - udg->udg_dev = input_allocate_device(); - if (udg->udg_dev == NULL) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate gesture device\n", - __func__); - retval = -ENOMEM; - goto exit_free_template_data_buf; - } - - udg->udg_dev->name = GESTURE_DRIVER_NAME; - udg->udg_dev->phys = GESTURE_PHYS_NAME; - udg->udg_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; - udg->udg_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; - udg->udg_dev->dev.parent = rmi4_data->pdev->dev.parent; - input_set_drvdata(udg->udg_dev, rmi4_data); - - set_bit(EV_KEY, udg->udg_dev->evbit); - set_bit(KEY_WAKEUP, udg->udg_dev->keybit); - input_set_capability(udg->udg_dev, EV_KEY, KEY_WAKEUP); - - retval = input_register_device(udg->udg_dev); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to register gesture device\n", - __func__); - input_free_device(udg->udg_dev); - goto exit_free_template_data_buf; - } - - udg->tuning_dir = kobject_create_and_add(TUNING_SYSFS_DIR_NAME, - &udg->udg_dev->dev.kobj); - if (!udg->tuning_dir) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create tuning sysfs directory\n", - __func__); - goto exit_unregister_input_device; - } - - retval = sysfs_create_bin_file(&udg->udg_dev->dev.kobj, &template_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create template data bin file\n", - __func__); - goto exit_remove_sysfs_directory; - } - - retval = sysfs_create_bin_file(&udg->udg_dev->dev.kobj, &trace_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create trace data bin file\n", - __func__); - goto exit_remove_bin_file; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(&udg->udg_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; - } - } - - for (param_count = 0; param_count < ARRAY_SIZE(params); param_count++) { - retval = sysfs_create_file(udg->tuning_dir, - ¶ms[param_count].attr); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create tuning parameters\n", - __func__); - retval = -ENODEV; - goto exit_remove_params; - } - } - - retval = udg_engine_enable(true); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to enable gesture engine\n", - __func__); - goto exit_remove_params; - } - - return 0; - -exit_remove_params: - for (param_count--; param_count >= 0; param_count--) { - sysfs_remove_file(udg->tuning_dir, - ¶ms[param_count].attr); - } - -exit_remove_attrs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&udg->udg_dev->dev.kobj, - &attrs[attr_count].attr); - } - - sysfs_remove_bin_file(&udg->udg_dev->dev.kobj, &trace_data); - -exit_remove_bin_file: - sysfs_remove_bin_file(&udg->udg_dev->dev.kobj, &template_data); - -exit_remove_sysfs_directory: - kobject_put(udg->tuning_dir); - -exit_unregister_input_device: - input_unregister_device(udg->udg_dev); - -exit_free_template_data_buf: -#ifdef STORE_GESTURES - kfree(udg->storage_buf); -#endif - kfree(udg->template_data_buf); - -exit_free_ctrl_buf: - kfree(udg->ctrl_buf); - -exit_free_udg: - kfree(udg); - udg = NULL; - -exit: - return retval; -} - -static void synaptics_rmi4_udg_remove(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char count; - - if (!udg) - goto exit; - - for (count = 0; count < ARRAY_SIZE(params); count++) { - sysfs_remove_file(udg->tuning_dir, - ¶ms[count].attr); - } - - for (count = 0; count < ARRAY_SIZE(attrs); count++) { - sysfs_remove_file(&udg->udg_dev->dev.kobj, - &attrs[count].attr); - } - - sysfs_remove_bin_file(&udg->udg_dev->dev.kobj, &trace_data); - sysfs_remove_bin_file(&udg->udg_dev->dev.kobj, &template_data); - kobject_put(udg->tuning_dir); - - input_unregister_device(udg->udg_dev); -#ifdef STORE_GESTURES - kfree(udg->storage_buf); -#endif - kfree(udg->template_data_buf); - kfree(udg->trace_data_buf); - kfree(udg->ctrl_buf); - kfree(udg); - udg = NULL; - -exit: - complete(&udg_remove_complete); - - return; -} - -static void synaptics_rmi4_udg_reset(struct synaptics_rmi4_data *rmi4_data) -{ - if (!udg) { - synaptics_rmi4_udg_init(rmi4_data); - return; - } - - udg_scan_pdt(); - udg_engine_enable(true); -#ifdef STORE_GESTURES - udg_write_template_data(); - udg_write_valid_data(); -#endif - - return; -} - -static void synaptics_rmi4_udg_reinit(struct synaptics_rmi4_data *rmi4_data) -{ - if (!udg) - return; - - udg_engine_enable(true); -#ifdef STORE_GESTURES - udg_write_template_data(); - udg_write_valid_data(); -#endif - - return; -} - -static void synaptics_rmi4_udg_e_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - if (!udg) - return; - - rmi4_data->sleep_enable(rmi4_data, false); - rmi4_data->irq_enable(rmi4_data, true, false); - enable_irq_wake(rmi4_data->irq); - - udg_engine_enable(true); - udg_detection_enable(true); - - return; -} - -static void synaptics_rmi4_udg_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - if (!udg) - return; - - rmi4_data->sleep_enable(rmi4_data, false); - rmi4_data->irq_enable(rmi4_data, true, false); - enable_irq_wake(rmi4_data->irq); - - udg_engine_enable(true); - udg_detection_enable(true); - - return; -} - -static void synaptics_rmi4_udg_resume(struct synaptics_rmi4_data *rmi4_data) -{ - if (!udg) - return; - - disable_irq_wake(rmi4_data->irq); - udg_detection_enable(false); - - return; -} - -static void synaptics_rmi4_udg_l_resume(struct synaptics_rmi4_data *rmi4_data) -{ - if (!udg) - return; - - disable_irq_wake(rmi4_data->irq); - udg_detection_enable(false); - - return; -} - -static struct synaptics_rmi4_exp_fn gesture_module = { - .fn_type = RMI_GESTURE, - .init = synaptics_rmi4_udg_init, - .remove = synaptics_rmi4_udg_remove, - .reset = synaptics_rmi4_udg_reset, - .reinit = synaptics_rmi4_udg_reinit, - .early_suspend = synaptics_rmi4_udg_e_suspend, - .suspend = synaptics_rmi4_udg_suspend, - .resume = synaptics_rmi4_udg_resume, - .late_resume = synaptics_rmi4_udg_l_resume, - .attn = synaptics_rmi4_udg_attn, -}; - -static int __init rmi4_gesture_module_init(void) -{ - synaptics_rmi4_new_function(&gesture_module, true); - - return 0; -} - -static void __exit rmi4_gesture_module_exit(void) -{ - synaptics_rmi4_new_function(&gesture_module, false); - - wait_for_completion(&udg_remove_complete); - - return; -} - -module_init(rmi4_gesture_module_init); -module_exit(rmi4_gesture_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX User Defined Gesture Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c deleted file mode 100644 index 563ce16885b3..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * Copyright (C) 2016, The Linux Foundation. All rights reserved. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define SYN_I2C_RETRY_TIMES 10 - -/* -#define I2C_BURST_LIMIT 255 -*/ -/* -#define XFER_MSGS_LIMIT 8 -*/ - -static unsigned char *wr_buf; - -static struct synaptics_dsx_hw_interface hw_if; - -static struct platform_device *synaptics_dsx_i2c_device; - -#ifdef CONFIG_OF -static int parse_dt(struct device *dev, struct synaptics_dsx_board_data *bdata) -{ - int retval; - u32 value; - const char *name; - struct property *prop; - struct device_node *np = dev->of_node; - - bdata->irq_gpio = of_get_named_gpio_flags(np, - "synaptics,irq-gpio", 0, - (enum of_gpio_flags *)&bdata->irq_flags); - - retval = of_property_read_u32(np, "synaptics,irq-on-state", - &value); - if (retval < 0) - bdata->irq_on_state = 0; - else - bdata->irq_on_state = value; - - bdata->resume_in_workqueue = of_property_read_bool(np, - "synaptics,resume-in-workqueue"); - - retval = of_property_read_string(np, "synaptics,pwr-reg-name", &name); - if (retval < 0) - bdata->pwr_reg_name = NULL; - else - bdata->pwr_reg_name = name; - - retval = of_property_read_string(np, "synaptics,bus-reg-name", &name); - if (retval < 0) - bdata->bus_reg_name = NULL; - else - bdata->bus_reg_name = name; - - prop = of_find_property(np, "synaptics,power-gpio", NULL); - if (prop && prop->length) { - bdata->power_gpio = of_get_named_gpio_flags(np, - "synaptics,power-gpio", 0, NULL); - retval = of_property_read_u32(np, "synaptics,power-on-state", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,power-on-state property\n", - __func__); - return retval; - } else { - bdata->power_on_state = value; - } - } else { - bdata->power_gpio = -1; - } - - prop = of_find_property(np, "synaptics,power-delay-ms", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,power-delay-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,power-delay-ms property\n", - __func__); - return retval; - } else { - bdata->power_delay_ms = value; - } - } else { - bdata->power_delay_ms = 0; - } - - prop = of_find_property(np, "synaptics,reset-gpio", NULL); - if (prop && prop->length) { - bdata->reset_gpio = of_get_named_gpio_flags(np, - "synaptics,reset-gpio", 0, NULL); - retval = of_property_read_u32(np, "synaptics,reset-on-state", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-on-state property\n", - __func__); - return retval; - } else { - bdata->reset_on_state = value; - } - retval = of_property_read_u32(np, "synaptics,reset-active-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-active-ms property\n", - __func__); - return retval; - } else { - bdata->reset_active_ms = value; - } - } else { - bdata->reset_gpio = -1; - } - - prop = of_find_property(np, "synaptics,reset-delay-ms", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,reset-delay-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-delay-ms property\n", - __func__); - return retval; - } else { - bdata->reset_delay_ms = value; - } - } else { - bdata->reset_delay_ms = 0; - } - - prop = of_find_property(np, "synaptics,max-y-for-2d", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,max-y-for-2d", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,max-y-for-2d property\n", - __func__); - return retval; - } else { - bdata->max_y_for_2d = value; - } - } else { - bdata->max_y_for_2d = -1; - } - - prop = of_find_property(np, "synaptics,swap-axes", NULL); - bdata->swap_axes = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,x-flip", NULL); - bdata->x_flip = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,y-flip", NULL); - bdata->y_flip = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,ub-i2c-addr", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,ub-i2c-addr", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,ub-i2c-addr property\n", - __func__); - return retval; - } else { - bdata->ub_i2c_addr = (unsigned short)value; - } - } else { - bdata->ub_i2c_addr = -1; - } - - prop = of_find_property(np, "synaptics,cap-button-codes", NULL); - if (prop && prop->length) { - bdata->cap_button_map->map = devm_kzalloc(dev, - prop->length, - GFP_KERNEL); - if (!bdata->cap_button_map->map) - return -ENOMEM; - bdata->cap_button_map->nbuttons = prop->length / sizeof(u32); - retval = of_property_read_u32_array(np, - "synaptics,cap-button-codes", - bdata->cap_button_map->map, - bdata->cap_button_map->nbuttons); - if (retval < 0) { - bdata->cap_button_map->nbuttons = 0; - bdata->cap_button_map->map = NULL; - } - } else { - bdata->cap_button_map->nbuttons = 0; - bdata->cap_button_map->map = NULL; - } - - prop = of_find_property(np, "synaptics,vir-button-codes", NULL); - if (prop && prop->length) { - bdata->vir_button_map->map = devm_kzalloc(dev, - prop->length, - GFP_KERNEL); - if (!bdata->vir_button_map->map) - return -ENOMEM; - bdata->vir_button_map->nbuttons = prop->length / sizeof(u32); - bdata->vir_button_map->nbuttons /= 5; - retval = of_property_read_u32_array(np, - "synaptics,vir-button-codes", - bdata->vir_button_map->map, - bdata->vir_button_map->nbuttons * 5); - if (retval < 0) { - bdata->vir_button_map->nbuttons = 0; - bdata->vir_button_map->map = NULL; - } - } else { - bdata->vir_button_map->nbuttons = 0; - bdata->vir_button_map->map = NULL; - } - - return 0; -} -#endif - -static int synaptics_rmi4_i2c_alloc_buf(struct synaptics_rmi4_data *rmi4_data, - unsigned int count) -{ - static unsigned int buf_size; - - if (count > buf_size) { - if (buf_size) - kfree(wr_buf); - wr_buf = kzalloc(count, GFP_KERNEL); - if (!wr_buf) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for buffer\n", - __func__); - buf_size = 0; - return -ENOMEM; - } - buf_size = count; - } - - return 0; -} - -static void synaptics_rmi4_i2c_check_addr(struct synaptics_rmi4_data *rmi4_data, - struct i2c_client *i2c) -{ - if (hw_if.board_data->ub_i2c_addr == -1) - return; - - if (hw_if.board_data->i2c_addr == i2c->addr) - hw_if.board_data->i2c_addr = hw_if.board_data->ub_i2c_addr; - else - hw_if.board_data->i2c_addr = i2c->addr; - - return; -} - -static int synaptics_rmi4_i2c_set_page(struct synaptics_rmi4_data *rmi4_data, - unsigned short addr) -{ - int retval = 0; - unsigned char retry; - unsigned char buf[PAGE_SELECT_LEN]; - unsigned char page; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - struct i2c_msg msg[1]; - - msg[0].addr = hw_if.board_data->i2c_addr; - msg[0].flags = 0; - msg[0].len = PAGE_SELECT_LEN; - msg[0].buf = buf; - - page = ((addr >> 8) & MASK_8BIT); - buf[0] = MASK_8BIT; - buf[1] = page; - - if (page != rmi4_data->current_page) { - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - if (i2c_transfer(i2c->adapter, msg, 1) == 1) { - rmi4_data->current_page = page; - retval = PAGE_SELECT_LEN; - break; - } - dev_err(rmi4_data->pdev->dev.parent, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - - if (retry == SYN_I2C_RETRY_TIMES / 2) { - synaptics_rmi4_i2c_check_addr(rmi4_data, i2c); - msg[0].addr = hw_if.board_data->i2c_addr; - } - } - } 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; -#ifdef I2C_BURST_LIMIT - unsigned char ii; - unsigned char rd_msgs = ((length - 1) / I2C_BURST_LIMIT) + 1; -#else - unsigned char rd_msgs = 1; -#endif - unsigned char index = 0; - unsigned char xfer_msgs; - unsigned char remaining_msgs; - unsigned short i2c_addr; - unsigned short data_offset = 0; - unsigned short remaining_length = length; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - struct i2c_adapter *adap = i2c->adapter; - struct i2c_msg msg[rd_msgs + 1]; - - 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; - } - - msg[0].addr = hw_if.board_data->i2c_addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &buf; - -#ifdef I2C_BURST_LIMIT - for (ii = 0; ii < (rd_msgs - 1); ii++) { - msg[ii + 1].addr = hw_if.board_data->i2c_addr; - msg[ii + 1].flags = I2C_M_RD; - msg[ii + 1].len = I2C_BURST_LIMIT; - msg[ii + 1].buf = &data[data_offset]; - data_offset += I2C_BURST_LIMIT; - remaining_length -= I2C_BURST_LIMIT; - } -#endif - - msg[rd_msgs].addr = hw_if.board_data->i2c_addr; - msg[rd_msgs].flags = I2C_M_RD; - msg[rd_msgs].len = remaining_length; - msg[rd_msgs].buf = &data[data_offset]; - - buf = addr & MASK_8BIT; - - remaining_msgs = rd_msgs + 1; - - while (remaining_msgs) { -#ifdef XFER_MSGS_LIMIT - if (remaining_msgs > XFER_MSGS_LIMIT) - xfer_msgs = XFER_MSGS_LIMIT; - else - xfer_msgs = remaining_msgs; -#else - xfer_msgs = remaining_msgs; -#endif - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - retval = i2c_transfer(adap, &msg[index], xfer_msgs); - if (retval == xfer_msgs) - break; - - dev_err(rmi4_data->pdev->dev.parent, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - - if (retry == SYN_I2C_RETRY_TIMES / 2) { - synaptics_rmi4_i2c_check_addr(rmi4_data, i2c); - i2c_addr = hw_if.board_data->i2c_addr; - msg[0].addr = i2c_addr; -#ifdef I2C_BURST_LIMIT - for (ii = 0; ii < (rd_msgs - 1); ii++) - msg[ii + 1].addr = i2c_addr; -#endif - msg[rd_msgs].addr = i2c_addr; - } - } - - if (retry == SYN_I2C_RETRY_TIMES) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: I2C read over retry limit\n", - __func__); - retval = -EIO; - goto exit; - } - - remaining_msgs -= xfer_msgs; - index += xfer_msgs; - } - - retval = length; - -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; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - struct i2c_msg msg[1]; - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - retval = synaptics_rmi4_i2c_alloc_buf(rmi4_data, length + 1); - if (retval < 0) - goto exit; - - retval = synaptics_rmi4_i2c_set_page(rmi4_data, addr); - if (retval != PAGE_SELECT_LEN) { - retval = -EIO; - goto exit; - } - - msg[0].addr = hw_if.board_data->i2c_addr; - msg[0].flags = 0; - msg[0].len = length + 1; - msg[0].buf = wr_buf; - - wr_buf[0] = addr & MASK_8BIT; - retval = secure_memcpy(&wr_buf[1], length, &data[0], length, length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy data\n", - __func__); - goto exit; - } - - 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 / 2) { - synaptics_rmi4_i2c_check_addr(rmi4_data, i2c); - msg[0].addr = hw_if.board_data->i2c_addr; - } - } - - 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_SYNAPTICS_DSX_V26) -static int synaptics_rmi4_clk_prepare_enable( - struct synaptics_rmi4_data *rmi4_data) -{ - int ret; - - ret = clk_prepare_enable(rmi4_data->iface_clk); - if (ret) { - dev_err(rmi4_data->pdev->dev.parent, - "error on clk_prepare_enable(iface_clk):%d\n", ret); - return ret; - } - - ret = clk_prepare_enable(rmi4_data->core_clk); - if (ret) { - clk_disable_unprepare(rmi4_data->iface_clk); - dev_err(rmi4_data->pdev->dev.parent, - "error clk_prepare_enable(core_clk):%d\n", ret); - } - return ret; -} - -static void synaptics_rmi4_clk_disable_unprepare( - struct synaptics_rmi4_data *rmi4_data) -{ - clk_disable_unprepare(rmi4_data->core_clk); - clk_disable_unprepare(rmi4_data->iface_clk); -} - -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); - if (retval >= 0 && rmi4_data->core_clk != NULL && - rmi4_data->iface_clk != NULL) { - retval = synaptics_rmi4_clk_prepare_enable(rmi4_data); - if (retval) - pm_runtime_put_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); - if (rmi4_data->core_clk != NULL && rmi4_data->iface_clk != NULL) - synaptics_rmi4_clk_disable_unprepare(rmi4_data); - 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_SYNAPTICS_DSX_V26) - .get = synaptics_rmi4_i2c_get, - .put = synaptics_rmi4_i2c_put, -#endif -}; - -static void synaptics_rmi4_i2c_dev_release(struct device *dev) -{ - kfree(synaptics_dsx_i2c_device); - - return; -} - -static int synaptics_rmi4_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - int retval; - - 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; - } - - 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; - } - -#ifdef CONFIG_OF - if (client->dev.of_node) { - hw_if.board_data = devm_kzalloc(&client->dev, - sizeof(struct synaptics_dsx_board_data), - GFP_KERNEL); - if (!hw_if.board_data) { - dev_err(&client->dev, - "%s: Failed to allocate memory for board data\n", - __func__); - return -ENOMEM; - } - hw_if.board_data->cap_button_map = devm_kzalloc(&client->dev, - sizeof(struct synaptics_dsx_button_map), - GFP_KERNEL); - if (!hw_if.board_data->cap_button_map) { - dev_err(&client->dev, - "%s: Failed to allocate memory for 0D button map\n", - __func__); - return -ENOMEM; - } - hw_if.board_data->vir_button_map = devm_kzalloc(&client->dev, - sizeof(struct synaptics_dsx_button_map), - GFP_KERNEL); - if (!hw_if.board_data->vir_button_map) { - dev_err(&client->dev, - "%s: Failed to allocate memory for virtual button map\n", - __func__); - return -ENOMEM; - } - parse_dt(&client->dev, hw_if.board_data); - } -#else - hw_if.board_data = client->dev.platform_data; -#endif - - hw_if.bus_access = &bus_access; - hw_if.board_data->i2c_addr = client->addr; - - 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 synaptics_rmi4_of_match_table[] = { - { - .compatible = "synaptics,dsx-i2c", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, synaptics_rmi4_of_match_table); -#else -#define synaptics_rmi4_of_match_table NULL -#endif - -static struct i2c_driver synaptics_rmi4_i2c_driver = { - .driver = { - .name = I2C_DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = synaptics_rmi4_of_match_table, - }, - .probe = synaptics_rmi4_i2c_probe, - .remove = synaptics_rmi4_i2c_remove, - .id_table = synaptics_rmi4_id_table, -}; - -int synaptics_rmi4_bus_init_v26(void) -{ - return i2c_add_driver(&synaptics_rmi4_i2c_driver); -} -EXPORT_SYMBOL(synaptics_rmi4_bus_init_v26); - -void synaptics_rmi4_bus_exit_v26(void) -{ - kfree(wr_buf); - - i2c_del_driver(&synaptics_rmi4_i2c_driver); - - return; -} -EXPORT_SYMBOL(synaptics_rmi4_bus_exit_v26); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX I2C Bus Support Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_proximity.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_proximity.c deleted file mode 100644 index d9e27c306af5..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_proximity.c +++ /dev/null @@ -1,692 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define PROX_PHYS_NAME "synaptics_dsx/proximity" - -#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; - } - } - - 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 + 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; - - if (prox) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Handle already exists\n", - __func__); - return 0; - } - - 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 = PROXIMITY_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) { - synaptics_rmi4_prox_init(rmi4_data); - return; - } - - prox_hover_finger_lift(); - - prox_scan_pdt(); - - prox_set_hover_finger_en(); - - 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_new_function(&proximity_module, true); - - return 0; -} - -static void __exit rmi4_proximity_module_exit(void) -{ - synaptics_rmi4_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_2.6/synaptics_dsx_rmi_dev.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_rmi_dev.c deleted file mode 100644 index 111b26c7b759..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_rmi_dev.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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); - -static ssize_t rmidev_sysfs_pid_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t rmidev_sysfs_pid_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_term_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_intr_mask_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t rmidev_sysfs_intr_mask_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_concurrent_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t rmidev_sysfs_concurrent_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -struct rmidev_handle { - dev_t dev_no; - pid_t pid; - unsigned char intr_mask; - unsigned char *tmpbuf; - unsigned int tmpbuf_size; - struct device dev; - struct synaptics_rmi4_data *rmi4_data; - struct kobject *sysfs_dir; - struct siginfo interrupt_signal; - struct siginfo terminate_signal; - struct task_struct *task; - void *data; - bool irq_enabled; - bool concurrent; -}; - -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, - NULL), - __ATTR(pid, S_IRUGO | S_IRUGO | S_IWUSR | S_IWGRP, - rmidev_sysfs_pid_show, - rmidev_sysfs_pid_store), - __ATTR(term, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_term_store), - __ATTR(intr_mask, S_IRUGO, - rmidev_sysfs_intr_mask_show, - rmidev_sysfs_intr_mask_store), - __ATTR(concurrent, S_IRUGO, - rmidev_sysfs_concurrent_show, - rmidev_sysfs_concurrent_store), -}; - -static int rmidev_major_num; - -static struct class *rmidev_device_class; - -static struct rmidev_handle *rmidev; - -DECLARE_COMPLETION(rmidev_remove_complete_v26); - -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 | - IRQF_ONESHOT; - - 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, - 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; - } - - 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 char intr_status = 0; - unsigned int length = (unsigned int)count; - unsigned short address = (unsigned short)pos; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_device_info *rmi; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - rmi = &(rmi4_data->rmi4_mod_info); - - 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; - } - - if (!rmidev->concurrent) - goto exit; - - if (address != rmi4_data->f01_data_base_addr) - goto exit; - - if (length <= 1) - goto exit; - - intr_status = buf[1]; - - 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_status) { - rmi4_data->report_touch(rmi4_data, - fhandler); - } - } - } - } - -exit: - 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; - - if (rmi4_data->sensor_sleep) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Sensor sleeping\n", - __func__); - return -ENODEV; - } - - rmi4_data->stay_awake = true; - - rmi4_data->irq_enable(rmi4_data, false, 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; - - rmidev_sysfs_irq_enable(rmi4_data, false); - rmi4_data->irq_enable(rmi4_data, true, false); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt enabled\n", - __func__); - - rmi4_data->reset_device(rmi4_data, false); - - rmi4_data->stay_awake = false; - - 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); -} - -static ssize_t rmidev_sysfs_pid_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", rmidev->pid); -} - -static ssize_t rmidev_sysfs_pid_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; - - rmidev->pid = input; - - if (rmidev->pid) { - rmidev->task = pid_task(find_vpid(rmidev->pid), PIDTYPE_PID); - if (!rmidev->task) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to locate PID of data logging tool\n", - __func__); - return -EINVAL; - } - } - - return count; -} - -static ssize_t rmidev_sysfs_term_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; - - if (rmidev->pid) - send_sig_info(SIGTERM, &rmidev->terminate_signal, rmidev->task); - - return count; -} - -static ssize_t rmidev_sysfs_intr_mask_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "0x%02x\n", rmidev->intr_mask); -} - -static ssize_t rmidev_sysfs_intr_mask_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; - - rmidev->intr_mask = (unsigned char)input; - - return count; -} - -static ssize_t rmidev_sysfs_concurrent_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", rmidev->concurrent); -} - -static ssize_t rmidev_sysfs_concurrent_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; - - rmidev->concurrent = input > 0 ? true : false; - - return count; -} - -static int rmidev_allocate_buffer(int count) -{ - if (count + 1 > rmidev->tmpbuf_size) { - if (rmidev->tmpbuf_size) - kfree(rmidev->tmpbuf); - rmidev->tmpbuf = kzalloc(count + 1, GFP_KERNEL); - if (!rmidev->tmpbuf) { - dev_err(rmidev->rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for buffer\n", - __func__); - rmidev->tmpbuf_size = 0; - return -ENOMEM; - } - rmidev->tmpbuf_size = count + 1; - } - - return 0; -} - -/* - * rmidev_llseek - set register address to access for RMI device - * - * @filp: pointer to file structure - * @off: - * if whence == SEEK_SET, - * off: 16-bit RMI register address - * if whence == SEEK_CUR, - * off: offset from current position - * if whence == SEEK_END, - * off: 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: read register data from RMI device - * - * @filp: pointer to file structure - * @buf: pointer to user space buffer - * @count: number of bytes to read - * @f_pos: starting RMI 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 intr_status = 0; - unsigned short address; - struct rmidev_data *dev_data = filp->private_data; - struct synaptics_rmi4_fn *fhandler; - struct synaptics_rmi4_device_info *rmi; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - rmi = &(rmi4_data->rmi4_mod_info); - - 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; - - address = (unsigned short)(*f_pos); - - rmidev_allocate_buffer(count); - - mutex_lock(&(dev_data->file_mutex)); - - retval = synaptics_rmi4_reg_read(rmidev->rmi4_data, - *f_pos, - rmidev->tmpbuf, - count); - if (retval < 0) - goto clean_up; - - if (copy_to_user(buf, rmidev->tmpbuf, count)) - retval = -EFAULT; - else - *f_pos += retval; - - if (!rmidev->concurrent) - goto clean_up; - - if (address != rmi4_data->f01_data_base_addr) - goto clean_up; - - if (count <= 1) - goto clean_up; - - intr_status = rmidev->tmpbuf[1]; - - 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_status) { - rmi4_data->report_touch(rmi4_data, - fhandler); - } - } - } - } - -clean_up: - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -/* - * rmidev_write: write register data to RMI device - * - * @filp: pointer to file structure - * @buf: pointer to user space buffer - * @count: number of bytes to write - * @f_pos: starting RMI register address - */ -static ssize_t rmidev_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - ssize_t retval; - 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; - - rmidev_allocate_buffer(count); - - if (copy_from_user(rmidev->tmpbuf, buf, count)) - return -EFAULT; - - mutex_lock(&(dev_data->file_mutex)); - - retval = synaptics_rmi4_reg_write(rmidev->rmi4_data, - *f_pos, - rmidev->tmpbuf, - count); - if (retval >= 0) - *f_pos += retval; - - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -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; - - if (rmi4_data->sensor_sleep) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Sensor sleeping\n", - __func__); - return -ENODEV; - } - - rmi4_data->stay_awake = true; - - filp->private_data = dev_data; - - mutex_lock(&(dev_data->file_mutex)); - - rmi4_data->irq_enable(rmi4_data, false, 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; -} - -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; - - 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, false); - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt enabled\n", - __func__); - - mutex_unlock(&(dev_data->file_mutex)); - - rmi4_data->reset_device(rmi4_data, false); - - rmi4_data->stay_awake = false; - - 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) -{ - if (rmidev_device_class != NULL) - return 0; - - 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 void rmidev_attn(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask) -{ - if (!rmidev) - return; - - if (rmidev->pid && (rmidev->intr_mask & intr_mask)) - send_sig_info(SIGIO, &rmidev->interrupt_signal, rmidev->task); - - return; -} - -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; - - if (rmidev) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Handle already exists\n", - __func__); - return 0; - } - - 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; - - memset(&rmidev->interrupt_signal, 0, sizeof(rmidev->interrupt_signal)); - rmidev->interrupt_signal.si_signo = SIGIO; - rmidev->interrupt_signal.si_code = SI_USER; - - memset(&rmidev->terminate_signal, 0, sizeof(rmidev->terminate_signal)); - rmidev->terminate_signal.si_signo = SIGTERM; - rmidev->terminate_signal.si_code = SI_USER; - - 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: - if (rmidev_device_class != NULL) { - class_destroy(rmidev_device_class); - rmidev_device_class = NULL; - } - -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; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_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); - - gpio_unexport(bdata->irq_gpio); - - dev_data = rmidev->data; - if (dev_data) { - rmidev_device_cleanup(dev_data); - kfree(dev_data); - } - - unregister_chrdev_region(rmidev->dev_no, 1); - - if (rmidev_device_class != NULL) { - class_destroy(rmidev_device_class); - rmidev_device_class = NULL; - } - - kfree(rmidev->tmpbuf); - - kfree(rmidev); - rmidev = NULL; - -exit: - complete(&rmidev_remove_complete_v26); - - 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 = rmidev_attn, -}; - -static int __init rmidev_module_init(void) -{ - synaptics_rmi4_new_function(&rmidev_module, true); - - return 0; -} - -static void __exit rmidev_module_exit(void) -{ - synaptics_rmi4_new_function(&rmidev_module, false); - - wait_for_completion(&rmidev_remove_complete_v26); - - 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_2.6/synaptics_dsx_rmi_hid_i2c.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_rmi_hid_i2c.c deleted file mode 100644 index 7e02487ece5a..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_rmi_hid_i2c.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define SYN_I2C_RETRY_TIMES 10 - -#define REPORT_ID_GET_BLOB 0x07 -#define REPORT_ID_WRITE 0x09 -#define REPORT_ID_READ_ADDRESS 0x0a -#define REPORT_ID_READ_DATA 0x0b -#define REPORT_ID_SET_RMI_MODE 0x0f - -#define PREFIX_USAGE_PAGE_1BYTE 0x05 -#define PREFIX_USAGE_PAGE_2BYTES 0x06 -#define PREFIX_USAGE 0x09 -#define PREFIX_REPORT_ID 0x85 -#define PREFIX_REPORT_COUNT_1BYTE 0x95 -#define PREFIX_REPORT_COUNT_2BYTES 0x96 - -#define USAGE_GET_BLOB 0xc5 -#define USAGE_WRITE 0x02 -#define USAGE_READ_ADDRESS 0x03 -#define USAGE_READ_DATA 0x04 -#define USAGE_SET_MODE 0x06 - -#define FEATURE_REPORT_TYPE 0x03 - -#define VENDOR_DEFINED_PAGE 0xff00 - -#define BLOB_REPORT_SIZE 256 - -#define RESET_COMMAND 0x01 -#define GET_REPORT_COMMAND 0x02 -#define SET_REPORT_COMMAND 0x03 -#define SET_POWER_COMMAND 0x08 - -#define FINGER_MODE 0x00 -#define RMI_MODE 0x02 - -struct hid_report_info { - unsigned char get_blob_id; - unsigned char write_id; - unsigned char read_addr_id; - unsigned char read_data_id; - unsigned char set_mode_id; - unsigned int blob_size; -}; - -static struct hid_report_info hid_report; - -struct hid_device_descriptor { - unsigned short device_descriptor_length; - unsigned short format_version; - unsigned short report_descriptor_length; - unsigned short report_descriptor_index; - unsigned short input_register_index; - unsigned short input_report_max_length; - unsigned short output_register_index; - unsigned short output_report_max_length; - unsigned short command_register_index; - unsigned short data_register_index; - unsigned short vendor_id; - unsigned short product_id; - unsigned short version_id; - unsigned int reserved; -}; - -static struct hid_device_descriptor hid_dd; - -struct i2c_rw_buffer { - unsigned char *read; - unsigned char *write; - unsigned short read_size; - unsigned short write_size; -}; - -static struct i2c_rw_buffer buffer; - -#ifdef CONFIG_OF -static int parse_dt(struct device *dev, struct synaptics_dsx_board_data *bdata) -{ - int retval; - u32 value; - const char *name; - struct property *prop; - struct device_node *np = dev->of_node; - - bdata->irq_gpio = of_get_named_gpio_flags(np, - "synaptics,irq-gpio", 0, - (enum of_gpio_flags *)&bdata->irq_flags); - - retval = of_property_read_u32(np, "synaptics,irq-on-state", - &value); - if (retval < 0) - bdata->irq_on_state = 0; - else - bdata->irq_on_state = value; - - retval = of_property_read_string(np, "synaptics,pwr-reg-name", &name); - if (retval < 0) - bdata->pwr_reg_name = NULL; - else - bdata->pwr_reg_name = name; - - retval = of_property_read_string(np, "synaptics,bus-reg-name", &name); - if (retval < 0) - bdata->bus_reg_name = NULL; - else - bdata->bus_reg_name = name; - - prop = of_find_property(np, "synaptics,power-gpio", NULL); - if (prop && prop->length) { - bdata->power_gpio = of_get_named_gpio_flags(np, - "synaptics,power-gpio", 0, NULL); - retval = of_property_read_u32(np, "synaptics,power-on-state", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,power-on-state property\n", - __func__); - return retval; - } else { - bdata->power_on_state = value; - } - } else { - bdata->power_gpio = -1; - } - - prop = of_find_property(np, "synaptics,power-delay-ms", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,power-delay-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,power-delay-ms property\n", - __func__); - return retval; - } else { - bdata->power_delay_ms = value; - } - } else { - bdata->power_delay_ms = 0; - } - - prop = of_find_property(np, "synaptics,reset-gpio", NULL); - if (prop && prop->length) { - bdata->reset_gpio = of_get_named_gpio_flags(np, - "synaptics,reset-gpio", 0, NULL); - retval = of_property_read_u32(np, "synaptics,reset-on-state", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-on-state property\n", - __func__); - return retval; - } else { - bdata->reset_on_state = value; - } - retval = of_property_read_u32(np, "synaptics,reset-active-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-active-ms property\n", - __func__); - return retval; - } else { - bdata->reset_active_ms = value; - } - } else { - bdata->reset_gpio = -1; - } - - prop = of_find_property(np, "synaptics,reset-delay-ms", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,reset-delay-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-delay-ms property\n", - __func__); - return retval; - } else { - bdata->reset_delay_ms = value; - } - } else { - bdata->reset_delay_ms = 0; - } - - prop = of_find_property(np, "synaptics,dev-dscrptr-addr", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,dev-dscrptr-addr", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,dev-dscrptr-addr property\n", - __func__); - return retval; - } else { - bdata->device_descriptor_addr = (unsigned short)value; - } - } else { - bdata->device_descriptor_addr = 0; - } - - prop = of_find_property(np, "synaptics,max-y-for-2d", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,max-y-for-2d", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,max-y-for-2d property\n", - __func__); - return retval; - } else { - bdata->max_y_for_2d = value; - } - } else { - bdata->max_y_for_2d = -1; - } - - prop = of_find_property(np, "synaptics,swap-axes", NULL); - bdata->swap_axes = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,x-flip", NULL); - bdata->x_flip = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,y-flip", NULL); - bdata->y_flip = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,ub-i2c-addr", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,ub-i2c-addr", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,ub-i2c-addr property\n", - __func__); - return retval; - } else { - bdata->ub_i2c_addr = (unsigned short)value; - } - } else { - bdata->ub_i2c_addr = -1; - } - - prop = of_find_property(np, "synaptics,cap-button-codes", NULL); - if (prop && prop->length) { - bdata->cap_button_map->map = devm_kzalloc(dev, - prop->length, - GFP_KERNEL); - if (!bdata->cap_button_map->map) - return -ENOMEM; - bdata->cap_button_map->nbuttons = prop->length / sizeof(u32); - retval = of_property_read_u32_array(np, - "synaptics,cap-button-codes", - bdata->cap_button_map->map, - bdata->cap_button_map->nbuttons); - if (retval < 0) { - bdata->cap_button_map->nbuttons = 0; - bdata->cap_button_map->map = NULL; - } - } else { - bdata->cap_button_map->nbuttons = 0; - bdata->cap_button_map->map = NULL; - } - - prop = of_find_property(np, "synaptics,vir-button-codes", NULL); - if (prop && prop->length) { - bdata->vir_button_map->map = devm_kzalloc(dev, - prop->length, - GFP_KERNEL); - if (!bdata->vir_button_map->map) - return -ENOMEM; - bdata->vir_button_map->nbuttons = prop->length / sizeof(u32); - bdata->vir_button_map->nbuttons /= 5; - retval = of_property_read_u32_array(np, - "synaptics,vir-button-codes", - bdata->vir_button_map->map, - bdata->vir_button_map->nbuttons * 5); - if (retval < 0) { - bdata->vir_button_map->nbuttons = 0; - bdata->vir_button_map->map = NULL; - } - } else { - bdata->vir_button_map->nbuttons = 0; - bdata->vir_button_map->map = NULL; - } - - return 0; -} -#endif - -static int do_i2c_transfer(struct i2c_client *client, struct i2c_msg *msg) -{ - unsigned char retry; - - for (retry = 0; retry < SYN_I2C_RETRY_TIMES; retry++) { - if (i2c_transfer(client->adapter, msg, 1) == 1) - break; - dev_err(&client->dev, - "%s: I2C retry %d\n", - __func__, retry + 1); - msleep(20); - } - - if (retry == SYN_I2C_RETRY_TIMES) { - dev_err(&client->dev, - "%s: I2C transfer over retry limit\n", - __func__); - return -EIO; - } - - return 0; -} - -static int check_buffer(unsigned char **buffer, unsigned short *buffer_size, - unsigned short length) -{ - if (*buffer_size < length) { - if (*buffer_size) - kfree(*buffer); - *buffer = kzalloc(length, GFP_KERNEL); - if (!(*buffer)) - return -ENOMEM; - *buffer_size = length; - } - - return 0; -} - -static int generic_read(struct i2c_client *client, unsigned short length) -{ - int retval; - struct i2c_msg msg[] = { - { - .addr = client->addr, - .flags = I2C_M_RD, - .len = length, - } - }; - - check_buffer(&buffer.read, &buffer.read_size, length); - msg[0].buf = buffer.read; - - retval = do_i2c_transfer(client, msg); - - return retval; -} - -static int generic_write(struct i2c_client *client, unsigned short length) -{ - int retval; - struct i2c_msg msg[] = { - { - .addr = client->addr, - .flags = 0, - .len = length, - .buf = buffer.write, - } - }; - - retval = do_i2c_transfer(client, msg); - - return retval; -} - -static void traverse_report_descriptor(unsigned int *index) -{ - unsigned char size; - unsigned char *buf = buffer.read; - - size = buf[*index] & MASK_2BIT; - switch (size) { - case 0: /* 0 bytes */ - *index += 1; - break; - case 1: /* 1 byte */ - *index += 2; - break; - case 2: /* 2 bytes */ - *index += 3; - break; - case 3: /* 4 bytes */ - *index += 5; - break; - default: - break; - } - - return; -} - -static void find_blob_size(unsigned int index) -{ - unsigned int ii = index; - unsigned char *buf = buffer.read; - - while (ii < hid_dd.report_descriptor_length) { - if (buf[ii] == PREFIX_REPORT_COUNT_1BYTE) { - hid_report.blob_size = buf[ii + 1]; - return; - } else if (buf[ii] == PREFIX_REPORT_COUNT_2BYTES) { - hid_report.blob_size = buf[ii + 1] | (buf[ii + 2] << 8); - return; - } - traverse_report_descriptor(&ii); - } - - return; -} - -static void find_reports(unsigned int index) -{ - unsigned int ii = index; - unsigned char *buf = buffer.read; - static unsigned int report_id_index; - static unsigned char report_id; - static unsigned short usage_page; - - if (buf[ii] == PREFIX_REPORT_ID) { - report_id = buf[ii + 1]; - report_id_index = ii; - return; - } - - if (buf[ii] == PREFIX_USAGE_PAGE_1BYTE) { - usage_page = buf[ii + 1]; - return; - } else if (buf[ii] == PREFIX_USAGE_PAGE_2BYTES) { - usage_page = buf[ii + 1] | (buf[ii + 2] << 8); - return; - } - - if ((usage_page == VENDOR_DEFINED_PAGE) && (buf[ii] == PREFIX_USAGE)) { - switch (buf[ii + 1]) { - case USAGE_GET_BLOB: - hid_report.get_blob_id = report_id; - find_blob_size(report_id_index); - break; - case USAGE_WRITE: - hid_report.write_id = report_id; - break; - case USAGE_READ_ADDRESS: - hid_report.read_addr_id = report_id; - break; - case USAGE_READ_DATA: - hid_report.read_data_id = report_id; - break; - case USAGE_SET_MODE: - hid_report.set_mode_id = report_id; - break; - default: - break; - } - } - - return; -} - -static int parse_report_descriptor(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned int ii = 0; - unsigned char *buf; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - - buffer.write[0] = hid_dd.report_descriptor_index & MASK_8BIT; - buffer.write[1] = hid_dd.report_descriptor_index >> 8; - retval = generic_write(i2c, 2); - if (retval < 0) - return retval; - retval = generic_read(i2c, hid_dd.report_descriptor_length); - if (retval < 0) - return retval; - - buf = buffer.read; - - hid_report.get_blob_id = REPORT_ID_GET_BLOB; - hid_report.write_id = REPORT_ID_WRITE; - hid_report.read_addr_id = REPORT_ID_READ_ADDRESS; - hid_report.read_data_id = REPORT_ID_READ_DATA; - hid_report.set_mode_id = REPORT_ID_SET_RMI_MODE; - hid_report.blob_size = BLOB_REPORT_SIZE; - - while (ii < hid_dd.report_descriptor_length) { - find_reports(ii); - traverse_report_descriptor(&ii); - } - - return 0; -} - -static int switch_to_rmi(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); - - check_buffer(&buffer.write, &buffer.write_size, 11); - - /* set rmi mode */ - buffer.write[0] = hid_dd.command_register_index & MASK_8BIT; - buffer.write[1] = hid_dd.command_register_index >> 8; - buffer.write[2] = (FEATURE_REPORT_TYPE << 4) | hid_report.set_mode_id; - buffer.write[3] = SET_REPORT_COMMAND; - buffer.write[4] = hid_report.set_mode_id; - buffer.write[5] = hid_dd.data_register_index & MASK_8BIT; - buffer.write[6] = hid_dd.data_register_index >> 8; - buffer.write[7] = 0x04; - buffer.write[8] = 0x00; - buffer.write[9] = hid_report.set_mode_id; - buffer.write[10] = RMI_MODE; - - retval = generic_write(i2c, 11); - - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - - return retval; -} - -static int check_report_mode(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned short report_size; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - check_buffer(&buffer.write, &buffer.write_size, 7); - - buffer.write[0] = hid_dd.command_register_index & MASK_8BIT; - buffer.write[1] = hid_dd.command_register_index >> 8; - buffer.write[2] = (FEATURE_REPORT_TYPE << 4) | hid_report.set_mode_id; - buffer.write[3] = GET_REPORT_COMMAND; - buffer.write[4] = hid_report.set_mode_id; - buffer.write[5] = hid_dd.data_register_index & MASK_8BIT; - buffer.write[6] = hid_dd.data_register_index >> 8; - - retval = generic_write(i2c, 7); - if (retval < 0) - goto exit; - - retval = generic_read(i2c, 2); - if (retval < 0) - goto exit; - - report_size = (buffer.read[1] << 8) | buffer.read[0]; - - retval = generic_write(i2c, 7); - if (retval < 0) - goto exit; - - retval = generic_read(i2c, report_size); - if (retval < 0) - goto exit; - - retval = buffer.read[3]; - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Report mode = %d\n", - __func__, retval); - -exit: - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - - return retval; -} - -static int hid_i2c_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - check_buffer(&buffer.write, &buffer.write_size, 6); - - /* read device descriptor */ - buffer.write[0] = bdata->device_descriptor_addr & MASK_8BIT; - buffer.write[1] = bdata->device_descriptor_addr >> 8; - retval = generic_write(i2c, 2); - if (retval < 0) - goto exit; - retval = generic_read(i2c, sizeof(hid_dd)); - if (retval < 0) - goto exit; - retval = secure_memcpy((unsigned char *)&hid_dd, - sizeof(struct hid_device_descriptor), - buffer.read, - buffer.read_size, - sizeof(hid_dd)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy device descriptor data\n", - __func__); - goto exit; - } - - retval = parse_report_descriptor(rmi4_data); - if (retval < 0) - goto exit; - - /* set power */ - buffer.write[0] = hid_dd.command_register_index & MASK_8BIT; - buffer.write[1] = hid_dd.command_register_index >> 8; - buffer.write[2] = 0x00; - buffer.write[3] = SET_POWER_COMMAND; - retval = generic_write(i2c, 4); - if (retval < 0) - goto exit; - - /* reset */ - buffer.write[0] = hid_dd.command_register_index & MASK_8BIT; - buffer.write[1] = hid_dd.command_register_index >> 8; - buffer.write[2] = 0x00; - buffer.write[3] = RESET_COMMAND; - retval = generic_write(i2c, 4); - if (retval < 0) - goto exit; - - while (gpio_get_value(bdata->irq_gpio)) - msleep(20); - - retval = generic_read(i2c, hid_dd.input_report_max_length); - if (retval < 0) - goto exit; - - /* get blob */ - buffer.write[0] = hid_dd.command_register_index & MASK_8BIT; - buffer.write[1] = hid_dd.command_register_index >> 8; - buffer.write[2] = (FEATURE_REPORT_TYPE << 4) | hid_report.get_blob_id; - buffer.write[3] = 0x02; - buffer.write[4] = hid_dd.data_register_index & MASK_8BIT; - buffer.write[5] = hid_dd.data_register_index >> 8; - - retval = generic_write(i2c, 6); - if (retval < 0) - goto exit; - - msleep(20); - - retval = generic_read(i2c, hid_report.blob_size + 3); - if (retval < 0) - goto exit; - -exit: - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to initialize HID/I2C interface\n", - __func__); - return retval; - } - - retval = switch_to_rmi(rmi4_data); - - 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 recover = 1; - unsigned short report_length; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - struct i2c_msg msg[] = { - { - .addr = i2c->addr, - .flags = 0, - .len = hid_dd.output_report_max_length + 2, - }, - { - .addr = i2c->addr, - .flags = I2C_M_RD, - .len = length + 4, - }, - }; - -recover: - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - check_buffer(&buffer.write, &buffer.write_size, - hid_dd.output_report_max_length + 2); - msg[0].buf = buffer.write; - buffer.write[0] = hid_dd.output_register_index & MASK_8BIT; - buffer.write[1] = hid_dd.output_register_index >> 8; - buffer.write[2] = hid_dd.output_report_max_length & MASK_8BIT; - buffer.write[3] = hid_dd.output_report_max_length >> 8; - buffer.write[4] = hid_report.read_addr_id; - buffer.write[5] = 0x00; - buffer.write[6] = addr & MASK_8BIT; - buffer.write[7] = addr >> 8; - buffer.write[8] = length & MASK_8BIT; - buffer.write[9] = length >> 8; - - check_buffer(&buffer.read, &buffer.read_size, length + 4); - msg[1].buf = buffer.read; - - retval = do_i2c_transfer(i2c, &msg[0]); - if (retval != 0) - goto exit; - - retry = 0; - do { - retval = do_i2c_transfer(i2c, &msg[1]); - if (retval == 0) - retval = length; - else - goto exit; - - report_length = (buffer.read[1] << 8) | buffer.read[0]; - if (report_length == hid_dd.input_report_max_length) { - retval = secure_memcpy(&data[0], length, - &buffer.read[4], buffer.read_size - 4, - length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy data\n", - __func__); - } else { - retval = length; - } - goto exit; - } - - msleep(20); - retry++; - } while (retry < SYN_I2C_RETRY_TIMES); - - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to receive read report\n", - __func__); - retval = -EIO; - -exit: - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - - if ((retval != length) && (recover == 1)) { - recover = 0; - if (check_report_mode(rmi4_data) != RMI_MODE) { - retval = hid_i2c_init(rmi4_data); - if (retval == 0) - goto recover; - } - } - - 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 recover = 1; - unsigned char msg_length; - struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent); - struct i2c_msg msg[] = { - { - .addr = i2c->addr, - .flags = 0, - } - }; - - if ((length + 10) < (hid_dd.output_report_max_length + 2)) - msg_length = hid_dd.output_report_max_length + 2; - else - msg_length = length + 10; - -recover: - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - check_buffer(&buffer.write, &buffer.write_size, msg_length); - msg[0].len = msg_length; - msg[0].buf = buffer.write; - buffer.write[0] = hid_dd.output_register_index & MASK_8BIT; - buffer.write[1] = hid_dd.output_register_index >> 8; - buffer.write[2] = hid_dd.output_report_max_length & MASK_8BIT; - buffer.write[3] = hid_dd.output_report_max_length >> 8; - buffer.write[4] = hid_report.write_id; - buffer.write[5] = 0x00; - buffer.write[6] = addr & MASK_8BIT; - buffer.write[7] = addr >> 8; - buffer.write[8] = length & MASK_8BIT; - buffer.write[9] = length >> 8; - retval = secure_memcpy(&buffer.write[10], buffer.write_size - 10, - &data[0], length, length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy data\n", - __func__); - } else { - retval = do_i2c_transfer(i2c, msg); - if (retval == 0) - retval = length; - } - - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - - if ((retval != length) && (recover == 1)) { - recover = 0; - if (check_report_mode(rmi4_data) != RMI_MODE) { - retval = hid_i2c_init(rmi4_data); - if (retval == 0) - goto recover; - } - } - - return retval; -} - -static struct synaptics_dsx_bus_access bus_access = { - .type = BUS_I2C, - .read = synaptics_rmi4_i2c_read, - .write = synaptics_rmi4_i2c_write, -}; - -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; -} - -static int synaptics_rmi4_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - int retval; - - 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; - } - - 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; - } - -#ifdef CONFIG_OF - if (client->dev.of_node) { - hw_if.board_data = devm_kzalloc(&client->dev, - sizeof(struct synaptics_dsx_board_data), - GFP_KERNEL); - if (!hw_if.board_data) { - dev_err(&client->dev, - "%s: Failed to allocate memory for board data\n", - __func__); - return -ENOMEM; - } - hw_if.board_data->cap_button_map = devm_kzalloc(&client->dev, - sizeof(struct synaptics_dsx_button_map), - GFP_KERNEL); - if (!hw_if.board_data->cap_button_map) { - dev_err(&client->dev, - "%s: Failed to allocate memory for 0D button map\n", - __func__); - return -ENOMEM; - } - hw_if.board_data->vir_button_map = devm_kzalloc(&client->dev, - sizeof(struct synaptics_dsx_button_map), - GFP_KERNEL); - if (!hw_if.board_data->vir_button_map) { - dev_err(&client->dev, - "%s: Failed to allocate memory for virtual button map\n", - __func__); - return -ENOMEM; - } - parse_dt(&client->dev, hw_if.board_data); - } -#else - hw_if.board_data = client->dev.platform_data; -#endif - - hw_if.bus_access = &bus_access; - hw_if.bl_hw_init = switch_to_rmi; - hw_if.ui_hw_init = hid_i2c_init; - - 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) -{ - if (buffer.read_size) - kfree(buffer.read); - - if (buffer.write_size) - kfree(buffer.write); - - 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 synaptics_rmi4_of_match_table[] = { - { - .compatible = "synaptics,dsx-rmi-hid-i2c", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, synaptics_rmi4_of_match_table); -#else -#define synaptics_rmi4_of_match_table NULL -#endif - -static struct i2c_driver synaptics_rmi4_i2c_driver = { - .driver = { - .name = I2C_DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = synaptics_rmi4_of_match_table, - }, - .probe = synaptics_rmi4_i2c_probe, - .remove = synaptics_rmi4_i2c_remove, - .id_table = synaptics_rmi4_id_table, -}; - -int synaptics_rmi4_bus_init_v26(void) -{ - return i2c_add_driver(&synaptics_rmi4_i2c_driver); -} -EXPORT_SYMBOL(synaptics_rmi4_bus_init_v26); - -void synaptics_rmi4_bus_exit_v26(void) -{ - i2c_del_driver(&synaptics_rmi4_i2c_driver); - - return; -} -EXPORT_SYMBOL(synaptics_rmi4_bus_exit_v26); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX I2C Bus Support Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_spi.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_spi.c deleted file mode 100644 index 382a3dd029d7..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_spi.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define SPI_READ 0x80 -#define SPI_WRITE 0x00 - -#ifdef CONFIG_OF -static int parse_dt(struct device *dev, struct synaptics_dsx_board_data *bdata) -{ - int retval; - u32 value; - const char *name; - struct property *prop; - struct device_node *np = dev->of_node; - - bdata->irq_gpio = of_get_named_gpio_flags(np, - "synaptics,irq-gpio", 0, - (enum of_gpio_flags *)&bdata->irq_flags); - - retval = of_property_read_u32(np, "synaptics,irq-on-state", - &value); - if (retval < 0) - bdata->irq_on_state = 0; - else - bdata->irq_on_state = value; - - retval = of_property_read_string(np, "synaptics,pwr-reg-name", &name); - if (retval < 0) - bdata->pwr_reg_name = NULL; - else - bdata->pwr_reg_name = name; - - retval = of_property_read_string(np, "synaptics,bus-reg-name", &name); - if (retval < 0) - bdata->bus_reg_name = NULL; - else - bdata->bus_reg_name = name; - - prop = of_find_property(np, "synaptics,power-gpio", NULL); - if (prop && prop->length) { - bdata->power_gpio = of_get_named_gpio_flags(np, - "synaptics,power-gpio", 0, NULL); - retval = of_property_read_u32(np, "synaptics,power-on-state", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,power-on-state property\n", - __func__); - return retval; - } else { - bdata->power_on_state = value; - } - } else { - bdata->power_gpio = -1; - } - - prop = of_find_property(np, "synaptics,power-delay-ms", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,power-delay-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,power-delay-ms property\n", - __func__); - return retval; - } else { - bdata->power_delay_ms = value; - } - } else { - bdata->power_delay_ms = 0; - } - - prop = of_find_property(np, "synaptics,reset-gpio", NULL); - if (prop && prop->length) { - bdata->reset_gpio = of_get_named_gpio_flags(np, - "synaptics,reset-gpio", 0, NULL); - retval = of_property_read_u32(np, "synaptics,reset-on-state", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-on-state property\n", - __func__); - return retval; - } else { - bdata->reset_on_state = value; - } - retval = of_property_read_u32(np, "synaptics,reset-active-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-active-ms property\n", - __func__); - return retval; - } else { - bdata->reset_active_ms = value; - } - } else { - bdata->reset_gpio = -1; - } - - prop = of_find_property(np, "synaptics,reset-delay-ms", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,reset-delay-ms", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,reset-delay-ms property\n", - __func__); - return retval; - } else { - bdata->reset_delay_ms = value; - } - } else { - bdata->reset_delay_ms = 0; - } - - prop = of_find_property(np, "synaptics,byte-delay-us", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,byte-delay-us", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,byte-delay-us property\n", - __func__); - return retval; - } else { - bdata->byte_delay_us = value; - } - } else { - bdata->byte_delay_us = 0; - } - - prop = of_find_property(np, "synaptics,block-delay-us", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,block-delay-us", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,block-delay-us property\n", - __func__); - return retval; - } else { - bdata->block_delay_us = value; - } - } else { - bdata->block_delay_us = 0; - } - - prop = of_find_property(np, "synaptics,max-y-for-2d", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,max-y-for-2d", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,max-y-for-2d property\n", - __func__); - return retval; - } else { - bdata->max_y_for_2d = value; - } - } else { - bdata->max_y_for_2d = -1; - } - - prop = of_find_property(np, "synaptics,swap-axes", NULL); - bdata->swap_axes = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,x-flip", NULL); - bdata->x_flip = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,y-flip", NULL); - bdata->y_flip = prop > 0 ? true : false; - - prop = of_find_property(np, "synaptics,ub-i2c-addr", NULL); - if (prop && prop->length) { - retval = of_property_read_u32(np, "synaptics,ub-i2c-addr", - &value); - if (retval < 0) { - dev_err(dev, "%s: Unable to read synaptics,ub-i2c-addr property\n", - __func__); - return retval; - } else { - bdata->ub_i2c_addr = (unsigned short)value; - } - } else { - bdata->ub_i2c_addr = -1; - } - - prop = of_find_property(np, "synaptics,cap-button-codes", NULL); - if (prop && prop->length) { - bdata->cap_button_map->map = devm_kzalloc(dev, - prop->length, - GFP_KERNEL); - if (!bdata->cap_button_map->map) - return -ENOMEM; - bdata->cap_button_map->nbuttons = prop->length / sizeof(u32); - retval = of_property_read_u32_array(np, - "synaptics,cap-button-codes", - bdata->cap_button_map->map, - bdata->cap_button_map->nbuttons); - if (retval < 0) { - bdata->cap_button_map->nbuttons = 0; - bdata->cap_button_map->map = NULL; - } - } else { - bdata->cap_button_map->nbuttons = 0; - bdata->cap_button_map->map = NULL; - } - - prop = of_find_property(np, "synaptics,vir-button-codes", NULL); - if (prop && prop->length) { - bdata->vir_button_map->map = devm_kzalloc(dev, - prop->length, - GFP_KERNEL); - if (!bdata->vir_button_map->map) - return -ENOMEM; - bdata->vir_button_map->nbuttons = prop->length / sizeof(u32); - bdata->vir_button_map->nbuttons /= 5; - retval = of_property_read_u32_array(np, - "synaptics,vir-button-codes", - bdata->vir_button_map->map, - bdata->vir_button_map->nbuttons * 5); - if (retval < 0) { - bdata->vir_button_map->nbuttons = 0; - bdata->vir_button_map->map = NULL; - } - } else { - bdata->vir_button_map->nbuttons = 0; - bdata->vir_button_map->map = NULL; - } - - return 0; -} -#endif - -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) { - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - 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 = secure_memcpy(data, length, rxbuf, length, length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy data\n", - __func__); - } else { - 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(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; - retval = secure_memcpy(&txbuf[ADDRESS_WORD_LEN], - xfer_count - ADDRESS_WORD_LEN, data, length, length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy data\n", - __func__); - goto exit; - } - - mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); - - retval = synaptics_rmi4_spi_set_page(rmi4_data, addr); - if (retval != PAGE_SELECT_LEN) { - mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); - 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; - } - -#ifdef CONFIG_OF - if (spi->dev.of_node) { - hw_if.board_data = devm_kzalloc(&spi->dev, - sizeof(struct synaptics_dsx_board_data), - GFP_KERNEL); - if (!hw_if.board_data) { - dev_err(&spi->dev, - "%s: Failed to allocate memory for board data\n", - __func__); - return -ENOMEM; - } - hw_if.board_data->cap_button_map = devm_kzalloc(&spi->dev, - sizeof(struct synaptics_dsx_button_map), - GFP_KERNEL); - if (!hw_if.board_data->cap_button_map) { - dev_err(&spi->dev, - "%s: Failed to allocate memory for 0D button map\n", - __func__); - return -ENOMEM; - } - hw_if.board_data->vir_button_map = devm_kzalloc(&spi->dev, - sizeof(struct synaptics_dsx_button_map), - GFP_KERNEL); - if (!hw_if.board_data->vir_button_map) { - dev_err(&spi->dev, - "%s: Failed to allocate memory for virtual button map\n", - __func__); - return -ENOMEM; - } - parse_dt(&spi->dev, hw_if.board_data); - } -#else - hw_if.board_data = spi->dev.platform_data; -#endif - - hw_if.bus_access = &bus_access; - - 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; - } - - 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; -} - -#ifdef CONFIG_OF -static struct of_device_id synaptics_rmi4_of_match_table[] = { - { - .compatible = "synaptics,dsx-spi", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, synaptics_rmi4_of_match_table); -#else -#define synaptics_rmi4_of_match_table NULL -#endif - -static struct spi_driver synaptics_rmi4_spi_driver = { - .driver = { - .name = SPI_DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = synaptics_rmi4_of_match_table, - }, - .probe = synaptics_rmi4_spi_probe, - .remove = synaptics_rmi4_spi_remove, -}; - - -int synaptics_rmi4_bus_init_v26(void) -{ - return spi_register_driver(&synaptics_rmi4_spi_driver); -} -EXPORT_SYMBOL(synaptics_rmi4_bus_init_v26); - -void synaptics_rmi4_bus_exit_v26(void) -{ - spi_unregister_driver(&synaptics_rmi4_spi_driver); - - return; -} -EXPORT_SYMBOL(synaptics_rmi4_bus_exit_v26); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX SPI Bus Support Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_test_reporting.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_test_reporting.c deleted file mode 100644 index d42b23e46d0a..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_test_reporting.c +++ /dev/null @@ -1,4162 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define SYSFS_FOLDER_NAME "f54" - -#define GET_REPORT_TIMEOUT_S 3 -#define CALIBRATION_TIMEOUT_S 10 -#define COMMAND_TIMEOUT_100MS 20 - -#define NO_SLEEP_OFF (0 << 2) -#define NO_SLEEP_ON (1 << 2) - -#define STATUS_IDLE 0 -#define STATUS_BUSY 1 -#define STATUS_ERROR 2 - -#define REPORT_INDEX_OFFSET 1 -#define REPORT_DATA_OFFSET 3 - -#define SENSOR_RX_MAPPING_OFFSET 1 -#define SENSOR_TX_MAPPING_OFFSET 2 - -#define COMMAND_GET_REPORT 1 -#define COMMAND_FORCE_CAL 2 -#define COMMAND_FORCE_UPDATE 4 - -#define CONTROL_NO_AUTO_CAL 1 - -#define CONTROL_0_SIZE 1 -#define CONTROL_1_SIZE 1 -#define CONTROL_2_SIZE 2 -#define CONTROL_3_SIZE 1 -#define CONTROL_4_6_SIZE 3 -#define CONTROL_7_SIZE 1 -#define CONTROL_8_9_SIZE 3 -#define CONTROL_10_SIZE 1 -#define CONTROL_11_SIZE 2 -#define CONTROL_12_13_SIZE 2 -#define CONTROL_14_SIZE 1 -#define CONTROL_15_SIZE 1 -#define CONTROL_16_SIZE 1 -#define CONTROL_17_SIZE 1 -#define CONTROL_18_SIZE 1 -#define CONTROL_19_SIZE 1 -#define CONTROL_20_SIZE 1 -#define CONTROL_21_SIZE 2 -#define CONTROL_22_26_SIZE 7 -#define CONTROL_27_SIZE 1 -#define CONTROL_28_SIZE 2 -#define CONTROL_29_SIZE 1 -#define CONTROL_30_SIZE 1 -#define CONTROL_31_SIZE 1 -#define CONTROL_32_35_SIZE 8 -#define CONTROL_36_SIZE 1 -#define CONTROL_37_SIZE 1 -#define CONTROL_38_SIZE 1 -#define CONTROL_39_SIZE 1 -#define CONTROL_40_SIZE 1 -#define CONTROL_41_SIZE 1 -#define CONTROL_42_SIZE 2 -#define CONTROL_43_54_SIZE 13 -#define CONTROL_55_56_SIZE 2 -#define CONTROL_57_SIZE 1 -#define CONTROL_58_SIZE 1 -#define CONTROL_59_SIZE 2 -#define CONTROL_60_62_SIZE 3 -#define CONTROL_63_SIZE 1 -#define CONTROL_64_67_SIZE 4 -#define CONTROL_68_73_SIZE 8 -#define CONTROL_74_SIZE 2 -#define CONTROL_75_SIZE 1 -#define CONTROL_76_SIZE 1 -#define CONTROL_77_78_SIZE 2 -#define CONTROL_79_83_SIZE 5 -#define CONTROL_84_85_SIZE 2 -#define CONTROL_86_SIZE 1 -#define CONTROL_87_SIZE 1 -#define CONTROL_88_SIZE 1 -#define CONTROL_89_SIZE 1 -#define CONTROL_90_SIZE 1 -#define CONTROL_91_SIZE 1 -#define CONTROL_92_SIZE 1 -#define CONTROL_93_SIZE 1 -#define CONTROL_94_SIZE 1 -#define CONTROL_95_SIZE 1 -#define CONTROL_96_SIZE 1 -#define CONTROL_97_SIZE 1 -#define CONTROL_98_SIZE 1 -#define CONTROL_99_SIZE 1 -#define CONTROL_100_SIZE 1 -#define CONTROL_101_SIZE 1 -#define CONTROL_102_SIZE 1 -#define CONTROL_103_SIZE 1 -#define CONTROL_104_SIZE 1 -#define CONTROL_105_SIZE 1 -#define CONTROL_106_SIZE 1 -#define CONTROL_107_SIZE 1 -#define CONTROL_108_SIZE 1 -#define CONTROL_109_SIZE 1 -#define CONTROL_110_SIZE 1 -#define CONTROL_111_SIZE 1 -#define CONTROL_112_SIZE 1 -#define CONTROL_113_SIZE 1 -#define CONTROL_114_SIZE 1 -#define CONTROL_115_SIZE 1 -#define CONTROL_116_SIZE 1 -#define CONTROL_117_SIZE 1 -#define CONTROL_118_SIZE 1 -#define CONTROL_119_SIZE 1 -#define CONTROL_120_SIZE 1 -#define CONTROL_121_SIZE 1 -#define CONTROL_122_SIZE 1 -#define CONTROL_123_SIZE 1 -#define CONTROL_124_SIZE 1 -#define CONTROL_125_SIZE 1 -#define CONTROL_126_SIZE 1 -#define CONTROL_127_SIZE 1 -#define CONTROL_128_SIZE 1 -#define CONTROL_129_SIZE 1 -#define CONTROL_130_SIZE 1 -#define CONTROL_131_SIZE 1 -#define CONTROL_132_SIZE 1 -#define CONTROL_133_SIZE 1 -#define CONTROL_134_SIZE 1 -#define CONTROL_135_SIZE 1 -#define CONTROL_136_SIZE 1 -#define CONTROL_137_SIZE 1 -#define CONTROL_138_SIZE 1 -#define CONTROL_139_SIZE 1 -#define CONTROL_140_SIZE 1 -#define CONTROL_141_SIZE 1 -#define CONTROL_142_SIZE 1 -#define CONTROL_143_SIZE 1 -#define CONTROL_144_SIZE 1 -#define CONTROL_145_SIZE 1 -#define CONTROL_146_SIZE 1 -#define CONTROL_147_SIZE 1 -#define CONTROL_148_SIZE 1 -#define CONTROL_149_SIZE 1 -#define CONTROL_163_SIZE 1 -#define CONTROL_165_SIZE 1 -#define CONTROL_167_SIZE 1 -#define CONTROL_176_SIZE 1 -#define CONTROL_179_SIZE 1 -#define CONTROL_188_SIZE 1 - -#define HIGH_RESISTANCE_DATA_SIZE 6 -#define FULL_RAW_CAP_MIN_MAX_DATA_SIZE 4 -#define TRX_OPEN_SHORT_DATA_SIZE 7 - -#define concat(a, b) a##b - -#define attrify(propname) (&dev_attr_##propname.attr) - -#define show_prototype(propname)\ -static ssize_t concat(test_sysfs, _##propname##_show)(\ - struct device *dev,\ - struct device_attribute *attr,\ - char *buf); - -#define store_prototype(propname)\ -static ssize_t concat(test_sysfs, _##propname##_store)(\ - struct device *dev,\ - struct device_attribute *attr,\ - const char *buf, size_t count); - -#define show_store_prototype(propname)\ -static ssize_t concat(test_sysfs, _##propname##_show)(\ - struct device *dev,\ - struct device_attribute *attr,\ - char *buf);\ -\ -static ssize_t concat(test_sysfs, _##propname##_store)(\ - struct device *dev,\ - struct device_attribute *attr,\ - const char *buf, size_t count);\ -\ -static struct device_attribute dev_attr_##propname =\ - __ATTR(propname, (S_IRUGO | S_IWUGO),\ - concat(test_sysfs, _##propname##_show),\ - concat(test_sysfs, _##propname##_store)); - -#define disable_cbc(ctrl_num)\ -do {\ - retval = synaptics_rmi4_reg_read(rmi4_data,\ - f54->control.ctrl_num->address,\ - f54->control.ctrl_num->data,\ - sizeof(f54->control.ctrl_num->data));\ - if (retval < 0) {\ - dev_err(rmi4_data->pdev->dev.parent,\ - "%s: Failed to disable CBC (" #ctrl_num ")\n",\ - __func__);\ - return retval;\ - } \ - f54->control.ctrl_num->cbc_tx_carrier_selection = 0;\ - retval = synaptics_rmi4_reg_write(rmi4_data,\ - f54->control.ctrl_num->address,\ - f54->control.ctrl_num->data,\ - sizeof(f54->control.ctrl_num->data));\ - if (retval < 0) {\ - dev_err(rmi4_data->pdev->dev.parent,\ - "%s: Failed to disable CBC (" #ctrl_num ")\n",\ - __func__);\ - return retval;\ - } \ -} while (0) - -enum f54_report_types { - F54_8BIT_IMAGE = 1, - F54_16BIT_IMAGE = 2, - F54_RAW_16BIT_IMAGE = 3, - F54_HIGH_RESISTANCE = 4, - F54_TX_TO_TX_SHORTS = 5, - F54_RX_TO_RX_SHORTS_1 = 7, - F54_TRUE_BASELINE = 9, - F54_FULL_RAW_CAP_MIN_MAX = 13, - F54_RX_OPENS_1 = 14, - F54_TX_OPENS = 15, - F54_TX_TO_GND_SHORTS = 16, - F54_RX_TO_RX_SHORTS_2 = 17, - F54_RX_OPENS_2 = 18, - F54_FULL_RAW_CAP = 19, - F54_FULL_RAW_CAP_NO_RX_COUPLING = 20, - F54_SENSOR_SPEED = 22, - F54_ADC_RANGE = 23, - F54_TRX_OPENS = 24, - F54_TRX_TO_GND_SHORTS = 25, - F54_TRX_SHORTS = 26, - F54_ABS_RAW_CAP = 38, - F54_ABS_DELTA_CAP = 40, - F54_ABS_HYBRID_DELTA_CAP = 59, - F54_ABS_HYBRID_RAW_CAP = 63, - F54_AMP_FULL_RAW_CAP = 78, - F54_AMP_RAW_ADC = 83, - INVALID_REPORT_TYPE = -1, -}; - -enum f54_afe_cal { - F54_AFE_CAL, - F54_AFE_IS_CAL, -}; - -struct f54_query { - union { - struct { - /* query 0 */ - unsigned char num_of_rx_electrodes; - - /* query 1 */ - unsigned char num_of_tx_electrodes; - - /* query 2 */ - unsigned char f54_query2_b0__1:2; - unsigned char has_baseline:1; - unsigned char has_image8:1; - unsigned char f54_query2_b4__5:2; - unsigned char has_image16:1; - unsigned char f54_query2_b7:1; - - /* queries 3.0 and 3.1 */ - unsigned short clock_rate; - - /* query 4 */ - unsigned char touch_controller_family; - - /* query 5 */ - unsigned char has_pixel_touch_threshold_adjustment:1; - unsigned char f54_query5_b1__7:7; - - /* query 6 */ - unsigned char has_sensor_assignment:1; - unsigned char has_interference_metric:1; - unsigned char has_sense_frequency_control:1; - unsigned char has_firmware_noise_mitigation:1; - unsigned char has_ctrl11:1; - unsigned char has_two_byte_report_rate:1; - unsigned char has_one_byte_report_rate:1; - unsigned char has_relaxation_control:1; - - /* query 7 */ - unsigned char curve_compensation_mode:2; - unsigned char f54_query7_b2__7:6; - - /* query 8 */ - unsigned char f54_query8_b0:1; - unsigned char has_iir_filter:1; - unsigned char has_cmn_removal:1; - unsigned char has_cmn_maximum:1; - unsigned char has_touch_hysteresis:1; - unsigned char has_edge_compensation:1; - unsigned char has_per_frequency_noise_control:1; - unsigned char has_enhanced_stretch:1; - - /* query 9 */ - unsigned char has_force_fast_relaxation:1; - unsigned char has_multi_metric_state_machine:1; - unsigned char has_signal_clarity:1; - unsigned char has_variance_metric:1; - unsigned char has_0d_relaxation_control:1; - unsigned char has_0d_acquisition_control:1; - unsigned char has_status:1; - unsigned char has_slew_metric:1; - - /* query 10 */ - unsigned char has_h_blank:1; - unsigned char has_v_blank:1; - unsigned char has_long_h_blank:1; - unsigned char has_startup_fast_relaxation:1; - unsigned char has_esd_control:1; - unsigned char has_noise_mitigation2:1; - unsigned char has_noise_state:1; - unsigned char has_energy_ratio_relaxation:1; - - /* query 11 */ - unsigned char has_excessive_noise_reporting:1; - unsigned char has_slew_option:1; - unsigned char has_two_overhead_bursts:1; - unsigned char has_query13:1; - unsigned char has_one_overhead_burst:1; - unsigned char f54_query11_b5:1; - unsigned char has_ctrl88:1; - unsigned char has_query15:1; - - /* query 12 */ - unsigned char number_of_sensing_frequencies:4; - unsigned char f54_query12_b4__7:4; - } __packed; - unsigned char data[14]; - }; -}; - -struct f54_query_13 { - union { - struct { - unsigned char has_ctrl86:1; - unsigned char has_ctrl87:1; - unsigned char has_ctrl87_sub0:1; - unsigned char has_ctrl87_sub1:1; - unsigned char has_ctrl87_sub2:1; - unsigned char has_cidim:1; - unsigned char has_noise_mitigation_enhancement:1; - unsigned char has_rail_im:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_15 { - union { - struct { - unsigned char has_ctrl90:1; - unsigned char has_transmit_strength:1; - unsigned char has_ctrl87_sub3:1; - unsigned char has_query16:1; - unsigned char has_query20:1; - unsigned char has_query21:1; - unsigned char has_query22:1; - unsigned char has_query25:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_16 { - union { - struct { - unsigned char has_query17:1; - unsigned char has_data17:1; - unsigned char has_ctrl92:1; - unsigned char has_ctrl93:1; - unsigned char has_ctrl94_query18:1; - unsigned char has_ctrl95_query19:1; - unsigned char has_ctrl99:1; - unsigned char has_ctrl100:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_21 { - union { - struct { - unsigned char has_abs_rx:1; - unsigned char has_abs_tx:1; - unsigned char has_ctrl91:1; - unsigned char has_ctrl96:1; - unsigned char has_ctrl97:1; - unsigned char has_ctrl98:1; - unsigned char has_data19:1; - unsigned char has_query24_data18:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_22 { - union { - struct { - unsigned char has_packed_image:1; - unsigned char has_ctrl101:1; - unsigned char has_dynamic_sense_display_ratio:1; - unsigned char has_query23:1; - unsigned char has_ctrl103_query26:1; - unsigned char has_ctrl104:1; - unsigned char has_ctrl105:1; - unsigned char has_query28:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_23 { - union { - struct { - unsigned char has_ctrl102:1; - unsigned char has_ctrl102_sub1:1; - unsigned char has_ctrl102_sub2:1; - unsigned char has_ctrl102_sub4:1; - unsigned char has_ctrl102_sub5:1; - unsigned char has_ctrl102_sub9:1; - unsigned char has_ctrl102_sub10:1; - unsigned char has_ctrl102_sub11:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_25 { - union { - struct { - unsigned char has_ctrl106:1; - unsigned char has_ctrl102_sub12:1; - unsigned char has_ctrl107:1; - unsigned char has_ctrl108:1; - unsigned char has_ctrl109:1; - unsigned char has_data20:1; - unsigned char f54_query25_b6:1; - unsigned char has_query27:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_27 { - union { - struct { - unsigned char has_ctrl110:1; - unsigned char has_data21:1; - unsigned char has_ctrl111:1; - unsigned char has_ctrl112:1; - unsigned char has_ctrl113:1; - unsigned char has_data22:1; - unsigned char has_ctrl114:1; - unsigned char has_query29:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_29 { - union { - struct { - unsigned char has_ctrl115:1; - unsigned char has_ground_ring_options:1; - unsigned char has_lost_bursts_tuning:1; - unsigned char has_aux_exvcom2_select:1; - unsigned char has_ctrl116:1; - unsigned char has_data23:1; - unsigned char has_ctrl117:1; - unsigned char has_query30:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_30 { - union { - struct { - unsigned char has_ctrl118:1; - unsigned char has_ctrl119:1; - unsigned char has_ctrl120:1; - unsigned char has_ctrl121:1; - unsigned char has_ctrl122_query31:1; - unsigned char has_ctrl123:1; - unsigned char f54_query30_b6:1; - unsigned char has_query32:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_32 { - union { - struct { - unsigned char has_ctrl125:1; - unsigned char has_ctrl126:1; - unsigned char has_ctrl127:1; - unsigned char has_abs_charge_pump_disable:1; - unsigned char has_query33:1; - unsigned char has_data24:1; - unsigned char has_query34:1; - unsigned char has_query35:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_33 { - union { - struct { - unsigned char f54_query33_b0:1; - unsigned char f54_query33_b1:1; - unsigned char f54_query33_b2:1; - unsigned char f54_query33_b3:1; - unsigned char has_ctrl132:1; - unsigned char has_ctrl133:1; - unsigned char has_ctrl134:1; - unsigned char has_query36:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_35 { - union { - struct { - unsigned char has_data25:1; - unsigned char f54_query35_b1:1; - unsigned char f54_query35_b2:1; - unsigned char has_ctrl137:1; - unsigned char has_ctrl138:1; - unsigned char has_ctrl139:1; - unsigned char has_data26:1; - unsigned char has_ctrl140:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_36 { - union { - struct { - unsigned char f54_query36_b0:1; - unsigned char has_ctrl142:1; - unsigned char has_query37:1; - unsigned char has_ctrl143:1; - unsigned char has_ctrl144:1; - unsigned char has_ctrl145:1; - unsigned char has_ctrl146:1; - unsigned char has_query38:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_38 { - union { - struct { - unsigned char has_ctrl147:1; - unsigned char has_ctrl148:1; - unsigned char has_ctrl149:1; - unsigned char f54_query38_b3__6:4; - unsigned char has_query39:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_39 { - union { - struct { - unsigned char f54_query39_b0__6:7; - unsigned char has_query40:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_40 { - union { - struct { - unsigned char f54_query40_b0:1; - unsigned char has_ctrl163_query41:1; - unsigned char f54_query40_b2:1; - unsigned char has_ctrl165_query42:1; - unsigned char f54_query40_b4:1; - unsigned char has_ctrl167:1; - unsigned char f54_query40_b6:1; - unsigned char has_query43:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_43 { - union { - struct { - unsigned char f54_query43_b0__6:7; - unsigned char has_query46:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_46 { - union { - struct { - unsigned char has_ctrl176:1; - unsigned char f54_query46_b1:1; - unsigned char has_ctrl179:1; - unsigned char f54_query46_b3:1; - unsigned char has_data27:1; - unsigned char has_data28:1; - unsigned char f54_query46_b6:1; - unsigned char has_query47:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_47 { - union { - struct { - unsigned char f54_query47_b0__6:7; - unsigned char has_query49:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_49 { - union { - struct { - unsigned char f54_query49_b0__1:2; - unsigned char has_ctrl188:1; - unsigned char has_data31:1; - unsigned char f54_query49_b4__6:3; - unsigned char has_query50:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_50 { - union { - struct { - unsigned char f54_query50_b0__6:7; - unsigned char has_query51:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_query_51 { - union { - struct { - unsigned char f54_query51_b0__4:5; - unsigned char has_query53_query54_ctrl198:1; - unsigned char f54_query51_b6__7:2; - } __packed; - unsigned char data[1]; - }; -}; - -struct f54_data_31 { - union { - struct { - unsigned char is_calibration_crc:1; - unsigned char calibration_crc:1; - unsigned char short_test_row_number:5; - } __packed; - struct { - unsigned char data[1]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control_7 { - union { - struct { - unsigned char cbc_cap:3; - unsigned char cbc_polarity:1; - unsigned char cbc_tx_carrier_selection:1; - unsigned char f54_ctrl7_b5__7:3; - } __packed; - struct { - unsigned char data[1]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control_41 { - union { - struct { - unsigned char no_signal_clarity:1; - unsigned char f54_ctrl41_b1__7:7; - } __packed; - struct { - unsigned char data[1]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control_57 { - union { - struct { - unsigned char cbc_cap:3; - unsigned char cbc_polarity:1; - unsigned char cbc_tx_carrier_selection:1; - unsigned char f54_ctrl57_b5__7:3; - } __packed; - struct { - unsigned char data[1]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control_86 { - union { - struct { - unsigned char enable_high_noise_state:1; - unsigned char dynamic_sense_display_ratio:2; - unsigned char f54_ctrl86_b3__7:5; - } __packed; - struct { - unsigned char data[1]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control_88 { - union { - struct { - unsigned char tx_low_reference_polarity:1; - unsigned char tx_high_reference_polarity:1; - unsigned char abs_low_reference_polarity:1; - unsigned char abs_polarity:1; - unsigned char cbc_polarity:1; - unsigned char cbc_tx_carrier_selection:1; - unsigned char charge_pump_enable:1; - unsigned char cbc_abs_auto_servo:1; - } __packed; - struct { - unsigned char data[1]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control_110 { - union { - struct { - unsigned char active_stylus_rx_feedback_cap; - unsigned char active_stylus_rx_feedback_cap_reference; - unsigned char active_stylus_low_reference; - unsigned char active_stylus_high_reference; - unsigned char active_stylus_gain_control; - unsigned char active_stylus_gain_control_reference; - unsigned char active_stylus_timing_mode; - unsigned char active_stylus_discovery_bursts; - unsigned char active_stylus_detection_bursts; - unsigned char active_stylus_discovery_noise_multiplier; - unsigned char active_stylus_detection_envelope_min; - unsigned char active_stylus_detection_envelope_max; - unsigned char active_stylus_lose_count; - } __packed; - struct { - unsigned char data[13]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control_149 { - union { - struct { - unsigned char trans_cbc_global_cap_enable:1; - unsigned char f54_ctrl149_b1__7:7; - } __packed; - struct { - unsigned char data[1]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control_188 { - union { - struct { - unsigned char start_calibration:1; - unsigned char start_is_calibration:1; - unsigned char frequency:2; - unsigned char start_production_test:1; - unsigned char short_test_calibration:1; - unsigned char f54_ctrl188_b7:1; - } __packed; - struct { - unsigned char data[1]; - unsigned short address; - } __packed; - }; -}; - -struct f54_control { - struct f54_control_7 *reg_7; - struct f54_control_41 *reg_41; - struct f54_control_57 *reg_57; - struct f54_control_86 *reg_86; - struct f54_control_88 *reg_88; - struct f54_control_110 *reg_110; - struct f54_control_149 *reg_149; - struct f54_control_188 *reg_188; -}; - -struct synaptics_rmi4_f54_handle { - bool no_auto_cal; - bool skip_preparation; - unsigned char status; - unsigned char intr_mask; - unsigned char intr_reg_num; - unsigned char tx_assigned; - unsigned char rx_assigned; - unsigned char *report_data; - unsigned short query_base_addr; - unsigned short control_base_addr; - unsigned short data_base_addr; - unsigned short command_base_addr; - unsigned short fifoindex; - unsigned int report_size; - unsigned int data_buffer_size; - unsigned int data_pos; - enum f54_report_types report_type; - struct f54_query query; - struct f54_query_13 query_13; - struct f54_query_15 query_15; - struct f54_query_16 query_16; - struct f54_query_21 query_21; - struct f54_query_22 query_22; - struct f54_query_23 query_23; - struct f54_query_25 query_25; - struct f54_query_27 query_27; - struct f54_query_29 query_29; - struct f54_query_30 query_30; - struct f54_query_32 query_32; - struct f54_query_33 query_33; - struct f54_query_35 query_35; - struct f54_query_36 query_36; - struct f54_query_38 query_38; - struct f54_query_39 query_39; - struct f54_query_40 query_40; - struct f54_query_43 query_43; - struct f54_query_46 query_46; - struct f54_query_47 query_47; - struct f54_query_49 query_49; - struct f54_query_50 query_50; - struct f54_query_51 query_51; - struct f54_data_31 data_31; - struct f54_control control; - struct mutex status_mutex; - struct kobject *sysfs_dir; - struct hrtimer watchdog; - struct work_struct timeout_work; - struct work_struct test_report_work; - struct workqueue_struct *test_report_workqueue; - struct synaptics_rmi4_data *rmi4_data; -}; - -struct f55_query { - union { - struct { - /* query 0 */ - unsigned char num_of_rx_electrodes; - - /* query 1 */ - unsigned char num_of_tx_electrodes; - - /* query 2 */ - unsigned char has_sensor_assignment:1; - unsigned char has_edge_compensation:1; - unsigned char curve_compensation_mode:2; - unsigned char has_ctrl6:1; - unsigned char has_alternate_transmitter_assignment:1; - unsigned char has_single_layer_multi_touch:1; - unsigned char has_query5:1; - } __packed; - unsigned char data[3]; - }; -}; - -struct f55_query_3 { - union { - struct { - unsigned char has_ctrl8:1; - unsigned char has_ctrl9:1; - unsigned char has_oncell_pattern_support:1; - unsigned char has_data0:1; - unsigned char has_single_wide_pattern_support:1; - unsigned char has_mirrored_tx_pattern_support:1; - unsigned char has_discrete_pattern_support:1; - unsigned char has_query9:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f55_query_5 { - union { - struct { - unsigned char has_corner_compensation:1; - unsigned char has_ctrl12:1; - unsigned char has_trx_configuration:1; - unsigned char has_ctrl13:1; - unsigned char f55_query5_b4:1; - unsigned char has_ctrl14:1; - unsigned char has_basis_function:1; - unsigned char has_query17:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f55_query_17 { - union { - struct { - unsigned char f55_query17_b0:1; - unsigned char has_ctrl16:1; - unsigned char f55_query17_b2:1; - unsigned char has_ctrl17:1; - unsigned char f55_query17_b4__6:3; - unsigned char has_query18:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f55_query_18 { - union { - struct { - unsigned char f55_query18_b0__6:7; - unsigned char has_query22:1; - } __packed; - unsigned char data[1]; - }; -}; - -struct f55_query_22 { - union { - struct { - unsigned char f55_query22_b0:1; - unsigned char has_query23:1; - unsigned char has_guard_disable:1; - unsigned char has_ctrl30:1; - unsigned char f55_query22_b4__7:4; - } __packed; - unsigned char data[1]; - }; -}; - -struct f55_query_23 { - union { - struct { - unsigned char amp_sensor_enabled:1; - unsigned char image_transposed:1; - unsigned char first_column_at_left_side:1; - unsigned char size_of_column2mux:5; - } __packed; - unsigned char data[1]; - }; -}; - -struct synaptics_rmi4_f55_handle { - bool amp_sensor; - unsigned char size_of_column2mux; - unsigned char *tx_assignment; - unsigned char *rx_assignment; - unsigned short query_base_addr; - unsigned short control_base_addr; - unsigned short data_base_addr; - unsigned short command_base_addr; - struct f55_query query; - struct f55_query_3 query_3; - struct f55_query_5 query_5; - struct f55_query_17 query_17; - struct f55_query_18 query_18; - struct f55_query_22 query_22; - struct f55_query_23 query_23; -}; - -show_prototype(num_of_mapped_tx) -show_prototype(num_of_mapped_rx) -show_prototype(tx_mapping) -show_prototype(rx_mapping) -show_prototype(report_size) -show_prototype(status) -store_prototype(do_preparation) -store_prototype(force_cal) -store_prototype(get_report) -store_prototype(resume_touch) -store_prototype(do_afe_calibration) -show_store_prototype(report_type) -show_store_prototype(fifoindex) -show_store_prototype(no_auto_cal) -show_store_prototype(read_report) - -static struct attribute *attrs[] = { - attrify(num_of_mapped_tx), - attrify(num_of_mapped_rx), - attrify(tx_mapping), - attrify(rx_mapping), - attrify(report_size), - attrify(status), - attrify(do_preparation), - attrify(force_cal), - attrify(get_report), - attrify(resume_touch), - attrify(do_afe_calibration), - attrify(report_type), - attrify(fifoindex), - attrify(no_auto_cal), - attrify(read_report), - NULL, -}; - -static struct attribute_group attr_group = { - .attrs = attrs, -}; - -static ssize_t test_sysfs_data_read(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static struct bin_attribute test_report_data = { - .attr = { - .name = "report_data", - .mode = S_IRUGO, - }, - .size = 0, - .read = test_sysfs_data_read, -}; - -static struct synaptics_rmi4_f54_handle *f54; -static struct synaptics_rmi4_f55_handle *f55; - -DECLARE_COMPLETION(test_remove_complete); - -static bool test_report_type_valid(enum f54_report_types report_type) -{ - switch (report_type) { - case F54_8BIT_IMAGE: - case F54_16BIT_IMAGE: - case F54_RAW_16BIT_IMAGE: - case F54_HIGH_RESISTANCE: - case F54_TX_TO_TX_SHORTS: - case F54_RX_TO_RX_SHORTS_1: - case F54_TRUE_BASELINE: - case F54_FULL_RAW_CAP_MIN_MAX: - case F54_RX_OPENS_1: - case F54_TX_OPENS: - case F54_TX_TO_GND_SHORTS: - case F54_RX_TO_RX_SHORTS_2: - case F54_RX_OPENS_2: - case F54_FULL_RAW_CAP: - case F54_FULL_RAW_CAP_NO_RX_COUPLING: - case F54_SENSOR_SPEED: - case F54_ADC_RANGE: - case F54_TRX_OPENS: - case F54_TRX_TO_GND_SHORTS: - case F54_TRX_SHORTS: - case F54_ABS_RAW_CAP: - case F54_ABS_DELTA_CAP: - case F54_ABS_HYBRID_DELTA_CAP: - case F54_ABS_HYBRID_RAW_CAP: - case F54_AMP_FULL_RAW_CAP: - case F54_AMP_RAW_ADC: - return true; - break; - default: - f54->report_type = INVALID_REPORT_TYPE; - f54->report_size = 0; - return false; - } -} - -static void test_set_report_size(void) -{ - int retval; - unsigned char tx = f54->tx_assigned; - unsigned char rx = f54->rx_assigned; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - switch (f54->report_type) { - case F54_8BIT_IMAGE: - f54->report_size = tx * rx; - break; - case F54_16BIT_IMAGE: - case F54_RAW_16BIT_IMAGE: - case F54_TRUE_BASELINE: - case F54_FULL_RAW_CAP: - case F54_FULL_RAW_CAP_NO_RX_COUPLING: - case F54_SENSOR_SPEED: - case F54_AMP_FULL_RAW_CAP: - case F54_AMP_RAW_ADC: - f54->report_size = 2 * tx * rx; - break; - case F54_HIGH_RESISTANCE: - f54->report_size = HIGH_RESISTANCE_DATA_SIZE; - break; - case F54_TX_TO_TX_SHORTS: - case F54_TX_OPENS: - case F54_TX_TO_GND_SHORTS: - f54->report_size = (tx + 7) / 8; - break; - case F54_RX_TO_RX_SHORTS_1: - case F54_RX_OPENS_1: - if (rx < tx) - f54->report_size = 2 * rx * rx; - else - f54->report_size = 2 * tx * rx; - break; - case F54_FULL_RAW_CAP_MIN_MAX: - f54->report_size = FULL_RAW_CAP_MIN_MAX_DATA_SIZE; - break; - case F54_RX_TO_RX_SHORTS_2: - case F54_RX_OPENS_2: - if (rx <= tx) - f54->report_size = 0; - else - f54->report_size = 2 * rx * (rx - tx); - break; - case F54_ADC_RANGE: - if (f54->query.has_signal_clarity) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->control.reg_41->address, - f54->control.reg_41->data, - sizeof(f54->control.reg_41->data)); - if (retval < 0) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Failed to read control reg_41\n", - __func__); - f54->report_size = 0; - break; - } - if (!f54->control.reg_41->no_signal_clarity) { - if (tx % 4) - tx += 4 - (tx % 4); - } - } - f54->report_size = 2 * tx * rx; - break; - case F54_TRX_OPENS: - case F54_TRX_TO_GND_SHORTS: - case F54_TRX_SHORTS: - f54->report_size = TRX_OPEN_SHORT_DATA_SIZE; - break; - case F54_ABS_RAW_CAP: - case F54_ABS_DELTA_CAP: - case F54_ABS_HYBRID_DELTA_CAP: - case F54_ABS_HYBRID_RAW_CAP: - f54->report_size = 4 * (tx + rx); - break; - default: - f54->report_size = 0; - } - - return; -} - -static int test_set_interrupt(bool set) -{ - int retval; - unsigned char ii; - unsigned char zero = 0x00; - unsigned char *intr_mask; - unsigned short f01_ctrl_reg; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - intr_mask = rmi4_data->intr_mask; - f01_ctrl_reg = rmi4_data->f01_ctrl_base_addr + 1 + f54->intr_reg_num; - - if (!set) { - retval = synaptics_rmi4_reg_write(rmi4_data, - f01_ctrl_reg, - &zero, - sizeof(zero)); - if (retval < 0) - return retval; - } - - for (ii = 0; ii < rmi4_data->num_of_intr_regs; ii++) { - if (intr_mask[ii] != 0x00) { - f01_ctrl_reg = rmi4_data->f01_ctrl_base_addr + 1 + ii; - if (set) { - retval = synaptics_rmi4_reg_write(rmi4_data, - f01_ctrl_reg, - &zero, - sizeof(zero)); - if (retval < 0) - return retval; - } else { - retval = synaptics_rmi4_reg_write(rmi4_data, - f01_ctrl_reg, - &(intr_mask[ii]), - sizeof(intr_mask[ii])); - if (retval < 0) - return retval; - } - } - } - - f01_ctrl_reg = rmi4_data->f01_ctrl_base_addr + 1 + f54->intr_reg_num; - - if (set) { - retval = synaptics_rmi4_reg_write(rmi4_data, - f01_ctrl_reg, - &f54->intr_mask, - 1); - if (retval < 0) - return retval; - } - - return 0; -} - -static int test_wait_for_command_completion(void) -{ - int retval; - unsigned char value; - unsigned char timeout_count; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - timeout_count = 0; - do { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->command_base_addr, - &value, - sizeof(value)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read command register\n", - __func__); - return retval; - } - - if (value == 0x00) - break; - - msleep(100); - timeout_count++; - } while (timeout_count < COMMAND_TIMEOUT_100MS); - - if (timeout_count == COMMAND_TIMEOUT_100MS) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Timed out waiting for command completion\n", - __func__); - return -ETIMEDOUT; - } - - return 0; -} - -static int test_do_command(unsigned char command) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->command_base_addr, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write command\n", - __func__); - return retval; - } - - retval = test_wait_for_command_completion(); - if (retval < 0) - return retval; - - return 0; -} - -static int test_do_preparation(void) -{ - int retval; - unsigned char value; - unsigned char zero = 0x00; - unsigned char device_ctrl; - struct f54_control_86 reg_86; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - 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 no sleep\n", - __func__); - return retval; - } - - device_ctrl |= NO_SLEEP_ON; - - 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 no sleep\n", - __func__); - return retval; - } - - if ((f54->query.has_query13) && - (f54->query_13.has_ctrl86)) { - reg_86.data[0] = f54->control.reg_86->data[0]; - reg_86.dynamic_sense_display_ratio = 1; - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->control.reg_86->address, - reg_86.data, - sizeof(reg_86.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set sense display ratio\n", - __func__); - return retval; - } - } - - if (f54->skip_preparation) - return 0; - - switch (f54->report_type) { - case F54_16BIT_IMAGE: - case F54_RAW_16BIT_IMAGE: - case F54_SENSOR_SPEED: - case F54_ADC_RANGE: - case F54_ABS_RAW_CAP: - case F54_ABS_DELTA_CAP: - case F54_ABS_HYBRID_DELTA_CAP: - case F54_ABS_HYBRID_RAW_CAP: - break; - case F54_AMP_RAW_ADC: - if (f54->query_49.has_ctrl188) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->control.reg_188->address, - f54->control.reg_188->data, - sizeof(f54->control.reg_188->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set start production test\n", - __func__); - return retval; - } - f54->control.reg_188->start_production_test = 1; - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->control.reg_188->address, - f54->control.reg_188->data, - sizeof(f54->control.reg_188->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set start production test\n", - __func__); - return retval; - } - } - break; - default: - if (f54->query.touch_controller_family == 1) - disable_cbc(reg_7); - else if (f54->query.has_ctrl88) - disable_cbc(reg_88); - - if (f54->query.has_0d_acquisition_control) - disable_cbc(reg_57); - - if ((f54->query.has_query15) && - (f54->query_15.has_query25) && - (f54->query_25.has_query27) && - (f54->query_27.has_query29) && - (f54->query_29.has_query30) && - (f54->query_30.has_query32) && - (f54->query_32.has_query33) && - (f54->query_33.has_query36) && - (f54->query_36.has_query38) && - (f54->query_38.has_ctrl149)) { - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->control.reg_149->address, - &zero, - sizeof(f54->control.reg_149->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to disable global CBC\n", - __func__); - return retval; - } - } - - if (f54->query.has_signal_clarity) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->control.reg_41->address, - &value, - sizeof(f54->control.reg_41->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to disable signal clarity\n", - __func__); - return retval; - } - value |= 0x01; - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->control.reg_41->address, - &value, - sizeof(f54->control.reg_41->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to disable signal clarity\n", - __func__); - return retval; - } - } - - retval = test_do_command(COMMAND_FORCE_UPDATE); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do force update\n", - __func__); - return retval; - } - - retval = test_do_command(COMMAND_FORCE_CAL); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do force cal\n", - __func__); - return retval; - } - } - - return 0; -} - -static int test_do_afe_calibration(enum f54_afe_cal mode) -{ - int retval; - unsigned char timeout = CALIBRATION_TIMEOUT_S; - unsigned char timeout_count = 0; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->control.reg_188->address, - f54->control.reg_188->data, - sizeof(f54->control.reg_188->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to start calibration\n", - __func__); - return retval; - } - - if (mode == F54_AFE_CAL) - f54->control.reg_188->start_calibration = 1; - else if (mode == F54_AFE_IS_CAL) - f54->control.reg_188->start_is_calibration = 1; - - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->control.reg_188->address, - f54->control.reg_188->data, - sizeof(f54->control.reg_188->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to start calibration\n", - __func__); - return retval; - } - - do { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->control.reg_188->address, - f54->control.reg_188->data, - sizeof(f54->control.reg_188->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to complete calibration\n", - __func__); - return retval; - } - - if (mode == F54_AFE_CAL) { - if (!f54->control.reg_188->start_calibration) - break; - } else if (mode == F54_AFE_IS_CAL) { - if (!f54->control.reg_188->start_is_calibration) - break; - } - - if (timeout_count == timeout) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Timed out waiting for calibration completion\n", - __func__); - return -EBUSY; - } - - timeout_count++; - msleep(1000); - } while (true); - - /* check CRC */ - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->data_31.address, - f54->data_31.data, - sizeof(f54->data_31.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read calibration CRC\n", - __func__); - return retval; - } - - if (mode == F54_AFE_CAL) { - if (f54->data_31.calibration_crc == 0) - return 0; - } else if (mode == F54_AFE_IS_CAL) { - if (f54->data_31.is_calibration_crc == 0) - return 0; - } - - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read calibration CRC\n", - __func__); - - return -EINVAL; -} - -static int test_check_for_idle_status(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - switch (f54->status) { - case STATUS_IDLE: - retval = 0; - break; - case STATUS_BUSY: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Status busy\n", - __func__); - retval = -EINVAL; - break; - case STATUS_ERROR: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Status error\n", - __func__); - retval = -EINVAL; - break; - default: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid status (%d)\n", - __func__, f54->status); - retval = -EINVAL; - } - - return retval; -} - -static void test_timeout_work(struct work_struct *work) -{ - int retval; - unsigned char command; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - mutex_lock(&f54->status_mutex); - - if (f54->status == STATUS_BUSY) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->command_base_addr, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read command register\n", - __func__); - } else if (command & COMMAND_GET_REPORT) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Report type not supported by FW\n", - __func__); - } else { - queue_work(f54->test_report_workqueue, - &f54->test_report_work); - goto exit; - } - f54->status = STATUS_ERROR; - f54->report_size = 0; - } - -exit: - mutex_unlock(&f54->status_mutex); - - return; -} - -static enum hrtimer_restart test_get_report_timeout(struct hrtimer *timer) -{ - schedule_work(&(f54->timeout_work)); - - return HRTIMER_NORESTART; -} - -static ssize_t test_sysfs_num_of_mapped_tx_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", f54->tx_assigned); -} - -static ssize_t test_sysfs_num_of_mapped_rx_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", f54->rx_assigned); -} - -static ssize_t test_sysfs_tx_mapping_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int cnt; - int count = 0; - unsigned char ii; - unsigned char tx_num; - unsigned char tx_electrodes = f54->query.num_of_tx_electrodes; - - if (!f55) - return -EINVAL; - - for (ii = 0; ii < tx_electrodes; ii++) { - tx_num = f55->tx_assignment[ii]; - if (tx_num == 0xff) - cnt = snprintf(buf, PAGE_SIZE - count, "xx "); - else - cnt = snprintf(buf, PAGE_SIZE - count, "%02u ", tx_num); - buf += cnt; - count += cnt; - } - - snprintf(buf, PAGE_SIZE - count, "\n"); - count++; - - return count; -} - -static ssize_t test_sysfs_rx_mapping_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int cnt; - int count = 0; - unsigned char ii; - unsigned char rx_num; - unsigned char rx_electrodes = f54->query.num_of_rx_electrodes; - - if (!f55) - return -EINVAL; - - for (ii = 0; ii < rx_electrodes; ii++) { - rx_num = f55->rx_assignment[ii]; - if (rx_num == 0xff) - cnt = snprintf(buf, PAGE_SIZE - count, "xx "); - else - cnt = snprintf(buf, PAGE_SIZE - count, "%02u ", rx_num); - buf += cnt; - count += cnt; - } - - snprintf(buf, PAGE_SIZE - count, "\n"); - count++; - - return count; -} - -static ssize_t test_sysfs_report_size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", f54->report_size); -} - -static ssize_t test_sysfs_status_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - - mutex_lock(&f54->status_mutex); - - retval = snprintf(buf, PAGE_SIZE, "%u\n", f54->status); - - mutex_unlock(&f54->status_mutex); - - return retval; -} - -static ssize_t test_sysfs_do_preparation_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long setting; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = sstrtoul(buf, 10, &setting); - if (retval) - return retval; - - if (setting != 1) - return -EINVAL; - - mutex_lock(&f54->status_mutex); - - retval = test_check_for_idle_status(); - if (retval < 0) - goto exit; - - retval = test_do_preparation(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do preparation\n", - __func__); - goto exit; - } - - retval = count; - -exit: - mutex_unlock(&f54->status_mutex); - - return retval; -} - -static ssize_t test_sysfs_force_cal_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long setting; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = sstrtoul(buf, 10, &setting); - if (retval) - return retval; - - if (setting != 1) - return -EINVAL; - - mutex_lock(&f54->status_mutex); - - retval = test_check_for_idle_status(); - if (retval < 0) - goto exit; - - retval = test_do_command(COMMAND_FORCE_CAL); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to do force cal\n", - __func__); - goto exit; - } - - retval = count; - -exit: - mutex_unlock(&f54->status_mutex); - - return retval; -} - -static ssize_t test_sysfs_get_report_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned char command; - unsigned long setting; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = sstrtoul(buf, 10, &setting); - if (retval) - return retval; - - if (setting != 1) - return -EINVAL; - - mutex_lock(&f54->status_mutex); - - retval = test_check_for_idle_status(); - if (retval < 0) - goto exit; - - if (!test_report_type_valid(f54->report_type)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Invalid report type\n", - __func__); - retval = -EINVAL; - goto exit; - } - - test_set_interrupt(true); - - command = (unsigned char)COMMAND_GET_REPORT; - - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->command_base_addr, - &command, - sizeof(command)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write get report command\n", - __func__); - goto exit; - } - - f54->status = STATUS_BUSY; - f54->report_size = 0; - f54->data_pos = 0; - - hrtimer_start(&f54->watchdog, - ktime_set(GET_REPORT_TIMEOUT_S, 0), - HRTIMER_MODE_REL); - - retval = count; - -exit: - mutex_unlock(&f54->status_mutex); - - return retval; -} - -static ssize_t test_sysfs_resume_touch_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned char device_ctrl; - unsigned long setting; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = sstrtoul(buf, 10, &setting); - if (retval) - return retval; - - if (setting != 1) - return -EINVAL; - - 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 restore no sleep setting\n", - __func__); - return retval; - } - - device_ctrl = device_ctrl & ~NO_SLEEP_ON; - device_ctrl |= rmi4_data->no_sleep_setting; - - 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 restore no sleep setting\n", - __func__); - return retval; - } - - if ((f54->query.has_query13) && - (f54->query_13.has_ctrl86)) { - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->control.reg_86->address, - f54->control.reg_86->data, - sizeof(f54->control.reg_86->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to restore sense display ratio\n", - __func__); - return retval; - } - } - - test_set_interrupt(false); - - if (f54->skip_preparation) - return count; - - switch (f54->report_type) { - case F54_16BIT_IMAGE: - case F54_RAW_16BIT_IMAGE: - case F54_SENSOR_SPEED: - case F54_ADC_RANGE: - case F54_ABS_RAW_CAP: - case F54_ABS_DELTA_CAP: - case F54_ABS_HYBRID_DELTA_CAP: - case F54_ABS_HYBRID_RAW_CAP: - break; - case F54_AMP_RAW_ADC: - if (f54->query_49.has_ctrl188) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->control.reg_188->address, - f54->control.reg_188->data, - sizeof(f54->control.reg_188->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set start production test\n", - __func__); - return retval; - } - f54->control.reg_188->start_production_test = 0; - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->control.reg_188->address, - f54->control.reg_188->data, - sizeof(f54->control.reg_188->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set start production test\n", - __func__); - return retval; - } - } - break; - default: - rmi4_data->reset_device(rmi4_data, false); - } - - return count; -} - -static ssize_t test_sysfs_do_afe_calibration_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned long setting; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = sstrtoul(buf, 10, &setting); - if (retval) - return retval; - - if (!f54->query_49.has_ctrl188) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: F54_ANALOG_Ctrl188 not found\n", - __func__); - return -EINVAL; - } - - if (setting == 0 || setting == 1) - retval = test_do_afe_calibration((enum f54_afe_cal)setting); - else - return -EINVAL; - - if (retval) - return retval; - else - return count; -} - -static ssize_t test_sysfs_report_type_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", f54->report_type); -} - -static ssize_t test_sysfs_report_type_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned char data; - unsigned long setting; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = sstrtoul(buf, 10, &setting); - if (retval) - return retval; - - mutex_lock(&f54->status_mutex); - - retval = test_check_for_idle_status(); - if (retval < 0) - goto exit; - - if (!test_report_type_valid((enum f54_report_types)setting)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Report type not supported by driver\n", - __func__); - retval = -EINVAL; - goto exit; - } - - f54->report_type = (enum f54_report_types)setting; - data = (unsigned char)setting; - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->data_base_addr, - &data, - sizeof(data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write report type\n", - __func__); - goto exit; - } - - retval = count; - -exit: - mutex_unlock(&f54->status_mutex); - - return retval; -} - -static ssize_t test_sysfs_fifoindex_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int retval; - unsigned char data[2]; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->data_base_addr + REPORT_INDEX_OFFSET, - data, - sizeof(data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read report index\n", - __func__); - return retval; - } - - batohs(&f54->fifoindex, data); - - return snprintf(buf, PAGE_SIZE, "%u\n", f54->fifoindex); -} - -static ssize_t test_sysfs_fifoindex_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned char data[2]; - unsigned long setting; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = sstrtoul(buf, 10, &setting); - if (retval) - return retval; - - f54->fifoindex = setting; - - hstoba(data, (unsigned short)setting); - - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->data_base_addr + REPORT_INDEX_OFFSET, - data, - sizeof(data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write report index\n", - __func__); - return retval; - } - - return count; -} - -static ssize_t test_sysfs_no_auto_cal_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", f54->no_auto_cal); -} - -static ssize_t test_sysfs_no_auto_cal_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned char data; - unsigned long setting; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = sstrtoul(buf, 10, &setting); - if (retval) - return retval; - - if (setting > 1) - return -EINVAL; - - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->control_base_addr, - &data, - sizeof(data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read no auto cal setting\n", - __func__); - return retval; - } - - if (setting) - data |= CONTROL_NO_AUTO_CAL; - else - data &= ~CONTROL_NO_AUTO_CAL; - - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->control_base_addr, - &data, - sizeof(data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write no auto cal setting\n", - __func__); - return retval; - } - - f54->no_auto_cal = (setting == 1); - - return count; -} - -static ssize_t test_sysfs_read_report_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned int ii; - unsigned int jj; - int cnt; - int count = 0; - int tx_num = f54->tx_assigned; - int rx_num = f54->rx_assigned; - char *report_data_8; - short *report_data_16; - int *report_data_32; - unsigned short *report_data_u16; - unsigned int *report_data_u32; - - switch (f54->report_type) { - case F54_8BIT_IMAGE: - report_data_8 = (char *)f54->report_data; - for (ii = 0; ii < f54->report_size; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, "%03d: %d\n", - ii, *report_data_8); - report_data_8++; - buf += cnt; - count += cnt; - } - break; - case F54_AMP_RAW_ADC: - report_data_u16 = (unsigned short *)f54->report_data; - cnt = snprintf(buf, PAGE_SIZE - count, "tx = %d\nrx = %d\n", - tx_num, rx_num); - buf += cnt; - count += cnt; - - for (ii = 0; ii < tx_num; ii++) { - for (jj = 0; jj < (rx_num - 1); jj++) { - cnt = snprintf(buf, PAGE_SIZE - count, "%-4d ", - *report_data_u16); - report_data_u16++; - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "%-4d\n", - *report_data_u16); - report_data_u16++; - buf += cnt; - count += cnt; - } - break; - case F54_16BIT_IMAGE: - case F54_RAW_16BIT_IMAGE: - case F54_TRUE_BASELINE: - case F54_FULL_RAW_CAP: - case F54_FULL_RAW_CAP_NO_RX_COUPLING: - case F54_SENSOR_SPEED: - case F54_AMP_FULL_RAW_CAP: - report_data_16 = (short *)f54->report_data; - cnt = snprintf(buf, PAGE_SIZE - count, "tx = %d\nrx = %d\n", - tx_num, rx_num); - buf += cnt; - count += cnt; - - for (ii = 0; ii < tx_num; ii++) { - for (jj = 0; jj < (rx_num - 1); jj++) { - cnt = snprintf(buf, PAGE_SIZE - count, "%-4d ", - *report_data_16); - report_data_16++; - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "%-4d\n", - *report_data_16); - report_data_16++; - buf += cnt; - count += cnt; - } - break; - case F54_HIGH_RESISTANCE: - case F54_FULL_RAW_CAP_MIN_MAX: - report_data_16 = (short *)f54->report_data; - for (ii = 0; ii < f54->report_size; ii += 2) { - cnt = snprintf(buf, PAGE_SIZE - count, "%03d: %d\n", - ii / 2, *report_data_16); - report_data_16++; - buf += cnt; - count += cnt; - } - break; - case F54_ABS_RAW_CAP: - report_data_u32 = (unsigned int *)f54->report_data; - cnt = snprintf(buf, PAGE_SIZE - count, "rx "); - buf += cnt; - count += cnt; - for (ii = 0; ii < rx_num; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, " %2d", ii); - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "\n"); - buf += cnt; - count += cnt; - - cnt = snprintf(buf, PAGE_SIZE - count, " "); - buf += cnt; - count += cnt; - for (ii = 0; ii < rx_num; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, " %5u", - *report_data_u32); - report_data_u32++; - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "\n"); - buf += cnt; - count += cnt; - - cnt = snprintf(buf, PAGE_SIZE - count, "tx "); - buf += cnt; - count += cnt; - for (ii = 0; ii < tx_num; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, " %2d", ii); - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "\n"); - buf += cnt; - count += cnt; - - cnt = snprintf(buf, PAGE_SIZE - count, " "); - buf += cnt; - count += cnt; - for (ii = 0; ii < tx_num; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, " %5u", - *report_data_u32); - report_data_u32++; - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "\n"); - buf += cnt; - count += cnt; - break; - case F54_ABS_DELTA_CAP: - case F54_ABS_HYBRID_DELTA_CAP: - case F54_ABS_HYBRID_RAW_CAP: - report_data_32 = (int *)f54->report_data; - cnt = snprintf(buf, PAGE_SIZE - count, "rx "); - buf += cnt; - count += cnt; - for (ii = 0; ii < rx_num; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, " %2d", ii); - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "\n"); - buf += cnt; - count += cnt; - - cnt = snprintf(buf, PAGE_SIZE - count, " "); - buf += cnt; - count += cnt; - for (ii = 0; ii < rx_num; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, " %5d", - *report_data_32); - report_data_32++; - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "\n"); - buf += cnt; - count += cnt; - - cnt = snprintf(buf, PAGE_SIZE - count, "tx "); - buf += cnt; - count += cnt; - for (ii = 0; ii < tx_num; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, " %2d", ii); - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "\n"); - buf += cnt; - count += cnt; - - cnt = snprintf(buf, PAGE_SIZE - count, " "); - buf += cnt; - count += cnt; - for (ii = 0; ii < tx_num; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, " %5d", - *report_data_32); - report_data_32++; - buf += cnt; - count += cnt; - } - cnt = snprintf(buf, PAGE_SIZE - count, "\n"); - buf += cnt; - count += cnt; - break; - default: - for (ii = 0; ii < f54->report_size; ii++) { - cnt = snprintf(buf, PAGE_SIZE - count, "%03d: 0x%02x\n", - ii, f54->report_data[ii]); - buf += cnt; - count += cnt; - } - } - - snprintf(buf, PAGE_SIZE - count, "\n"); - count++; - - return count; -} - -static ssize_t test_sysfs_read_report_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned char timeout = GET_REPORT_TIMEOUT_S * 10; - unsigned char timeout_count; - const char cmd[] = {'1', 0}; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = test_sysfs_report_type_store(dev, attr, buf, count); - if (retval < 0) - goto exit; - - retval = test_sysfs_do_preparation_store(dev, attr, cmd, 1); - if (retval < 0) - goto exit; - - retval = test_sysfs_get_report_store(dev, attr, cmd, 1); - if (retval < 0) - goto exit; - - timeout_count = 0; - do { - if (f54->status != STATUS_BUSY) - break; - msleep(100); - timeout_count++; - } while (timeout_count < timeout); - - if ((f54->status != STATUS_IDLE) || (f54->report_size == 0)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read report\n", - __func__); - retval = -EINVAL; - goto exit; - } - - retval = test_sysfs_resume_touch_store(dev, attr, cmd, 1); - if (retval < 0) - goto exit; - - return count; - -exit: - rmi4_data->reset_device(rmi4_data, false); - - return retval; -} - -static ssize_t test_sysfs_data_read(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - int retval; - unsigned int read_size; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - mutex_lock(&f54->status_mutex); - - retval = test_check_for_idle_status(); - if (retval < 0) - goto exit; - - if (!f54->report_data) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Report type %d data not available\n", - __func__, f54->report_type); - retval = -EINVAL; - goto exit; - } - - if ((f54->data_pos + count) > f54->report_size) - read_size = f54->report_size - f54->data_pos; - else - read_size = min_t(unsigned int, count, f54->report_size); - - retval = secure_memcpy(buf, count, f54->report_data + f54->data_pos, - f54->data_buffer_size - f54->data_pos, read_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to copy report data\n", - __func__); - goto exit; - } - f54->data_pos += read_size; - retval = read_size; - -exit: - mutex_unlock(&f54->status_mutex); - - return retval; -} - -static void test_report_work(struct work_struct *work) -{ - int retval; - unsigned char report_index[2]; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - mutex_lock(&f54->status_mutex); - - if (f54->status != STATUS_BUSY) { - retval = STATUS_ERROR; - goto exit; - } - - retval = test_wait_for_command_completion(); - if (retval < 0) { - retval = STATUS_ERROR; - goto exit; - } - - test_set_report_size(); - if (f54->report_size == 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Report data size = 0\n", - __func__); - retval = STATUS_ERROR; - goto exit; - } - - if (f54->data_buffer_size < f54->report_size) { - if (f54->data_buffer_size) - kfree(f54->report_data); - f54->report_data = kzalloc(f54->report_size, GFP_KERNEL); - if (!f54->report_data) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for data buffer\n", - __func__); - f54->data_buffer_size = 0; - retval = STATUS_ERROR; - goto exit; - } - f54->data_buffer_size = f54->report_size; - } - - report_index[0] = 0; - report_index[1] = 0; - - retval = synaptics_rmi4_reg_write(rmi4_data, - f54->data_base_addr + REPORT_INDEX_OFFSET, - report_index, - sizeof(report_index)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write report data index\n", - __func__); - retval = STATUS_ERROR; - goto exit; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->data_base_addr + REPORT_DATA_OFFSET, - f54->report_data, - f54->report_size); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read report data\n", - __func__); - retval = STATUS_ERROR; - goto exit; - } - - retval = STATUS_IDLE; - -exit: - mutex_unlock(&f54->status_mutex); - - if (retval == STATUS_ERROR) - f54->report_size = 0; - - f54->status = retval; - - return; -} - -static void test_remove_sysfs(void) -{ - sysfs_remove_group(f54->sysfs_dir, &attr_group); - sysfs_remove_bin_file(f54->sysfs_dir, &test_report_data); - kobject_put(f54->sysfs_dir); - - return; -} - -static int test_set_sysfs(void) -{ - int retval; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - f54->sysfs_dir = kobject_create_and_add(SYSFS_FOLDER_NAME, - &rmi4_data->input_dev->dev.kobj); - if (!f54->sysfs_dir) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs directory\n", - __func__); - goto exit_directory; - } - - retval = sysfs_create_bin_file(f54->sysfs_dir, &test_report_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs bin file\n", - __func__); - goto exit_bin_file; - } - - retval = sysfs_create_group(f54->sysfs_dir, &attr_group); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs attributes\n", - __func__); - goto exit_attributes; - } - - return 0; - -exit_attributes: - sysfs_remove_group(f54->sysfs_dir, &attr_group); - sysfs_remove_bin_file(f54->sysfs_dir, &test_report_data); - -exit_bin_file: - kobject_put(f54->sysfs_dir); - -exit_directory: - return -ENODEV; -} - -static void test_free_control_mem(void) -{ - struct f54_control control = f54->control; - - kfree(control.reg_7); - kfree(control.reg_41); - kfree(control.reg_57); - kfree(control.reg_86); - kfree(control.reg_88); - kfree(control.reg_110); - kfree(control.reg_149); - kfree(control.reg_188); - - return; -} - -static void test_set_data(void) -{ - unsigned short reg_addr; - - reg_addr = f54->data_base_addr + REPORT_DATA_OFFSET + 1; - - /* data 4 */ - if (f54->query.has_sense_frequency_control) - reg_addr++; - - /* data 5 reserved */ - - /* data 6 */ - if (f54->query.has_interference_metric) - reg_addr += 2; - - /* data 7 */ - if (f54->query.has_one_byte_report_rate | - f54->query.has_two_byte_report_rate) - reg_addr++; - if (f54->query.has_two_byte_report_rate) - reg_addr++; - - /* data 8 */ - if (f54->query.has_variance_metric) - reg_addr += 2; - - /* data 9 */ - if (f54->query.has_multi_metric_state_machine) - reg_addr += 2; - - /* data 10 */ - if (f54->query.has_multi_metric_state_machine | - f54->query.has_noise_state) - reg_addr++; - - /* data 11 */ - if (f54->query.has_status) - reg_addr++; - - /* data 12 */ - if (f54->query.has_slew_metric) - reg_addr += 2; - - /* data 13 */ - if (f54->query.has_multi_metric_state_machine) - reg_addr += 2; - - /* data 14 */ - if (f54->query_13.has_cidim) - reg_addr++; - - /* data 15 */ - if (f54->query_13.has_rail_im) - reg_addr++; - - /* data 16 */ - if (f54->query_13.has_noise_mitigation_enhancement) - reg_addr++; - - /* data 17 */ - if (f54->query_16.has_data17) - reg_addr++; - - /* data 18 */ - if (f54->query_21.has_query24_data18) - reg_addr++; - - /* data 19 */ - if (f54->query_21.has_data19) - reg_addr++; - - /* data_20 */ - if (f54->query_25.has_ctrl109) - reg_addr++; - - /* data 21 */ - if (f54->query_27.has_data21) - reg_addr++; - - /* data 22 */ - if (f54->query_27.has_data22) - reg_addr++; - - /* data 23 */ - if (f54->query_29.has_data23) - reg_addr++; - - /* data 24 */ - if (f54->query_32.has_data24) - reg_addr++; - - /* data 25 */ - if (f54->query_35.has_data25) - reg_addr++; - - /* data 26 */ - if (f54->query_35.has_data26) - reg_addr++; - - /* data 27 */ - if (f54->query_46.has_data27) - reg_addr++; - - /* data 28 */ - if (f54->query_46.has_data28) - reg_addr++; - - /* data 29 30 reserved */ - - /* data 31 */ - if (f54->query_49.has_data31) { - f54->data_31.address = reg_addr; - reg_addr++; - } - - return; -} - -static int test_set_controls(void) -{ - int retval; - unsigned char length; - unsigned char num_of_sensing_freqs; - unsigned short reg_addr = f54->control_base_addr; - struct f54_control *control = &f54->control; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - num_of_sensing_freqs = f54->query.number_of_sensing_frequencies; - - /* control 0 */ - reg_addr += CONTROL_0_SIZE; - - /* control 1 */ - if ((f54->query.touch_controller_family == 0) || - (f54->query.touch_controller_family == 1)) - reg_addr += CONTROL_1_SIZE; - - /* control 2 */ - reg_addr += CONTROL_2_SIZE; - - /* control 3 */ - if (f54->query.has_pixel_touch_threshold_adjustment) - reg_addr += CONTROL_3_SIZE; - - /* controls 4 5 6 */ - if ((f54->query.touch_controller_family == 0) || - (f54->query.touch_controller_family == 1)) - reg_addr += CONTROL_4_6_SIZE; - - /* control 7 */ - if (f54->query.touch_controller_family == 1) { - control->reg_7 = kzalloc(sizeof(*(control->reg_7)), - GFP_KERNEL); - if (!control->reg_7) - goto exit_no_mem; - control->reg_7->address = reg_addr; - reg_addr += CONTROL_7_SIZE; - } - - /* controls 8 9 */ - if ((f54->query.touch_controller_family == 0) || - (f54->query.touch_controller_family == 1)) - reg_addr += CONTROL_8_9_SIZE; - - /* control 10 */ - if (f54->query.has_interference_metric) - reg_addr += CONTROL_10_SIZE; - - /* control 11 */ - if (f54->query.has_ctrl11) - reg_addr += CONTROL_11_SIZE; - - /* controls 12 13 */ - if (f54->query.has_relaxation_control) - reg_addr += CONTROL_12_13_SIZE; - - /* controls 14 15 16 */ - if (f54->query.has_sensor_assignment) { - reg_addr += CONTROL_14_SIZE; - reg_addr += CONTROL_15_SIZE * f54->query.num_of_rx_electrodes; - reg_addr += CONTROL_16_SIZE * f54->query.num_of_tx_electrodes; - } - - /* controls 17 18 19 */ - if (f54->query.has_sense_frequency_control) { - reg_addr += CONTROL_17_SIZE * num_of_sensing_freqs; - reg_addr += CONTROL_18_SIZE * num_of_sensing_freqs; - reg_addr += CONTROL_19_SIZE * num_of_sensing_freqs; - } - - /* control 20 */ - reg_addr += CONTROL_20_SIZE; - - /* control 21 */ - if (f54->query.has_sense_frequency_control) - reg_addr += CONTROL_21_SIZE; - - /* controls 22 23 24 25 26 */ - if (f54->query.has_firmware_noise_mitigation) - reg_addr += CONTROL_22_26_SIZE; - - /* control 27 */ - if (f54->query.has_iir_filter) - reg_addr += CONTROL_27_SIZE; - - /* control 28 */ - if (f54->query.has_firmware_noise_mitigation) - reg_addr += CONTROL_28_SIZE; - - /* control 29 */ - if (f54->query.has_cmn_removal) - reg_addr += CONTROL_29_SIZE; - - /* control 30 */ - if (f54->query.has_cmn_maximum) - reg_addr += CONTROL_30_SIZE; - - /* control 31 */ - if (f54->query.has_touch_hysteresis) - reg_addr += CONTROL_31_SIZE; - - /* controls 32 33 34 35 */ - if (f54->query.has_edge_compensation) - reg_addr += CONTROL_32_35_SIZE; - - /* control 36 */ - if ((f54->query.curve_compensation_mode == 1) || - (f54->query.curve_compensation_mode == 2)) { - if (f54->query.curve_compensation_mode == 1) { - length = max(f54->query.num_of_rx_electrodes, - f54->query.num_of_tx_electrodes); - } else if (f54->query.curve_compensation_mode == 2) { - length = f54->query.num_of_rx_electrodes; - } - reg_addr += CONTROL_36_SIZE * length; - } - - /* control 37 */ - if (f54->query.curve_compensation_mode == 2) - reg_addr += CONTROL_37_SIZE * f54->query.num_of_tx_electrodes; - - /* controls 38 39 40 */ - if (f54->query.has_per_frequency_noise_control) { - reg_addr += CONTROL_38_SIZE * num_of_sensing_freqs; - reg_addr += CONTROL_39_SIZE * num_of_sensing_freqs; - reg_addr += CONTROL_40_SIZE * num_of_sensing_freqs; - } - - /* control 41 */ - if (f54->query.has_signal_clarity) { - control->reg_41 = kzalloc(sizeof(*(control->reg_41)), - GFP_KERNEL); - if (!control->reg_41) - goto exit_no_mem; - control->reg_41->address = reg_addr; - reg_addr += CONTROL_41_SIZE; - } - - /* control 42 */ - if (f54->query.has_variance_metric) - reg_addr += CONTROL_42_SIZE; - - /* controls 43 44 45 46 47 48 49 50 51 52 53 54 */ - if (f54->query.has_multi_metric_state_machine) - reg_addr += CONTROL_43_54_SIZE; - - /* controls 55 56 */ - if (f54->query.has_0d_relaxation_control) - reg_addr += CONTROL_55_56_SIZE; - - /* control 57 */ - if (f54->query.has_0d_acquisition_control) { - control->reg_57 = kzalloc(sizeof(*(control->reg_57)), - GFP_KERNEL); - if (!control->reg_57) - goto exit_no_mem; - control->reg_57->address = reg_addr; - reg_addr += CONTROL_57_SIZE; - } - - /* control 58 */ - if (f54->query.has_0d_acquisition_control) - reg_addr += CONTROL_58_SIZE; - - /* control 59 */ - if (f54->query.has_h_blank) - reg_addr += CONTROL_59_SIZE; - - /* controls 60 61 62 */ - if ((f54->query.has_h_blank) || - (f54->query.has_v_blank) || - (f54->query.has_long_h_blank)) - reg_addr += CONTROL_60_62_SIZE; - - /* control 63 */ - if ((f54->query.has_h_blank) || - (f54->query.has_v_blank) || - (f54->query.has_long_h_blank) || - (f54->query.has_slew_metric) || - (f54->query.has_slew_option) || - (f54->query.has_noise_mitigation2)) - reg_addr += CONTROL_63_SIZE; - - /* controls 64 65 66 67 */ - if (f54->query.has_h_blank) - reg_addr += CONTROL_64_67_SIZE * 7; - else if ((f54->query.has_v_blank) || - (f54->query.has_long_h_blank)) - reg_addr += CONTROL_64_67_SIZE; - - /* controls 68 69 70 71 72 73 */ - if ((f54->query.has_h_blank) || - (f54->query.has_v_blank) || - (f54->query.has_long_h_blank)) - reg_addr += CONTROL_68_73_SIZE; - - /* control 74 */ - if (f54->query.has_slew_metric) - reg_addr += CONTROL_74_SIZE; - - /* control 75 */ - if (f54->query.has_enhanced_stretch) - reg_addr += CONTROL_75_SIZE * num_of_sensing_freqs; - - /* control 76 */ - if (f54->query.has_startup_fast_relaxation) - reg_addr += CONTROL_76_SIZE; - - /* controls 77 78 */ - if (f54->query.has_esd_control) - reg_addr += CONTROL_77_78_SIZE; - - /* controls 79 80 81 82 83 */ - if (f54->query.has_noise_mitigation2) - reg_addr += CONTROL_79_83_SIZE; - - /* controls 84 85 */ - if (f54->query.has_energy_ratio_relaxation) - reg_addr += CONTROL_84_85_SIZE; - - /* control 86 */ - if (f54->query_13.has_ctrl86) { - control->reg_86 = kzalloc(sizeof(*(control->reg_86)), - GFP_KERNEL); - if (!control->reg_86) - goto exit_no_mem; - control->reg_86->address = reg_addr; - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->control.reg_86->address, - f54->control.reg_86->data, - sizeof(f54->control.reg_86->data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read sense display ratio\n", - __func__); - return retval; - } - reg_addr += CONTROL_86_SIZE; - } - - /* control 87 */ - if (f54->query_13.has_ctrl87) - reg_addr += CONTROL_87_SIZE; - - /* control 88 */ - if (f54->query.has_ctrl88) { - control->reg_88 = kzalloc(sizeof(*(control->reg_88)), - GFP_KERNEL); - if (!control->reg_88) - goto exit_no_mem; - control->reg_88->address = reg_addr; - reg_addr += CONTROL_88_SIZE; - } - - /* control 89 */ - if (f54->query_13.has_cidim || - f54->query_13.has_noise_mitigation_enhancement || - f54->query_13.has_rail_im) - reg_addr += CONTROL_89_SIZE; - - /* control 90 */ - if (f54->query_15.has_ctrl90) - reg_addr += CONTROL_90_SIZE; - - /* control 91 */ - if (f54->query_21.has_ctrl91) - reg_addr += CONTROL_91_SIZE; - - /* control 92 */ - if (f54->query_16.has_ctrl92) - reg_addr += CONTROL_92_SIZE; - - /* control 93 */ - if (f54->query_16.has_ctrl93) - reg_addr += CONTROL_93_SIZE; - - /* control 94 */ - if (f54->query_16.has_ctrl94_query18) - reg_addr += CONTROL_94_SIZE; - - /* control 95 */ - if (f54->query_16.has_ctrl95_query19) - reg_addr += CONTROL_95_SIZE; - - /* control 96 */ - if (f54->query_21.has_ctrl96) - reg_addr += CONTROL_96_SIZE; - - /* control 97 */ - if (f54->query_21.has_ctrl97) - reg_addr += CONTROL_97_SIZE; - - /* control 98 */ - if (f54->query_21.has_ctrl98) - reg_addr += CONTROL_98_SIZE; - - /* control 99 */ - if (f54->query.touch_controller_family == 2) - reg_addr += CONTROL_99_SIZE; - - /* control 100 */ - if (f54->query_16.has_ctrl100) - reg_addr += CONTROL_100_SIZE; - - /* control 101 */ - if (f54->query_22.has_ctrl101) - reg_addr += CONTROL_101_SIZE; - - - /* control 102 */ - if (f54->query_23.has_ctrl102) - reg_addr += CONTROL_102_SIZE; - - /* control 103 */ - if (f54->query_22.has_ctrl103_query26) { - f54->skip_preparation = true; - reg_addr += CONTROL_103_SIZE; - } - - /* control 104 */ - if (f54->query_22.has_ctrl104) - reg_addr += CONTROL_104_SIZE; - - /* control 105 */ - if (f54->query_22.has_ctrl105) - reg_addr += CONTROL_105_SIZE; - - /* control 106 */ - if (f54->query_25.has_ctrl106) - reg_addr += CONTROL_106_SIZE; - - /* control 107 */ - if (f54->query_25.has_ctrl107) - reg_addr += CONTROL_107_SIZE; - - /* control 108 */ - if (f54->query_25.has_ctrl108) - reg_addr += CONTROL_108_SIZE; - - /* control 109 */ - if (f54->query_25.has_ctrl109) - reg_addr += CONTROL_109_SIZE; - - /* control 110 */ - if (f54->query_27.has_ctrl110) { - control->reg_110 = kzalloc(sizeof(*(control->reg_110)), - GFP_KERNEL); - if (!control->reg_110) - goto exit_no_mem; - control->reg_110->address = reg_addr; - reg_addr += CONTROL_110_SIZE; - } - - /* control 111 */ - if (f54->query_27.has_ctrl111) - reg_addr += CONTROL_111_SIZE; - - /* control 112 */ - if (f54->query_27.has_ctrl112) - reg_addr += CONTROL_112_SIZE; - - /* control 113 */ - if (f54->query_27.has_ctrl113) - reg_addr += CONTROL_113_SIZE; - - /* control 114 */ - if (f54->query_27.has_ctrl114) - reg_addr += CONTROL_114_SIZE; - - /* control 115 */ - if (f54->query_29.has_ctrl115) - reg_addr += CONTROL_115_SIZE; - - /* control 116 */ - if (f54->query_29.has_ctrl116) - reg_addr += CONTROL_116_SIZE; - - /* control 117 */ - if (f54->query_29.has_ctrl117) - reg_addr += CONTROL_117_SIZE; - - /* control 118 */ - if (f54->query_30.has_ctrl118) - reg_addr += CONTROL_118_SIZE; - - /* control 119 */ - if (f54->query_30.has_ctrl119) - reg_addr += CONTROL_119_SIZE; - - /* control 120 */ - if (f54->query_30.has_ctrl120) - reg_addr += CONTROL_120_SIZE; - - /* control 121 */ - if (f54->query_30.has_ctrl121) - reg_addr += CONTROL_121_SIZE; - - /* control 122 */ - if (f54->query_30.has_ctrl122_query31) - reg_addr += CONTROL_122_SIZE; - - /* control 123 */ - if (f54->query_30.has_ctrl123) - reg_addr += CONTROL_123_SIZE; - - /* control 124 reserved */ - - /* control 125 */ - if (f54->query_32.has_ctrl125) - reg_addr += CONTROL_125_SIZE; - - /* control 126 */ - if (f54->query_32.has_ctrl126) - reg_addr += CONTROL_126_SIZE; - - /* control 127 */ - if (f54->query_32.has_ctrl127) - reg_addr += CONTROL_127_SIZE; - - /* controls 128 129 130 131 reserved */ - - /* control 132 */ - if (f54->query_33.has_ctrl132) - reg_addr += CONTROL_132_SIZE; - - /* control 133 */ - if (f54->query_33.has_ctrl133) - reg_addr += CONTROL_133_SIZE; - - /* control 134 */ - if (f54->query_33.has_ctrl134) - reg_addr += CONTROL_134_SIZE; - - /* controls 135 136 reserved */ - - /* control 137 */ - if (f54->query_35.has_ctrl137) - reg_addr += CONTROL_137_SIZE; - - /* control 138 */ - if (f54->query_35.has_ctrl138) - reg_addr += CONTROL_138_SIZE; - - /* control 139 */ - if (f54->query_35.has_ctrl139) - reg_addr += CONTROL_139_SIZE; - - /* control 140 */ - if (f54->query_35.has_ctrl140) - reg_addr += CONTROL_140_SIZE; - - /* control 141 reserved */ - - /* control 142 */ - if (f54->query_36.has_ctrl142) - reg_addr += CONTROL_142_SIZE; - - /* control 143 */ - if (f54->query_36.has_ctrl143) - reg_addr += CONTROL_143_SIZE; - - /* control 144 */ - if (f54->query_36.has_ctrl144) - reg_addr += CONTROL_144_SIZE; - - /* control 145 */ - if (f54->query_36.has_ctrl145) - reg_addr += CONTROL_145_SIZE; - - /* control 146 */ - if (f54->query_36.has_ctrl146) - reg_addr += CONTROL_146_SIZE; - - /* control 147 */ - if (f54->query_38.has_ctrl147) - reg_addr += CONTROL_147_SIZE; - - /* control 148 */ - if (f54->query_38.has_ctrl148) - reg_addr += CONTROL_148_SIZE; - - /* control 149 */ - if (f54->query_38.has_ctrl149) { - control->reg_149 = kzalloc(sizeof(*(control->reg_149)), - GFP_KERNEL); - if (!control->reg_149) - goto exit_no_mem; - control->reg_149->address = reg_addr; - reg_addr += CONTROL_149_SIZE; - } - - /* controls 150 to 162 reserved */ - - /* control 163 */ - if (f54->query_40.has_ctrl163_query41) - reg_addr += CONTROL_163_SIZE; - - /* control 164 reserved */ - - /* control 165 */ - if (f54->query_40.has_ctrl165_query42) - reg_addr += CONTROL_165_SIZE; - - /* control 166 reserved */ - - /* control 167 */ - if (f54->query_40.has_ctrl167) - reg_addr += CONTROL_167_SIZE; - - /* controls 168 to 175 reserved */ - - /* control 176 */ - if (f54->query_46.has_ctrl176) - reg_addr += CONTROL_176_SIZE; - - /* controls 177 178 reserved */ - - /* control 179 */ - if (f54->query_46.has_ctrl179) - reg_addr += CONTROL_179_SIZE; - - /* controls 180 to 187 reserved */ - - /* control 188 */ - if (f54->query_49.has_ctrl188) { - control->reg_188 = kzalloc(sizeof(*(control->reg_188)), - GFP_KERNEL); - if (!control->reg_188) - goto exit_no_mem; - control->reg_188->address = reg_addr; - reg_addr += CONTROL_188_SIZE; - } - - return 0; - -exit_no_mem: - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for control registers\n", - __func__); - return -ENOMEM; -} - -static int test_set_queries(void) -{ - int retval; - unsigned char offset; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr, - f54->query.data, - sizeof(f54->query.data)); - if (retval < 0) - return retval; - - offset = sizeof(f54->query.data); - - /* query 12 */ - if (f54->query.has_sense_frequency_control == 0) - offset -= 1; - - /* query 13 */ - if (f54->query.has_query13) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_13.data, - sizeof(f54->query_13.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 14 */ - if (f54->query_13.has_ctrl87) - offset += 1; - - /* query 15 */ - if (f54->query.has_query15) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_15.data, - sizeof(f54->query_15.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 16 */ - if (f54->query_15.has_query16) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_16.data, - sizeof(f54->query_16.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 17 */ - if (f54->query_16.has_query17) - offset += 1; - - /* query 18 */ - if (f54->query_16.has_ctrl94_query18) - offset += 1; - - /* query 19 */ - if (f54->query_16.has_ctrl95_query19) - offset += 1; - - /* query 20 */ - if (f54->query_15.has_query20) - offset += 1; - - /* query 21 */ - if (f54->query_15.has_query21) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_21.data, - sizeof(f54->query_21.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 22 */ - if (f54->query_15.has_query22) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_22.data, - sizeof(f54->query_22.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 23 */ - if (f54->query_22.has_query23) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_23.data, - sizeof(f54->query_23.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 24 */ - if (f54->query_21.has_query24_data18) - offset += 1; - - /* query 25 */ - if (f54->query_15.has_query25) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_25.data, - sizeof(f54->query_25.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 26 */ - if (f54->query_22.has_ctrl103_query26) - offset += 1; - - /* query 27 */ - if (f54->query_25.has_query27) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_27.data, - sizeof(f54->query_27.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 28 */ - if (f54->query_22.has_query28) - offset += 1; - - /* query 29 */ - if (f54->query_27.has_query29) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_29.data, - sizeof(f54->query_29.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 30 */ - if (f54->query_29.has_query30) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_30.data, - sizeof(f54->query_30.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 31 */ - if (f54->query_30.has_ctrl122_query31) - offset += 1; - - /* query 32 */ - if (f54->query_30.has_query32) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_32.data, - sizeof(f54->query_32.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 33 */ - if (f54->query_32.has_query33) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_33.data, - sizeof(f54->query_33.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 34 */ - if (f54->query_32.has_query34) - offset += 1; - - /* query 35 */ - if (f54->query_32.has_query35) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_35.data, - sizeof(f54->query_35.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 36 */ - if (f54->query_33.has_query36) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_36.data, - sizeof(f54->query_36.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 37 */ - if (f54->query_36.has_query37) - offset += 1; - - /* query 38 */ - if (f54->query_36.has_query38) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_38.data, - sizeof(f54->query_38.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 39 */ - if (f54->query_38.has_query39) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_39.data, - sizeof(f54->query_39.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 40 */ - if (f54->query_39.has_query40) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_40.data, - sizeof(f54->query_40.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 41 */ - if (f54->query_40.has_ctrl163_query41) - offset += 1; - - /* query 42 */ - if (f54->query_40.has_ctrl165_query42) - offset += 1; - - /* query 43 */ - if (f54->query_40.has_query43) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_43.data, - sizeof(f54->query_43.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* queries 44 45 reserved */ - - /* query 46 */ - if (f54->query_43.has_query46) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_46.data, - sizeof(f54->query_46.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 47 */ - if (f54->query_46.has_query47) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_47.data, - sizeof(f54->query_47.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 48 reserved */ - - /* query 49 */ - if (f54->query_47.has_query49) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_49.data, - sizeof(f54->query_49.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 50 */ - if (f54->query_49.has_query50) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_50.data, - sizeof(f54->query_50.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 51 */ - if (f54->query_50.has_query51) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f54->query_base_addr + offset, - f54->query_51.data, - sizeof(f54->query_51.data)); - if (retval < 0) - return retval; - offset += 1; - } - - return 0; -} - -static void test_f54_set_regs(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn_desc *fd, - unsigned int intr_count, - unsigned char page) -{ - unsigned char ii; - unsigned char intr_offset; - - f54->query_base_addr = fd->query_base_addr | (page << 8); - f54->control_base_addr = fd->ctrl_base_addr | (page << 8); - f54->data_base_addr = fd->data_base_addr | (page << 8); - f54->command_base_addr = fd->cmd_base_addr | (page << 8); - - f54->intr_reg_num = (intr_count + 7) / 8; - if (f54->intr_reg_num != 0) - f54->intr_reg_num -= 1; - - f54->intr_mask = 0; - intr_offset = intr_count % 8; - for (ii = intr_offset; - ii < (fd->intr_src_count + intr_offset); - ii++) { - f54->intr_mask |= 1 << ii; - } - - return; -} - -static int test_f55_set_queries(void) -{ - int retval; - unsigned char offset; - struct synaptics_rmi4_data *rmi4_data = f54->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->query_base_addr, - f55->query.data, - sizeof(f55->query.data)); - if (retval < 0) - return retval; - - offset = sizeof(f55->query.data); - - /* query 3 */ - if (f55->query.has_single_layer_multi_touch) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->query_base_addr + offset, - f55->query_3.data, - sizeof(f55->query_3.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 4 */ - if ((f55->query.has_single_layer_multi_touch) && - (f55->query_3.has_ctrl9)) - offset += 1; - - /* query 5 */ - if (f55->query.has_query5) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->query_base_addr + offset, - f55->query_5.data, - sizeof(f55->query_5.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* queries 6 7 */ - if (f55->query.curve_compensation_mode == 0x3) - offset += 2; - - /* query 8 */ - if ((f55->query.has_single_layer_multi_touch) && - f55->query_3.has_ctrl8) - offset += 1; - - /* query 9 */ - if ((f55->query.has_single_layer_multi_touch) && - f55->query_3.has_query9) - offset += 1; - - /* queries 10 11 12 13 14 15 16 */ - if ((f55->query.has_query5) && (f55->query_5.has_basis_function)) - offset += 7; - - /* query 17 */ - if ((f55->query.has_query5) && (f55->query_5.has_query17)) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->query_base_addr + offset, - f55->query_17.data, - sizeof(f55->query_17.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 18 */ - if ((f55->query.has_query5) && - (f55->query_5.has_query17) && - (f55->query_17.has_query18)) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->query_base_addr + offset, - f55->query_18.data, - sizeof(f55->query_18.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 22 */ - if ((f55->query.has_query5) && - (f55->query_5.has_query17) && - (f55->query_17.has_query18) && - (f55->query_18.has_query22)) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->query_base_addr + offset, - f55->query_22.data, - sizeof(f55->query_22.data)); - if (retval < 0) - return retval; - offset += 1; - } - - /* query 23 */ - if ((f55->query.has_query5) && - (f55->query_5.has_query17) && - (f55->query_17.has_query18) && - (f55->query_18.has_query22) && - (f55->query_22.has_query23)) { - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->query_base_addr + offset, - f55->query_23.data, - sizeof(f55->query_23.data)); - if (retval < 0) - return retval; - offset += 1; - - f55->amp_sensor = f55->query_23.amp_sensor_enabled; - f55->size_of_column2mux = f55->query_23.size_of_column2mux; - } - - return 0; -} - -static void test_f55_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char ii; - unsigned char rx_electrodes = f54->query.num_of_rx_electrodes; - unsigned char tx_electrodes = f54->query.num_of_tx_electrodes; - - retval = test_f55_set_queries(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read f55 query registers\n", - __func__); - return; - } - - if (!f55->query.has_sensor_assignment) - return; - - f55->tx_assignment = kzalloc(tx_electrodes, GFP_KERNEL); - f55->rx_assignment = kzalloc(rx_electrodes, GFP_KERNEL); - - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->control_base_addr + SENSOR_TX_MAPPING_OFFSET, - f55->tx_assignment, - tx_electrodes); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read f55 tx assignment\n", - __func__); - return; - } - - retval = synaptics_rmi4_reg_read(rmi4_data, - f55->control_base_addr + SENSOR_RX_MAPPING_OFFSET, - f55->rx_assignment, - rx_electrodes); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read f55 rx assignment\n", - __func__); - return; - } - - f54->tx_assigned = 0; - for (ii = 0; ii < tx_electrodes; ii++) { - if (f55->tx_assignment[ii] != 0xff) - f54->tx_assigned++; - } - - f54->rx_assigned = 0; - for (ii = 0; ii < rx_electrodes; ii++) { - if (f55->rx_assignment[ii] != 0xff) - f54->rx_assigned++; - } - - if (f55->amp_sensor) { - f54->tx_assigned = f55->size_of_column2mux; - f54->rx_assigned /= 2; - } - - return; -} - -static void test_f55_set_regs(struct synaptics_rmi4_data *rmi4_data, - struct synaptics_rmi4_fn_desc *fd, - unsigned char page) -{ - f55 = kzalloc(sizeof(*f55), GFP_KERNEL); - if (!f55) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for f55\n", - __func__); - return; - } - - f55->query_base_addr = fd->query_base_addr | (page << 8); - f55->control_base_addr = fd->ctrl_base_addr | (page << 8); - f55->data_base_addr = fd->data_base_addr | (page << 8); - f55->command_base_addr = fd->cmd_base_addr | (page << 8); - - return; -} - -static int test_scan_pdt(void) -{ - int retval; - unsigned char intr_count = 0; - unsigned char page; - unsigned short addr; - bool f54found = false; - bool f55found = false; - struct synaptics_rmi4_fn_desc rmi_fd; - struct synaptics_rmi4_data *rmi4_data = f54->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 *)&rmi_fd, - sizeof(rmi_fd)); - if (retval < 0) - return retval; - - addr &= ~(MASK_8BIT << 8); - - if (!rmi_fd.fn_number) - break; - - switch (rmi_fd.fn_number) { - case SYNAPTICS_RMI4_F54: - test_f54_set_regs(rmi4_data, - &rmi_fd, intr_count, page); - f54found = true; - break; - case SYNAPTICS_RMI4_F55: - test_f55_set_regs(rmi4_data, - &rmi_fd, page); - f55found = true; - break; - default: - break; - } - - if (f54found && f55found) - goto pdt_done; - - intr_count += rmi_fd.intr_src_count; - } - } - - if (!f54found) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F54\n", - __func__); - return -EINVAL; - } - -pdt_done: - return 0; -} - -static void synaptics_rmi4_test_attn(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask) -{ - if (!f54) - return; - - if (f54->intr_mask & intr_mask) - queue_work(f54->test_report_workqueue, &f54->test_report_work); - - return; -} - -static int synaptics_rmi4_test_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - - if (f54) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Handle already exists\n", - __func__); - return 0; - } - - f54 = kzalloc(sizeof(*f54), GFP_KERNEL); - if (!f54) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for f54\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - f54->rmi4_data = rmi4_data; - - f55 = NULL; - - retval = test_scan_pdt(); - if (retval < 0) - goto exit_free_mem; - - retval = test_set_queries(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read f54 query registers\n", - __func__); - goto exit_free_mem; - } - - f54->tx_assigned = f54->query.num_of_tx_electrodes; - f54->rx_assigned = f54->query.num_of_rx_electrodes; - - retval = test_set_controls(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set up f54 control registers\n", - __func__); - goto exit_free_control; - } - - test_set_data(); - - if (f55) - test_f55_init(rmi4_data); - - if (rmi4_data->external_afe_buttons) - f54->tx_assigned++; - - retval = test_set_sysfs(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs entries\n", - __func__); - goto exit_sysfs; - } - - f54->test_report_workqueue = - create_singlethread_workqueue("test_report_workqueue"); - INIT_WORK(&f54->test_report_work, test_report_work); - - hrtimer_init(&f54->watchdog, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - f54->watchdog.function = test_get_report_timeout; - INIT_WORK(&f54->timeout_work, test_timeout_work); - - mutex_init(&f54->status_mutex); - f54->status = STATUS_IDLE; - - return 0; - -exit_sysfs: - if (f55) { - kfree(f55->tx_assignment); - kfree(f55->rx_assignment); - } - -exit_free_control: - test_free_control_mem(); - -exit_free_mem: - kfree(f55); - f55 = NULL; - kfree(f54); - f54 = NULL; - -exit: - return retval; -} - -static void synaptics_rmi4_test_remove(struct synaptics_rmi4_data *rmi4_data) -{ - if (!f54) - goto exit; - - hrtimer_cancel(&f54->watchdog); - - cancel_work_sync(&f54->test_report_work); - flush_workqueue(f54->test_report_workqueue); - destroy_workqueue(f54->test_report_workqueue); - - test_remove_sysfs(); - - if (f55) { - kfree(f55->tx_assignment); - kfree(f55->rx_assignment); - } - - test_free_control_mem(); - - if (f54->data_buffer_size) - kfree(f54->report_data); - - kfree(f55); - f55 = NULL; - - kfree(f54); - f54 = NULL; - -exit: - complete(&test_remove_complete); - - return; -} - -static void synaptics_rmi4_test_reset(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - - if (!f54) { - synaptics_rmi4_test_init(rmi4_data); - return; - } - - if (f55) { - kfree(f55->tx_assignment); - kfree(f55->rx_assignment); - } - - test_free_control_mem(); - - kfree(f55); - f55 = NULL; - - retval = test_scan_pdt(); - if (retval < 0) - goto exit_free_mem; - - retval = test_set_queries(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read f54 query registers\n", - __func__); - goto exit_free_mem; - } - - f54->tx_assigned = f54->query.num_of_tx_electrodes; - f54->rx_assigned = f54->query.num_of_rx_electrodes; - - retval = test_set_controls(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set up f54 control registers\n", - __func__); - goto exit_free_control; - } - - test_set_data(); - - if (f55) - test_f55_init(rmi4_data); - - if (rmi4_data->external_afe_buttons) - f54->tx_assigned++; - - f54->status = STATUS_IDLE; - - return; - -exit_free_control: - test_free_control_mem(); - -exit_free_mem: - hrtimer_cancel(&f54->watchdog); - - cancel_work_sync(&f54->test_report_work); - flush_workqueue(f54->test_report_workqueue); - destroy_workqueue(f54->test_report_workqueue); - - test_remove_sysfs(); - - if (f54->data_buffer_size) - kfree(f54->report_data); - - kfree(f55); - f55 = NULL; - - kfree(f54); - f54 = NULL; - - return; -} - -static struct synaptics_rmi4_exp_fn test_module = { - .fn_type = RMI_TEST_REPORTING, - .init = synaptics_rmi4_test_init, - .remove = synaptics_rmi4_test_remove, - .reset = synaptics_rmi4_test_reset, - .reinit = NULL, - .early_suspend = NULL, - .suspend = NULL, - .resume = NULL, - .late_resume = NULL, - .attn = synaptics_rmi4_test_attn, -}; - -static int __init rmi4_test_module_init(void) -{ - synaptics_rmi4_new_function(&test_module, true); - - return 0; -} - -static void __exit rmi4_test_module_exit(void) -{ - synaptics_rmi4_new_function(&test_module, false); - - wait_for_completion(&test_remove_complete); - - return; -} - -module_init(rmi4_test_module_init); -module_exit(rmi4_test_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX Test Reporting Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_video.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_video.c deleted file mode 100644 index 847dc4dd3049..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_video.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * - * 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. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "synaptics_dsx_core.h" - -#define SYSFS_FOLDER_NAME "video" - -/* -#define RMI_DCS_SUSPEND_RESUME -*/ - -static ssize_t video_sysfs_dcs_write_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t video_sysfs_param_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static int video_send_dcs_command(unsigned char command_opcode); - -struct f38_command { - union { - struct { - unsigned char command_opcode; - unsigned char register_access:1; - unsigned char gamma_page:1; - unsigned char f38_control1_b2__7:6; - unsigned char parameter_field_1; - unsigned char parameter_field_2; - unsigned char parameter_field_3; - unsigned char parameter_field_4; - unsigned char send_to_dcs:1; - unsigned char f38_command6_b1__7:7; - } __packed; - unsigned char data[7]; - }; -}; - -struct synaptics_rmi4_video_handle { - unsigned char param; - unsigned short query_base_addr; - unsigned short control_base_addr; - unsigned short data_base_addr; - unsigned short command_base_addr; - struct synaptics_rmi4_data *rmi4_data; - struct kobject *sysfs_dir; -}; - -#ifdef RMI_DCS_SUSPEND_RESUME -struct dcs_command { - unsigned char command; - unsigned int wait_time; -}; - -static struct dcs_command suspend_sequence[] = { - { - .command = 0x28, - .wait_time = 200, - }, - { - .command = 0x10, - .wait_time = 200, - }, -}; - -static struct dcs_command resume_sequence[] = { - { - .command = 0x11, - .wait_time = 200, - }, - { - .command = 0x29, - .wait_time = 200, - }, -}; -#endif - -static struct device_attribute attrs[] = { - __ATTR(dcs_write, S_IWUGO, - NULL, - video_sysfs_dcs_write_store), - __ATTR(param, S_IWUGO, - NULL, - video_sysfs_param_store), -}; - -static struct synaptics_rmi4_video_handle *video; - -DECLARE_COMPLETION(video_remove_complete); - -static ssize_t video_sysfs_dcs_write_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - - if (sscanf(buf, "%x", &input) != 1) - return -EINVAL; - - retval = video_send_dcs_command((unsigned char)input); - if (retval < 0) - return retval; - - return count; -} - -static ssize_t video_sysfs_param_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - - if (sscanf(buf, "%x", &input) != 1) - return -EINVAL; - - video->param = (unsigned char)input; - - return count; -} - -static int video_send_dcs_command(unsigned char command_opcode) -{ - int retval; - struct f38_command command; - struct synaptics_rmi4_data *rmi4_data = video->rmi4_data; - - memset(&command, 0x00, sizeof(command)); - - command.command_opcode = command_opcode; - command.parameter_field_1 = video->param; - command.send_to_dcs = 1; - - video->param = 0; - - retval = synaptics_rmi4_reg_write(rmi4_data, - video->command_base_addr, - command.data, - sizeof(command.data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to send DCS command\n", - __func__); - return retval; - } - - return 0; -} - -static int video_scan_pdt(void) -{ - int retval; - unsigned char page; - unsigned short addr; - bool f38_found = false; - struct synaptics_rmi4_fn_desc rmi_fd; - struct synaptics_rmi4_data *rmi4_data = video->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 *)&rmi_fd, - sizeof(rmi_fd)); - if (retval < 0) - return retval; - - addr &= ~(MASK_8BIT << 8); - - if (!rmi_fd.fn_number) - break; - - if (rmi_fd.fn_number == SYNAPTICS_RMI4_F38) { - f38_found = true; - goto f38_found; - } - } - } - - if (!f38_found) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F38\n", - __func__); - return -EINVAL; - } - -f38_found: - video->query_base_addr = rmi_fd.query_base_addr | (page << 8); - video->control_base_addr = rmi_fd.ctrl_base_addr | (page << 8); - video->data_base_addr = rmi_fd.data_base_addr | (page << 8); - video->command_base_addr = rmi_fd.cmd_base_addr | (page << 8); - - return 0; -} - -static int synaptics_rmi4_video_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char attr_count; - - if (video) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Handle already exists\n", - __func__); - return 0; - } - - video = kzalloc(sizeof(*video), GFP_KERNEL); - if (!video) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for video\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - video->rmi4_data = rmi4_data; - - retval = video_scan_pdt(); - if (retval < 0) { - retval = 0; - goto exit_scan_pdt; - } - - video->sysfs_dir = kobject_create_and_add(SYSFS_FOLDER_NAME, - &rmi4_data->input_dev->dev.kobj); - if (!video->sysfs_dir) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs directory\n", - __func__); - retval = -ENODEV; - goto exit_sysfs_dir; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(video->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 exit_sysfs_attrs; - } - } - - return 0; - -exit_sysfs_attrs: - for (attr_count--; attr_count >= 0; attr_count--) - sysfs_remove_file(video->sysfs_dir, &attrs[attr_count].attr); - - kobject_put(video->sysfs_dir); - -exit_sysfs_dir: -exit_scan_pdt: - kfree(video); - video = NULL; - -exit: - return retval; -} - -static void synaptics_rmi4_video_remove(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char attr_count; - - if (!video) - goto exit; - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) - sysfs_remove_file(video->sysfs_dir, &attrs[attr_count].attr); - - kobject_put(video->sysfs_dir); - - kfree(video); - video = NULL; - -exit: - complete(&video_remove_complete); - - return; -} - -static void synaptics_rmi4_video_reset(struct synaptics_rmi4_data *rmi4_data) -{ - if (!video) - synaptics_rmi4_video_init(rmi4_data); - - return; -} - -#ifdef RMI_DCS_SUSPEND_RESUME -static void synaptics_rmi4_video_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char ii; - unsigned char command; - unsigned char num_of_cmds; - - if (!video) - return; - - num_of_cmds = ARRAY_SIZE(suspend_sequence); - - for (ii = 0; ii < num_of_cmds; ii++) { - command = suspend_sequence[ii].command; - retval = video_send_dcs_command(command); - if (retval < 0) - return; - msleep(suspend_sequence[ii].wait_time); - } - - return; -} - -static void synaptics_rmi4_video_resume(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char ii; - unsigned char command; - unsigned char num_of_cmds; - - if (!video) - return; - - num_of_cmds = ARRAY_SIZE(resume_sequence); - - for (ii = 0; ii < num_of_cmds; ii++) { - command = resume_sequence[ii].command; - retval = video_send_dcs_command(command); - if (retval < 0) - return; - msleep(resume_sequence[ii].wait_time); - } - - return; -} -#endif - -static struct synaptics_rmi4_exp_fn video_module = { - .fn_type = RMI_VIDEO, - .init = synaptics_rmi4_video_init, - .remove = synaptics_rmi4_video_remove, - .reset = synaptics_rmi4_video_reset, - .reinit = NULL, - .early_suspend = NULL, -#ifdef RMI_DCS_SUSPEND_RESUME - .suspend = synaptics_rmi4_video_suspend, - .resume = synaptics_rmi4_video_resume, -#else - .suspend = NULL, - .resume = NULL, -#endif - .late_resume = NULL, - .attn = NULL, -}; - -static int __init rmi4_video_module_init(void) -{ - synaptics_rmi4_new_function(&video_module, true); - - return 0; -} - -static void __exit rmi4_video_module_exit(void) -{ - synaptics_rmi4_new_function(&video_module, false); - - wait_for_completion(&video_remove_complete); - - return; -} - -module_init(rmi4_video_module_init); -module_exit(rmi4_video_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX Video Module"); -MODULE_LICENSE("GPL v2"); diff --git a/include/linux/input/synaptics_dsx_v2_6.h b/include/linux/input/synaptics_dsx_v2_6.h deleted file mode 100644 index 5d4bbedb5f1a..000000000000 --- a/include/linux/input/synaptics_dsx_v2_6.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012-2015 Synaptics Incorporated. All rights reserved. - * - * Copyright (C) 2012 Alexandra Chin - * Copyright (C) 2012 Scott Lin - * Copyright (C) 2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS - * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS. - * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION - * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED - * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES - * NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' - * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. - * DOLLARS. - */ - -#ifndef _SYNAPTICS_DSX_H_ -#define _SYNAPTICS_DSX_H_ - -#define PLATFORM_DRIVER_NAME "synaptics_dsxv26" -#define STYLUS_DRIVER_NAME "synaptics_dsxv26_stylus" -#define ACTIVE_PEN_DRIVER_NAME "synaptics_dsxv26_active_pen" -#define PROXIMITY_DRIVER_NAME "synaptics_dsxv26_proximity" -#define GESTURE_DRIVER_NAME "synaptics_dsxv26_gesture" -#define I2C_DRIVER_NAME "synaptics_dsxv26" -#define SPI_DRIVER_NAME "synaptics_dsxv26" - -/* - * struct synaptics_dsx_button_map - button map - * @nbuttons: number of buttons - * @map: pointer to array of button codes - */ -struct synaptics_dsx_button_map { - unsigned char nbuttons; - unsigned int *map; -}; - -/* - * struct synaptics_dsx_board_data - DSX board data - * @x_flip: x flip flag - * @y_flip: y flip flag - * @swap_axes: swap axes flag - * @resume_in_workqueue: defer resume function to workqueue - * @irq_gpio: attention interrupt GPIO - * @irq_on_state: attention interrupt active state - * @power_gpio: power switch GPIO - * @power_on_state: power switch active state - * @reset_gpio: reset GPIO - * @reset_on_state: reset active state - * @max_y_for_2d: maximum y value for 2D area when virtual buttons are present - * @irq_flags: IRQ flags - * @i2c_addr: I2C slave address - * @ub_i2c_addr: microbootloader mode I2C slave address - * @device_descriptor_addr: HID device descriptor address - * @panel_x: x-axis resolution of display panel - * @panel_y: y-axis resolution of display panel - * @power_delay_ms: delay time to wait after powering up device - * @reset_delay_ms: delay time to wait after resetting device - * @reset_active_ms: reset active time - * @byte_delay_us: delay time between two bytes of SPI data - * @block_delay_us: delay time between two SPI transfers - * @pwr_reg_name: pointer to name of regulator for power control - * @bus_reg_name: pointer to name of regulator for bus pullup control - * @cap_button_map: pointer to 0D button map - * @vir_button_map: pointer to virtual button map - * @resume_in_workqueue: defer resume function to workqueue - */ -struct synaptics_dsx_board_data { - bool x_flip; - bool y_flip; - bool swap_axes; - bool resume_in_workqueue; - int irq_gpio; - int irq_on_state; - int power_gpio; - int power_on_state; - int reset_gpio; - int reset_on_state; - int max_y_for_2d; - unsigned long irq_flags; - unsigned short i2c_addr; - unsigned short ub_i2c_addr; - unsigned short device_descriptor_addr; - unsigned int panel_x; - unsigned int panel_y; - unsigned int power_delay_ms; - unsigned int reset_delay_ms; - unsigned int reset_active_ms; - unsigned int byte_delay_us; - unsigned int block_delay_us; - const char *pwr_reg_name; - const char *bus_reg_name; - struct synaptics_dsx_button_map *cap_button_map; - struct synaptics_dsx_button_map *vir_button_map; -}; - -#endif