lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1446766925-31123-1-git-send-email-aduggan@synaptics.com>
Date:	Thu, 5 Nov 2015 15:42:05 -0800
From:	Andrew Duggan <aduggan@...aptics.com>
To:	<linux-input@...r.kernel.org>, <linux-kernel@...r.kernel.org>
CC:	Andrew Duggan <aduggan@...aptics.com>,
	Dmitry Torokhov <dmitry.torokhov@...il.com>,
	Linus Walleij <linus.walleij@...aro.org>,
	Benjamin Tissoires <benjamin.tissoires@...il.com>,
	Christopher Heiny <cheiny@...aptics.com>,
	Stephen Chandler Paul <cpaul@...hat.com>
Subject: [PATCH 20/26] Input: synaptics-rmi4: Create common functions for 2D sensors

RMI4 defines two functions for 2D sensors. This patch moves some of the
code which is shared between the two functions into a new file to avoid
duplicating the code on rmi_f11.c and rmi_f12.c.

Signed-off-by: Andrew Duggan <aduggan@...aptics.com>
---
 .../bindings/input/rmi4/rmi_2d_sensor.txt          |  55 +++
 drivers/input/rmi4/Kconfig                         |  11 +
 drivers/input/rmi4/Makefile                        |   2 +
 drivers/input/rmi4/rmi_2d_sensor.c                 | 370 ++++++++++++++++
 drivers/input/rmi4/rmi_2d_sensor.h                 |  87 ++++
 drivers/input/rmi4/rmi_f11.c                       | 487 +++++----------------
 include/linux/rmi.h                                |  30 +-
 7 files changed, 639 insertions(+), 403 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/rmi4/rmi_2d_sensor.txt
 create mode 100644 drivers/input/rmi4/rmi_2d_sensor.c
 create mode 100644 drivers/input/rmi4/rmi_2d_sensor.h

diff --git a/Documentation/devicetree/bindings/input/rmi4/rmi_2d_sensor.txt b/Documentation/devicetree/bindings/input/rmi4/rmi_2d_sensor.txt
new file mode 100644
index 0000000..79411c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/rmi4/rmi_2d_sensor.txt
@@ -0,0 +1,55 @@
+Synaptics RMI4 2D Sensor Device Binding
+
+The Synaptics RMI4 core is able to support RMI4 devices using differnet
+transports and differnet functions. This file describes the device tree
+bindings for devices which contain 2D sensors using Function 11 or
+Function 12. Complete documentation for transports and other functions
+can be found in:
+Documentation/devicetree/bindings/input/rmi4.
+
+RMI4 Function 11 and Function 12 are for 2D touch position sensing.
+Additional documentation for F11 can be found at:
+http://www.synaptics.com/sites/default/files/511-000136-01-Rev-E-RMI4-Interfacing-Guide.pdf
+
+Optional Properties:
+- syna,swap-axes: Swap X and Y positions when reporting (boolean).
+- syna,flip-x: Reverse the direction of X (boolean).
+- syna,flip-y: Reverse the direction of Y (boolean).
+- syna,clip-x-low: Sets a minimum value for X.
+- syna,clip-y-low: Sets a minimum value for Y.
+- syna,clip-x-high: Sets a maximum value for X.
+- syna,clip-y-high: Sets a maximum value for Y.
+- syna,offset-x: Add an offset to X.
+- syna,offset_y: Add an offset to Y.
+- syna,delta-x-threshold: Set the minimum distance on the X axis required
+				to generate an interrupt in reduced reporting
+				mode.
+- syna,delta-y-threshold: Set the minimum distance on the Y axis required
+				to generate an interrupt in reduced reporting
+				mode.
+- syna,type-a: Report type A multitouch events.
+- syna,sensor-type: Set the sensor type. 1 for touchscreen 2 for touchpad.
+- syna,x-mm: The length in millimeters of the X axis.
+- syna,y-mm: The length in millimeters of the Y axis.
+- syna,disable-report-mask: Mask for disabling posiiton reporting. Used to
+				disable reporing absolute position data.
+- syna,rezero-wait: Time in miliseconds to wait after issuing a rezero
+				command.
+
+
+Example of a RMI4 I2C device with F11:
+Example:
+	&i2c1 {
+		rmi-i2c-dev@2c {
+			compatible = "syna,rmi-i2c";
+
+			...
+
+			rmi-f11@11 {
+				reg = <0x11>;
+				syna,flip-y;
+				syna,sensor-type = <2>;
+			};
+		};
+	};
+
diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index 88a3919..db2c1be 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -45,6 +45,17 @@ config RMI4_SPI
 
 	  If unsure, say N.
 
+config RMI4_2D_SENSOR
+	bool "RMI4 2D Sensors"
+	depends on RMI4_CORE
+	default y if RMI4_CORE
+	help
+	  Say Y here if you want to add support for 2D Sensors.
+
+	  Provides core functionality for 2D multifinger pointing for
+	  touchscreens and touchpads using RMI4 functions 11 and 12. This
+	  feature is needed is the device contains either F11 or F12.
+
 config RMI4_F11
 	bool "RMI4 Function 11 (2D pointing)"
 	depends on RMI4_CORE
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 1745757..e4812d8 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -1,6 +1,8 @@
 obj-$(CONFIG_RMI4_CORE) += rmi_core.o
 rmi_core-y := rmi_bus.o rmi_driver.o rmi_f01.o
 
+rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
+
 # Function drivers
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 
diff --git a/drivers/input/rmi4/rmi_2d_sensor.c b/drivers/input/rmi4/rmi_2d_sensor.c
new file mode 100644
index 0000000..57c0ba8
--- /dev/null
+++ b/drivers/input/rmi4/rmi_2d_sensor.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2011-2015 Synaptics Incorporated
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/rmi.h>
+#include "rmi_driver.h"
+#include "rmi_2d_sensor.h"
+
+#define RMI_2D_REL_POS_MIN		-128
+#define RMI_2D_REL_POS_MAX		127
+
+/* maximum ABS_MT_POSITION displacement (in mm) */
+#define DMAX 10
+
+void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
+				struct rmi_2d_sensor_abs_object *obj,
+				int slot)
+{
+	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
+
+	/* we keep the previous values if the finger is released */
+	if (obj->type == RMI_2D_OBJECT_NONE)
+		return;
+
+	if (axis_align->swap_axes)
+		swap(obj->x, obj->y);
+
+	if (axis_align->flip_x)
+		obj->x = sensor->max_x - obj->x;
+
+	if (axis_align->flip_y)
+		obj->y = sensor->max_y - obj->y;
+
+	/*
+	 * Here checking if X offset or y offset are specified is
+	 * redundant. We just add the offsets or clip the values.
+	 *
+	 * Note: offsets need to be applied before clipping occurs,
+	 * or we could get funny values that are outside of
+	 * clipping boundaries.
+	 */
+	obj->x += axis_align->offset_x;
+	obj->y += axis_align->offset_y;
+
+	obj->x =  max(axis_align->clip_x_low, obj->x);
+	obj->y =  max(axis_align->clip_y_low, obj->y);
+
+	if (axis_align->clip_x_high)
+		obj->x = min(sensor->max_x, obj->x);
+
+	if (axis_align->clip_y_high)
+		obj->y =  min(sensor->max_y, obj->y);
+
+	sensor->tracking_pos[slot].x = obj->x;
+	sensor->tracking_pos[slot].y = obj->y;
+}
+EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_process);
+
+void rmi_2d_sensor_abs_report(struct rmi_2d_sensor *sensor,
+				struct rmi_2d_sensor_abs_object *obj,
+				int slot)
+{
+	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
+	struct input_dev *input = sensor->input;
+	int wide, major, minor;
+
+	if (sensor->kernel_tracking)
+		input_mt_slot(input, sensor->tracking_slots[slot]);
+	else
+		input_mt_slot(input, slot);
+
+	input_mt_report_slot_state(input, obj->mt_tool,
+				   obj->type != RMI_2D_OBJECT_NONE);
+
+	if (obj->type != RMI_2D_OBJECT_NONE) {
+		obj->x = sensor->tracking_pos[slot].x;
+		obj->y = sensor->tracking_pos[slot].y;
+
+		if (axis_align->swap_axes)
+			swap(obj->wx, obj->wy);
+
+		wide = (obj->wx > obj->wy);
+		major = max(obj->wx, obj->wy);
+		minor = min(obj->wx, obj->wy);
+
+		if (obj->type == RMI_2D_OBJECT_STYLUS) {
+			major = max(1, major);
+			minor = max(1, minor);
+		}
+
+		input_event(sensor->input, EV_ABS, ABS_MT_POSITION_X, obj->x);
+		input_event(sensor->input, EV_ABS, ABS_MT_POSITION_Y, obj->y);
+		input_event(sensor->input, EV_ABS, ABS_MT_ORIENTATION, wide);
+		input_event(sensor->input, EV_ABS, ABS_MT_PRESSURE, obj->z);
+		input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
+		input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
+
+		dev_dbg(&sensor->input->dev, "%s: obj[%d]: type: 0x%02x X: %d Y: %d Z: %d WX: %d WY: %d\n",
+			__func__, slot, obj->type, obj->x, obj->y, obj->z,
+			obj->wx, obj->wy);
+	}
+}
+EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_report);
+
+void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y)
+{
+	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
+
+	x = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)x));
+	y = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)y));
+
+	if (axis_align->swap_axes)
+		swap(x, y);
+
+	if (axis_align->flip_x)
+		x = min(RMI_2D_REL_POS_MAX, -x);
+
+	if (axis_align->flip_y)
+		y = min(RMI_2D_REL_POS_MAX, -y);
+
+	if (x || y) {
+		input_report_rel(sensor->input, REL_X, x);
+		input_report_rel(sensor->input, REL_Y, y);
+	}
+}
+EXPORT_SYMBOL_GPL(rmi_2d_sensor_rel_report);
+
+static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
+{
+	struct input_dev *input = sensor->input;
+	int res_x;
+	int res_y;
+	int input_flags = 0;
+
+	if (sensor->report_abs) {
+		if (sensor->axis_align.swap_axes)
+			swap(sensor->max_x, sensor->max_y);
+
+		sensor->min_x = sensor->axis_align.clip_x_low;
+		if (sensor->axis_align.clip_x_high)
+			sensor->max_x = min(sensor->max_x,
+				sensor->axis_align.clip_x_high);
+
+		sensor->min_y = sensor->axis_align.clip_y_low;
+		if (sensor->axis_align.clip_y_high)
+			sensor->max_y = min(sensor->max_y,
+				sensor->axis_align.clip_y_high);
+
+		set_bit(EV_ABS, input->evbit);
+		input_set_abs_params(input, ABS_MT_POSITION_X, 0, sensor->max_x,
+					0, 0);
+		input_set_abs_params(input, ABS_MT_POSITION_Y, 0, sensor->max_y,
+					0, 0);
+
+		if (sensor->x_mm && sensor->y_mm) {
+			res_x = (sensor->max_x - sensor->min_x) / sensor->x_mm;
+			res_y = (sensor->max_y - sensor->min_y) / sensor->y_mm;
+
+			input_abs_set_res(input, ABS_X, res_x);
+			input_abs_set_res(input, ABS_Y, res_y);
+
+			input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
+			input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
+
+			if (!sensor->dmax)
+				sensor->dmax = DMAX * res_x;
+		}
+
+		input_set_abs_params(input, ABS_MT_PRESSURE, 0,	0xff, 0, 0);
+		input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,	0, 0x0f, 0, 0);
+		input_set_abs_params(input, ABS_MT_TOUCH_MINOR,	0, 0x0f, 0, 0);
+		input_set_abs_params(input, ABS_MT_ORIENTATION,	0, 1, 0, 0);
+
+		if (sensor->sensor_type == rmi_sensor_touchpad)
+			input_flags = INPUT_MT_POINTER;
+		else
+			input_flags = INPUT_MT_DIRECT;
+
+		if (sensor->kernel_tracking)
+			input_flags |= INPUT_MT_TRACK;
+
+		input_mt_init_slots(input, sensor->nbr_fingers, input_flags);
+	}
+
+	if (sensor->report_rel) {
+		set_bit(EV_REL, input->evbit);
+		set_bit(REL_X, input->relbit);
+		set_bit(REL_Y, input->relbit);
+	}
+
+	if (sensor->topbuttonpad)
+		set_bit(INPUT_PROP_TOPBUTTONPAD, input->propbit);
+}
+EXPORT_SYMBOL_GPL(rmi_2d_sensor_set_input_params);
+
+int rmi_2d_sensor_configure_input(struct rmi_function *fn,
+					struct rmi_2d_sensor *sensor)
+{
+	struct rmi_device *rmi_dev = fn->rmi_dev;
+	struct input_dev *input_dev;
+	struct rmi_driver *driver = rmi_dev->driver;
+	struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
+	int rc;
+
+	if (!drv_data->input) {
+		input_dev = input_allocate_device();
+	} else {
+		input_dev = drv_data->input;
+		sensor->unified_input = true;
+	}
+
+	if (!input_dev) {
+		rc = -ENOMEM;
+		goto error_unregister;
+	}
+
+	sensor->input = input_dev;
+
+	if (!sensor->unified_input) {
+		if (driver->set_input_params) {
+			rc = driver->set_input_params(rmi_dev, input_dev);
+			if (rc < 0) {
+				dev_err(&fn->dev,
+					"%s: Error in setting input device.\n",
+					__func__);
+				goto error_unregister;
+			}
+		}
+		snprintf(sensor->input_phys, sizeof(sensor->input_phys),
+			"%s.abs/input0", dev_name(&fn->dev));
+		input_dev->phys = sensor->input_phys;
+		input_dev->dev.parent = &rmi_dev->dev;
+	}
+
+	rmi_2d_sensor_set_input_params(sensor);
+
+	if (!sensor->unified_input) {
+		rc = input_register_device(input_dev);
+		if (rc) {
+			input_free_device(input_dev);
+			sensor->input = NULL;
+			goto error_unregister;
+		}
+	}
+
+	return 0;
+
+error_unregister:
+	if (!sensor->unified_input && sensor->input) {
+		input_unregister_device(sensor->input);
+		sensor->input = NULL;
+	}
+
+	return rc;
+}
+
+#ifdef CONFIG_OF
+int rmi_2d_sensor_of_probe(struct device *dev,
+				struct rmi_2d_sensor_platform_data *pdata)
+{
+	int retval;
+
+	pdata->axis_align.swap_axes = of_property_read_bool(dev->of_node,
+						"syna,swap-axes");
+
+	pdata->axis_align.flip_x = of_property_read_bool(dev->of_node,
+						"syna,flip-x");
+
+	pdata->axis_align.flip_y = of_property_read_bool(dev->of_node,
+						"syna,flip-y");
+
+	retval = rmi_of_property_read_u16(dev,
+			&pdata->axis_align.clip_x_low,
+			"syna,clip-x-low", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u16(dev,
+			&pdata->axis_align.clip_y_low,
+			"syna,clip-y-low", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u16(dev,
+			&pdata->axis_align.clip_x_high,
+			"syna,clip-x-high", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u16(dev,
+			&pdata->axis_align.clip_y_high,
+			"syna,clip-y-high", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u16(dev,
+			&pdata->axis_align.offset_x,
+			"syna,offset-x", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u16(dev,
+			&pdata->axis_align.offset_y,
+			"syna,offset_y", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u8(dev,
+			&pdata->axis_align.delta_x_threshold,
+			"syna,delta-x-threshold", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u8(dev,
+			&pdata->axis_align.delta_y_threshold,
+			"syna,delta-y-threshold", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u32(dev,
+			(u32 *)&pdata->sensor_type,
+			"syna,sensor-type", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u32(dev,
+			(u32 *)&pdata->x_mm,
+			"syna,x-mm", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u32(dev,
+			(u32 *)&pdata->y_mm,
+			"syna,y-mm", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u32(dev,
+			(u32 *)&pdata->disable_report_mask,
+			"syna,disable-report-mask", 1);
+	if (retval)
+		return retval;
+
+	retval = rmi_of_property_read_u16(dev, &pdata->rezero_wait,
+			"syna,rezero-wait", 1);
+	if (retval)
+		return retval;
+
+	return 0;
+}
+#else
+inline int rmi_2d_sensor_of_probe(struct device *dev,
+				struct rmi_2d_sensor *sensor,
+				struct rmi_2d_sensor_platform_data *pdata)
+{
+	return -ENODEV;
+}
+
+
+#endif
diff --git a/drivers/input/rmi4/rmi_2d_sensor.h b/drivers/input/rmi4/rmi_2d_sensor.h
new file mode 100644
index 0000000..c13a50d
--- /dev/null
+++ b/drivers/input/rmi4/rmi_2d_sensor.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011-2015 Synaptics Incorporated
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _RMI_2D_SENSOR_H
+#define _RMI_2D_SENSOR_H
+
+enum rmi_2d_sensor_object_type {
+	RMI_2D_OBJECT_NONE,
+	RMI_2D_OBJECT_FINGER,
+	RMI_2D_OBJECT_STYLUS,
+	RMI_2D_OBJECT_PALM,
+	RMI_2D_OBJECT_UNCLASSIFIED,
+};
+
+struct rmi_2d_sensor_abs_object {
+	enum rmi_2d_sensor_object_type type;
+	int mt_tool;
+	u16 x;
+	u16 y;
+	u8 z;
+	u8 wx;
+	u8 wy;
+};
+
+/**
+ * @axis_align - controls parameters that are useful in system prototyping
+ * and bring up.
+ * @max_x - The maximum X coordinate that will be reported by this sensor.
+ * @max_y - The maximum Y coordinate that will be reported by this sensor.
+ * @nbr_fingers - How many fingers can this sensor report?
+ * @data_pkt - buffer for data reported by this sensor.
+ * @pkt_size - number of bytes in that buffer.
+ * @type_a - some early RMI4 2D sensors do not reliably track the finger
+ * position when two fingers are on the device.  When this is true, we
+ * assume we have one of those sensors and report events appropriately.
+ * @sensor_type - indicates whether we're touchscreen or touchpad.
+ * @input - input device for absolute pointing stream
+ * @input_phys - buffer for the absolute phys name for this sensor.
+ */
+struct rmi_2d_sensor {
+	struct rmi_2d_axis_alignment axis_align;
+	struct input_mt_pos *tracking_pos;
+	int *tracking_slots;
+	bool kernel_tracking;
+	struct rmi_2d_sensor_abs_object *objs;
+	int dmax;
+	u16 min_x;
+	u16 max_x;
+	u16 min_y;
+	u16 max_y;
+	u8 nbr_fingers;
+	u8 *data_pkt;
+	int pkt_size;
+	bool topbuttonpad;
+	enum rmi_sensor_type sensor_type;
+	struct input_dev *input;
+	bool unified_input;
+	struct rmi_function *fn;
+	char input_phys[32];
+	u8 report_abs;
+	u8 report_rel;
+	u8 x_mm;
+	u8 y_mm;
+};
+
+int rmi_2d_sensor_of_probe(struct device *dev,
+				struct rmi_2d_sensor_platform_data *pdata);
+
+void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
+				struct rmi_2d_sensor_abs_object *obj,
+				int slot);
+
+void rmi_2d_sensor_abs_report(struct rmi_2d_sensor *sensor,
+				struct rmi_2d_sensor_abs_object *obj,
+				int slot);
+
+void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y);
+
+int rmi_2d_sensor_configure_input(struct rmi_function *fn,
+					struct rmi_2d_sensor *sensor);
+#endif /* _RMI_2D_SENSOR_H */
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 146691f..ee4b155 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -15,14 +15,13 @@
 #include <linux/kconfig.h>
 #include <linux/rmi.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 #include "rmi_driver.h"
+#include "rmi_2d_sensor.h"
 
 #define F11_MAX_NUM_OF_FINGERS		10
 #define F11_MAX_NUM_OF_TOUCH_SHAPES	16
 
-#define F11_REL_POS_MIN		-128
-#define F11_REL_POS_MAX		127
-
 #define FINGER_STATE_MASK	0x03
 
 #define F11_CTRL_SENSOR_MAX_X_POS_OFFSET	6
@@ -34,7 +33,6 @@
 #define DEFAULT_MAX_ABS_MT_ORIENTATION 1
 #define DEFAULT_MIN_ABS_MT_TRACKING_ID 1
 #define DEFAULT_MAX_ABS_MT_TRACKING_ID 10
-#define FUNCTION_NUMBER 0x11
 
 /** A note about RMI4 F11 register structure.
  *
@@ -488,48 +486,6 @@ struct f11_2d_data {
 	s8	*scroll_zones;
 };
 
-/**
- * @axis_align - controls parameters that are useful in system prototyping
- * and bring up.
- * @sens_query - query registers for this particular sensor.
- * @data - the data reported by this sensor, mapped into a collection of
- * structs.
- * @max_x - The maximum X coordinate that will be reported by this sensor.
- * @max_y - The maximum Y coordinate that will be reported by this sensor.
- * @nbr_fingers - How many fingers can this sensor report?
- * @data_pkt - buffer for data reported by this sensor.
- * @pkt_size - number of bytes in that buffer.
- * @sensor_index - identifies this particular 2D touch sensor
- * @sensor_type - indicates whether we're touchscreen or touchpad.
- * @input - input device for absolute pointing stream
- * @input_phys - buffer for the absolute phys name for this sensor.
- */
-struct f11_2d_sensor {
-	struct rmi_f11_2d_axis_alignment axis_align;
-	struct f11_2d_sensor_queries sens_query;
-	struct f11_2d_data data;
-	struct input_mt_pos *tracking_pos;
-	int *tracking_slots;
-	bool kernel_tracking;
-	int dmax;
-	u16 max_x;
-	u16 max_y;
-	u8 nbr_fingers;
-	u8 *data_pkt;
-	int pkt_size;
-	u8 sensor_index;
-	bool topbuttonpad;
-	enum rmi_f11_sensor_type sensor_type;
-	struct input_dev *input;
-	bool unified_input;
-	struct rmi_function *fn;
-	char input_phys[NAME_BUFFER_SIZE];
-	u8 report_abs;
-	u8 report_rel;
-	u8 x_mm;
-	u8 y_mm;
-};
-
 /** Data pertaining to F11 in general.  For per-sensor data, see struct
  * f11_2d_sensor.
  *
@@ -551,7 +507,10 @@ struct f11_data {
 	struct f11_2d_ctrl dev_controls;
 	struct mutex dev_controls_mutex;
 	u16 rezero_wait_ms;
-	struct f11_2d_sensor sensor;
+	struct rmi_2d_sensor sensor;
+	struct f11_2d_sensor_queries sens_query;
+	struct f11_2d_data data;
+	struct rmi_2d_sensor_platform_data sensor_pdata;
 	unsigned long *abs_mask;
 	unsigned long *rel_mask;
 	unsigned long *result_bits;
@@ -567,151 +526,60 @@ enum f11_finger_state {
 /** F11_INACCURATE state is overloaded to indicate pen present. */
 #define F11_PEN F11_INACCURATE
 
-static int rmi_f11_get_tool_type(struct f11_2d_sensor *sensor,
+static int rmi_f11_get_tool_type(struct f11_data *f11,
 				 enum f11_finger_state finger_state)
 {
 	if (IS_ENABLED(CONFIG_RMI4_F11_PEN) &&
-			sensor->sens_query.has_pen &&
+			f11->sens_query.has_pen &&
 			finger_state == F11_PEN)
 		return MT_TOOL_PEN;
 
 	return MT_TOOL_FINGER;
 }
 
-static void rmi_f11_rel_pos_report(struct f11_2d_sensor *sensor, u8 n_finger)
+static void rmi_f11_rel_pos_report(struct f11_data *f11, u8 n_finger)
 {
-	struct f11_2d_data *data = &sensor->data;
-	struct rmi_f11_2d_axis_alignment *axis_align = &sensor->axis_align;
+	struct rmi_2d_sensor *sensor = &f11->sensor;
+	struct f11_2d_data *data = &f11->data;
 	s8 x, y;
-	s8 temp;
 
 	x = data->rel_pos[n_finger * 2];
 	y = data->rel_pos[n_finger * 2 + 1];
 
-	x = min(F11_REL_POS_MAX, max(F11_REL_POS_MIN, (int)x));
-	y = min(F11_REL_POS_MAX, max(F11_REL_POS_MIN, (int)y));
-
-	if (axis_align->swap_axes) {
-		temp = x;
-		x = y;
-		y = temp;
-	}
-	if (axis_align->flip_x)
-		x = min(F11_REL_POS_MAX, -x);
-	if (axis_align->flip_y)
-		y = min(F11_REL_POS_MAX, -y);
-
-	if (x || y) {
-		input_report_rel(sensor->input, REL_X, x);
-		input_report_rel(sensor->input, REL_Y, y);
-	}
-}
-
-static void rmi_f11_abs_parse_xy(struct f11_data *f11,
-				 struct f11_2d_sensor *sensor,
-				 enum f11_finger_state finger_state,
-				 u8 n_finger)
-{
-	struct f11_2d_data *data = &sensor->data;
-	struct rmi_f11_2d_axis_alignment *axis_align = &sensor->axis_align;
-	u8 *pos_data = &data->abs_pos[n_finger * RMI_F11_ABS_BYTES];
-	u16 x, y;
-
-	/* we keep the previous values if the finger is released */
-	if (!finger_state)
-		return;
-
-	x = (pos_data[0] << 4) | (pos_data[2] & 0x0F);
-	y = (pos_data[1] << 4) | (pos_data[2] >> 4);
-
-	if (axis_align->swap_axes)
-		swap(x, y);
-
-	if (axis_align->flip_x)
-		x = max(sensor->max_x - x, 0);
-
-	if (axis_align->flip_y)
-		y = max(sensor->max_y - y, 0);
-
-	/*
-	 * Here checking if X offset or y offset are specified is
-	 * redundant. We just add the offsets or clip the values.
-	 *
-	 * Note: offsets need to be applied before clipping occurs,
-	 * or we could get funny values that are outside of
-	 * clipping boundaries.
-	 */
-	x += axis_align->offset_x;
-	y += axis_align->offset_y;
-	x =  max(axis_align->clip_x_low, x);
-	y =  max(axis_align->clip_y_low, y);
-	if (axis_align->clip_x_high)
-		x = min(axis_align->clip_x_high, x);
-	if (axis_align->clip_y_high)
-		y =  min(axis_align->clip_y_high, y);
-
-	sensor->tracking_pos[n_finger].x = x;
-	sensor->tracking_pos[n_finger].y = y;
+	rmi_2d_sensor_rel_report(sensor, x, y);
 }
 
-static void rmi_f11_abs_pos_report(struct f11_data *f11,
-				   struct f11_2d_sensor *sensor,
+static void rmi_f11_abs_pos_process(struct f11_data *f11,
+				   struct rmi_2d_sensor *sensor,
+				   struct rmi_2d_sensor_abs_object *obj,
 				   enum f11_finger_state finger_state,
 				   u8 n_finger)
 {
-	struct f11_2d_data *data = &sensor->data;
-	struct input_dev *input = sensor->input;
-	struct rmi_f11_2d_axis_alignment *axis_align = &sensor->axis_align;
+	struct f11_2d_data *data = &f11->data;
 	u8 *pos_data = &data->abs_pos[n_finger * RMI_F11_ABS_BYTES];
-	u16 x, y, z;
-	int w_x, w_y, w_max, w_min, orient;
-	int tool_type = rmi_f11_get_tool_type(sensor, finger_state);
-
-	if (sensor->kernel_tracking)
-		input_mt_slot(input, sensor->tracking_slots[n_finger]);
-	else
-		input_mt_slot(input, n_finger);
-	input_mt_report_slot_state(input, tool_type,
-				   finger_state != F11_NO_FINGER);
-
-	if (finger_state) {
-		x = sensor->tracking_pos[n_finger].x;
-		y = sensor->tracking_pos[n_finger].y;
-
-		w_x = pos_data[3] & 0x0f;
-		w_y = pos_data[3] >> 4;
-
-		if (axis_align->swap_axes)
-			swap(w_x, w_y);
-
-		orient = w_x > w_y ? 1 : 0;
-
-		w_max = max(w_x, w_y);
-		w_min = min(w_x, w_y);
-
-		/*
-		 * Some UIs ignore W of zero, so we fudge it to 1 for pens.  This
-		 * only appears to be an issue when reporting pens, not plain old
-		 * fingers.
-		 */
-		if (tool_type == MT_TOOL_PEN) {
-			w_max = max(1, w_max);
-			w_min = max(1, w_min);
-		}
-
-		z = pos_data[4];
+	int tool_type = rmi_f11_get_tool_type(f11, finger_state);
+
+	switch (finger_state) {
+	case F11_PEN:
+		if (IS_ENABLED(CONFIG_RMI4_F11_PEN) &&
+		    f11->sens_query.has_pen)
+			obj->type = RMI_2D_OBJECT_STYLUS;
+		break;
+	case F11_PRESENT:
+		obj->type = RMI_2D_OBJECT_FINGER;
+		break;
+	default:
+		obj->type = RMI_2D_OBJECT_NONE;
+	}
 
-		input_report_abs(input, ABS_MT_PRESSURE, z);
-		input_report_abs(input, ABS_MT_TOUCH_MAJOR, w_max);
-		input_report_abs(input, ABS_MT_TOUCH_MINOR, w_min);
-		input_report_abs(input, ABS_MT_ORIENTATION, orient);
-		input_report_abs(input, ABS_MT_POSITION_X, x);
-		input_report_abs(input, ABS_MT_POSITION_Y, y);
+	obj->mt_tool = tool_type;
+	obj->x = (pos_data[0] << 4) | (pos_data[2] & 0x0F);
+	obj->y = (pos_data[1] << 4) | (pos_data[2] >> 4);
+	obj->z = pos_data[4];
+	obj->wx = pos_data[3] & 0x0f;
+	obj->wy = pos_data[3] >> 4;
 
-		dev_dbg(&sensor->fn->dev,
-			"finger[%d]:%d - x:%d y:%d z:%d w_max:%d w_min:%d\n",
-			n_finger, finger_state, x, y, z, w_max, w_min);
-	}
+	rmi_2d_sensor_abs_process(sensor, obj, n_finger);
 }
 
 static inline u8 rmi_f11_parse_finger_state(const u8 *f_state, u8 n_finger)
@@ -721,10 +589,10 @@ static inline u8 rmi_f11_parse_finger_state(const u8 *f_state, u8 n_finger)
 }
 
 static void rmi_f11_finger_handler(struct f11_data *f11,
-				   struct f11_2d_sensor *sensor,
+				   struct rmi_2d_sensor *sensor,
 				   unsigned long *irq_bits, int num_irq_regs)
 {
-	const u8 *f_state = sensor->data.f_state;
+	const u8 *f_state = f11->data.f_state;
 	u8 finger_state;
 	u8 i;
 
@@ -742,10 +610,11 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
 		}
 
 		if (abs_bits)
-			rmi_f11_abs_parse_xy(f11, sensor, finger_state, i);
+			rmi_f11_abs_pos_process(f11, sensor, &sensor->objs[i],
+							finger_state, i);
 
 		if (rel_bits)
-			rmi_f11_rel_pos_report(sensor, i);
+			rmi_f11_rel_pos_report(f11, i);
 	}
 
 	if (abs_bits) {
@@ -766,7 +635,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
 				/* no need to send twice the error */
 				continue;
 
-			rmi_f11_abs_pos_report(f11, sensor, finger_state, i);
+			rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i);
 		}
 
 		input_mt_sync_frame(sensor->input);
@@ -776,10 +645,11 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
 		input_sync(sensor->input);
 }
 
-static int f11_2d_construct_data(struct f11_2d_sensor *sensor)
+static int f11_2d_construct_data(struct f11_data *f11)
 {
-	struct f11_2d_sensor_queries *query = &sensor->sens_query;
-	struct f11_2d_data *data = &sensor->data;
+	struct rmi_2d_sensor *sensor = &f11->sensor;
+	struct f11_2d_sensor_queries *query = &f11->sens_query;
+	struct f11_2d_data *data = &f11->data;
 	int i;
 
 	sensor->nbr_fingers = (query->nr_fingers == 5 ? 10 :
@@ -1151,102 +1021,6 @@ static int rmi_f11_get_query_parameters(struct rmi_device *rmi_dev,
 	return query_size;
 }
 
-/* This operation is done in a number of places, so we have a handy routine
- * for it.
- */
-static void f11_set_abs_params(struct rmi_function *fn, struct f11_data *f11)
-{
-	struct f11_2d_sensor *sensor = &f11->sensor;
-	struct input_dev *input = sensor->input;
-	/* These two lines are not doing what we want them to.  So we use
-	 * some shifts instead.
-	int device_x_max = le16_to_cpu(*(f11->dev_controls.ctrl0_9 + 6));
-	int device_y_max = le16_to_cpu(*(f11->dev_controls.ctrl0_9 + 8));
-	 */
-	u16 device_x_max = f11->dev_controls.ctrl0_9[6] |
-			((f11->dev_controls.ctrl0_9[7] & 0x0F) << 8);
-	u16 device_y_max = f11->dev_controls.ctrl0_9[8] |
-			((f11->dev_controls.ctrl0_9[9] & 0x0F) << 8);
-	u16 x_min, x_max, y_min, y_max;
-	unsigned int input_flags;
-	int res_x, res_y;
-
-	/* We assume touchscreen unless demonstrably a touchpad or specified
-	 * as a touchpad in the platform data
-	 */
-	if (sensor->sensor_type == rmi_f11_sensor_touchpad)
-		input_flags = INPUT_MT_POINTER;
-	else
-		input_flags = INPUT_MT_DIRECT;
-
-	if (sensor->kernel_tracking)
-		input_flags |= INPUT_MT_TRACK;
-
-	if (sensor->axis_align.swap_axes) {
-		int temp = device_x_max;
-		device_x_max = device_y_max;
-		device_y_max = temp;
-	}
-	/* Use the max X and max Y read from the device, or the clip values,
-	 * whichever is stricter.
-	 */
-	x_min = sensor->axis_align.clip_x_low;
-	if (sensor->axis_align.clip_x_high)
-		x_max = min(device_x_max,
-			sensor->axis_align.clip_x_high);
-	else
-		x_max = device_x_max;
-
-	y_min = sensor->axis_align.clip_y_low;
-	if (sensor->axis_align.clip_y_high)
-		y_max = min(device_y_max,
-			sensor->axis_align.clip_y_high);
-	else
-		y_max = device_y_max;
-
-	dev_dbg(&fn->dev, "Set ranges X=[%d..%d] Y=[%d..%d].",
-			x_min, x_max, y_min, y_max);
-
-	input_set_abs_params(input, ABS_MT_PRESSURE, 0,
-			DEFAULT_MAX_ABS_MT_PRESSURE, 0, 0);
-	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
-			0, DEFAULT_MAX_ABS_MT_TOUCH, 0, 0);
-	input_set_abs_params(input, ABS_MT_TOUCH_MINOR,
-			0, DEFAULT_MAX_ABS_MT_TOUCH, 0, 0);
-	input_set_abs_params(input, ABS_MT_ORIENTATION,
-			0, DEFAULT_MAX_ABS_MT_ORIENTATION, 0, 0);
-	input_set_abs_params(input, ABS_MT_TRACKING_ID,
-			DEFAULT_MIN_ABS_MT_TRACKING_ID,
-			DEFAULT_MAX_ABS_MT_TRACKING_ID, 0, 0);
-	/* TODO get max_x_pos (and y) from control registers. */
-	input_set_abs_params(input, ABS_MT_POSITION_X,
-			x_min, x_max, 0, 0);
-	input_set_abs_params(input, ABS_MT_POSITION_Y,
-			y_min, y_max, 0, 0);
-
-	if (sensor->x_mm && sensor->y_mm) {
-		res_x = (x_max - x_min) / sensor->x_mm;
-		res_y = (y_max - y_min) / sensor->y_mm;
-
-		input_abs_set_res(input, ABS_X, res_x);
-		input_abs_set_res(input, ABS_Y, res_y);
-
-		input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
-		input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
-
-		if (!sensor->dmax)
-			sensor->dmax = DMAX * res_x;
-	}
-
-	input_mt_init_slots(input, sensor->nbr_fingers, input_flags);
-	if (IS_ENABLED(CONFIG_RMI4_F11_PEN) && sensor->sens_query.has_pen)
-		input_set_abs_params(input, ABS_MT_TOOL_TYPE,
-				     0, MT_TOOL_MAX, 0, 0);
-	else
-		input_set_abs_params(input, ABS_MT_TOOL_TYPE,
-				     0, MT_TOOL_FINGER, 0, 0);
-}
-
 static int rmi_f11_initialize(struct rmi_function *fn)
 {
 	struct rmi_device *rmi_dev = fn->rmi_dev;
@@ -1255,11 +1029,11 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 	u8 query_offset;
 	u16 query_base_addr;
 	u16 control_base_addr;
-	u16 max_x_pos, max_y_pos, temp;
+	u16 max_x_pos, max_y_pos;
 	int rc;
 	const struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
 	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
-	struct f11_2d_sensor *sensor;
+	struct rmi_2d_sensor *sensor;
 	u8 buf;
 	int mask_size;
 
@@ -1276,7 +1050,15 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 	if (!f11)
 		return -ENOMEM;
 
-	f11->rezero_wait_ms = pdata->f11_rezero_wait;
+	if (fn->dev.of_node) {
+		rc = rmi_2d_sensor_of_probe(&fn->dev, &f11->sensor_pdata);
+		if (rc)
+			return rc;
+	} else if (pdata->sensor_pdata) {
+		f11->sensor_pdata = *pdata->sensor_pdata;
+	}
+
+	f11->rezero_wait_ms = f11->sensor_pdata.rezero_wait;
 
 	f11->abs_mask = (unsigned long *)((char *)f11
 			+ sizeof(struct f11_data));
@@ -1306,7 +1088,7 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 	sensor->fn = fn;
 
 	rc = rmi_f11_get_query_parameters(rmi_dev, f11,
-			&sensor->sens_query, query_offset);
+			&f11->sens_query, query_offset);
 	if (rc < 0)
 		return rc;
 	query_offset += rc;
@@ -1319,46 +1101,44 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 		return rc;
 	}
 
-	if (sensor->sens_query.has_info2) {
-		if (sensor->sens_query.is_clear)
-			sensor->sensor_type = rmi_f11_sensor_touchscreen;
+	if (f11->sens_query.has_info2) {
+		if (f11->sens_query.is_clear)
+			f11->sensor.sensor_type = rmi_sensor_touchscreen;
 		else
-			sensor->sensor_type = rmi_f11_sensor_touchpad;
+			f11->sensor.sensor_type = rmi_sensor_touchpad;
 	}
 
-	sensor->report_abs = sensor->sens_query.has_abs;
-
-	if (pdata->f11_sensor_data) {
-		sensor->axis_align =
-			pdata->f11_sensor_data->axis_align;
-		sensor->topbuttonpad = pdata->f11_sensor_data->topbuttonpad;
-		sensor->kernel_tracking =
-			pdata->f11_sensor_data->kernel_tracking;
-		sensor->dmax = pdata->f11_sensor_data->dmax;
-
-		if (sensor->sens_query.has_physical_props) {
-			sensor->x_mm = sensor->sens_query.x_sensor_size_mm;
-			sensor->y_mm = sensor->sens_query.y_sensor_size_mm;
-		} else if (pdata->f11_sensor_data) {
-			sensor->x_mm = pdata->f11_sensor_data->x_mm;
-			sensor->y_mm = pdata->f11_sensor_data->y_mm;
-		}
+	sensor->report_abs = f11->sens_query.has_abs;
 
-		if (sensor->sensor_type == rmi_f11_sensor_default)
-			sensor->sensor_type =
-				pdata->f11_sensor_data->sensor_type;
+	sensor->axis_align =
+		f11->sensor_pdata.axis_align;
 
-		sensor->report_abs = sensor->report_abs
-			&& !(pdata->f11_sensor_data->disable_report_mask
-				& RMI_F11_DISABLE_ABS_REPORT);
+	sensor->topbuttonpad = f11->sensor_pdata.topbuttonpad;
+	sensor->kernel_tracking = f11->sensor_pdata.kernel_tracking;
+	sensor->dmax = f11->sensor_pdata.dmax;
+
+	if (f11->sens_query.has_physical_props) {
+		sensor->x_mm = f11->sens_query.x_sensor_size_mm;
+		sensor->y_mm = f11->sens_query.y_sensor_size_mm;
+	} else {
+		sensor->x_mm = f11->sensor_pdata.x_mm;
+		sensor->y_mm = f11->sensor_pdata.y_mm;
 	}
 
+	if (sensor->sensor_type == rmi_sensor_default)
+		sensor->sensor_type =
+			f11->sensor_pdata.sensor_type;
+
+	sensor->report_abs = sensor->report_abs
+		&& !(f11->sensor_pdata.disable_report_mask
+			& RMI_F11_DISABLE_ABS_REPORT);
+
 	if (!sensor->report_abs)
 		/*
 		 * If device doesn't have abs or if it has been disables
 		 * fallback to reporting rel data.
 		 */
-		sensor->report_rel = sensor->sens_query.has_rel;
+		sensor->report_rel = f11->sens_query.has_rel;
 
 	rc = rmi_read_block(rmi_dev,
 		control_base_addr + F11_CTRL_SENSOR_MAX_X_POS_OFFSET,
@@ -1372,15 +1152,13 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 	if (rc < 0)
 		return rc;
 
-	if (sensor->axis_align.swap_axes) {
-		temp = max_x_pos;
-		max_x_pos = max_y_pos;
-		max_y_pos = temp;
-	}
+	if (sensor->axis_align.swap_axes)
+		swap(max_x_pos, max_y_pos);
+
 	sensor->max_x = max_x_pos;
 	sensor->max_y = max_y_pos;
 
-	rc = f11_2d_construct_data(sensor);
+	rc = f11_2d_construct_data(f11);
 	if (rc < 0)
 		return rc;
 
@@ -1390,7 +1168,10 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 			GFP_KERNEL);
 	sensor->tracking_slots = devm_kzalloc(&fn->dev,
 			sizeof(int) * sensor->nbr_fingers, GFP_KERNEL);
-	if (!sensor->tracking_pos || !sensor->tracking_slots)
+	sensor->objs = devm_kzalloc(&fn->dev,
+			sizeof(struct rmi_2d_sensor_abs_object)
+			* sensor->nbr_fingers, GFP_KERNEL);
+	if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs)
 		return -ENOMEM;
 
 	ctrl = &f11->dev_controls;
@@ -1423,84 +1204,11 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 	return 0;
 }
 
-static int rmi_f11_register_devices(struct rmi_function *fn)
-{
-	struct rmi_device *rmi_dev = fn->rmi_dev;
-	struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
-	struct f11_data *f11 = dev_get_drvdata(&fn->dev);
-	struct input_dev *input_dev;
-	struct rmi_driver *driver = rmi_dev->driver;
-	struct f11_2d_sensor *sensor = &f11->sensor;
-	int rc;
-
-	if (!drv_data->input) {
-		input_dev = input_allocate_device();
-	} else {
-		input_dev = drv_data->input;
-		sensor->unified_input = true;
-	}
-	if (!input_dev) {
-		rc = -ENOMEM;
-		goto error_unregister;
-	}
-
-	sensor->input = input_dev;
-
-	if (!sensor->unified_input) {
-		if (driver->set_input_params) {
-			rc = driver->set_input_params(rmi_dev, input_dev);
-			if (rc < 0) {
-				dev_err(&fn->dev,
-					"%s: Error in setting input device.\n",
-					__func__);
-				goto error_unregister;
-			}
-		}
-		sprintf(sensor->input_phys, "%s.abs/input0",
-			dev_name(&fn->dev));
-		input_dev->phys = sensor->input_phys;
-		input_dev->dev.parent = &rmi_dev->dev;
-	}
-
-	set_bit(EV_ABS, input_dev->evbit);
-	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
-
-	if (sensor->report_abs)
-		f11_set_abs_params(fn, f11);
-
-	if (sensor->topbuttonpad)
-		set_bit(INPUT_PROP_TOPBUTTONPAD, input_dev->propbit);
-
-	if (sensor->report_rel) {
-		set_bit(EV_REL, input_dev->evbit);
-		set_bit(REL_X, input_dev->relbit);
-		set_bit(REL_Y, input_dev->relbit);
-	}
-	if (!sensor->unified_input) {
-		rc = input_register_device(input_dev);
-		if (rc) {
-			input_free_device(input_dev);
-			sensor->input = NULL;
-			goto error_unregister;
-		}
-	}
-
-	return 0;
-
-error_unregister:
-	if (!sensor->unified_input && sensor->input) {
-		input_unregister_device(sensor->input);
-		sensor->input = NULL;
-	}
-
-	return rc;
-}
-
 static int rmi_f11_config(struct rmi_function *fn)
 {
 	struct f11_data *f11 = dev_get_drvdata(&fn->dev);
 	struct rmi_driver *drv = fn->rmi_dev->driver;
-	struct f11_2d_sensor *sensor = &f11->sensor;
+	struct rmi_2d_sensor *sensor = &f11->sensor;
 	int rc;
 
 	if (!sensor->report_abs)
@@ -1513,7 +1221,7 @@ static int rmi_f11_config(struct rmi_function *fn)
 	else
 		drv->set_irq_bits(fn->rmi_dev, f11->rel_mask);
 
-	rc = f11_write_control_regs(fn, &f11->sensor.sens_query,
+	rc = f11_write_control_regs(fn, &f11->sens_query,
 			   &f11->dev_controls, fn->fd.query_base_addr);
 	if (rc < 0)
 		return rc;
@@ -1574,12 +1282,15 @@ static SIMPLE_DEV_PM_OPS(rmi_f11_pm_ops, NULL, rmi_f11_resume);
 static int rmi_f11_probe(struct rmi_function *fn)
 {
 	int error;
+	struct f11_data *f11;
+
 
 	error = rmi_f11_initialize(fn);
 	if (error)
 		return error;
 
-	error = rmi_f11_register_devices(fn);
+	f11 = dev_get_drvdata(&fn->dev);
+	error = rmi_2d_sensor_configure_input(fn, &f11->sensor);
 	if (error)
 		return error;
 
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index c781d09..0092787 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -32,7 +32,7 @@ enum rmi_attn_polarity {
 };
 
 /**
- * struct rmi_f11_axis_alignment - target axis alignment
+ * struct rmi_2d_axis_alignment - target axis alignment
  * @swap_axes: set to TRUE if desired to swap x- and y-axis
  * @flip_x: set to TRUE if desired to flip direction on x-axis
  * @flip_y: set to TRUE if desired to flip direction on y-axis
@@ -49,10 +49,10 @@ enum rmi_attn_polarity {
  * @rel_report_enabled - if set to true, the relative reporting will be
  *               automatically enabled for this sensor.
  */
-struct rmi_f11_2d_axis_alignment {
-	u32 swap_axes;	/* boolean, but u32 is needed by debugfs API */
-	u32 flip_x;	/* boolean */
-	u32 flip_y;	/* boolean */
+struct rmi_2d_axis_alignment {
+	bool swap_axes;
+	bool flip_x;
+	bool flip_y;
 	u16 clip_x_low;
 	u16 clip_y_low;
 	u16 clip_x_high;
@@ -73,16 +73,16 @@ struct rmi_f11_2d_axis_alignment {
  * @rmi_f11_sensor_touchpad - thread the sensor as a touchpad (indirect
  * pointing).
  */
-enum rmi_f11_sensor_type {
-	rmi_f11_sensor_default = 0,
-	rmi_f11_sensor_touchscreen,
-	rmi_f11_sensor_touchpad
+enum rmi_sensor_type {
+	rmi_sensor_default = 0,
+	rmi_sensor_touchscreen,
+	rmi_sensor_touchpad
 };
 
 #define RMI_F11_DISABLE_ABS_REPORT      BIT(0)
 
 /**
- * struct rmi_f11_sensor_data - overrides defaults for a single F11 2D sensor.
+ * struct rmi_2d_sensor_data - overrides defaults for a 2D sensor.
  * @axis_align - provides axis alignment overrides (see above).
  * @sensor_type - Forces the driver to treat the sensor as an indirect
  * pointing device (touchpad) rather than a direct pointing device
@@ -101,12 +101,13 @@ enum rmi_f11_sensor_type {
  * @dmax - the maximum distance (in sensor units) the kernel tracking allows two
  * distincts fingers to be considered the same.
  */
-struct rmi_f11_sensor_data {
-	struct rmi_f11_2d_axis_alignment axis_align;
-	enum rmi_f11_sensor_type sensor_type;
+struct rmi_2d_sensor_platform_data {
+	struct rmi_2d_axis_alignment axis_align;
+	enum rmi_sensor_type sensor_type;
 	int x_mm;
 	int y_mm;
 	int disable_report_mask;
+	u16 rezero_wait;
 	bool topbuttonpad;
 	bool kernel_tracking;
 	int dmax;
@@ -268,8 +269,7 @@ struct rmi_device_platform_data {
 	struct rmi_device_platform_data_spi spi_data;
 
 	/* function handler pdata */
-	struct rmi_f11_sensor_data *f11_sensor_data;
-	u16 f11_rezero_wait;
+	struct rmi_2d_sensor_platform_data *sensor_pdata;
 	struct rmi_f01_power_management power_management;
 	struct rmi_button_map *f19_button_map;
 	struct rmi_button_map *f1a_button_map;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ