// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2011-2015 Synaptics Incorporated * Copyright (c) 2011 Unixphere */ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/input.h> #include <linux/input/mt.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 … #define F11_MAX_NUM_OF_TOUCH_SHAPES … #define FINGER_STATE_MASK … #define F11_CTRL_SENSOR_MAX_X_POS_OFFSET … #define F11_CTRL_SENSOR_MAX_Y_POS_OFFSET … #define DEFAULT_XY_MAX … #define DEFAULT_MAX_ABS_MT_PRESSURE … #define DEFAULT_MAX_ABS_MT_TOUCH … #define DEFAULT_MAX_ABS_MT_ORIENTATION … #define DEFAULT_MIN_ABS_MT_TRACKING_ID … #define DEFAULT_MAX_ABS_MT_TRACKING_ID … /* * A note about RMI4 F11 register structure. * * The properties for a given sensor are described by its query registers. The * number of query registers and the layout of their contents are described by * the F11 device queries as well as the sensor query information. * * Similarly, each sensor has control registers that govern its behavior. The * size and layout of the control registers for a given sensor can be determined * by parsing that sensors query registers. * * And in a likewise fashion, each sensor has data registers where it reports * its touch data and other interesting stuff. The size and layout of a * sensors data registers must be determined by parsing its query registers. * * The short story is that we need to read and parse a lot of query * registers in order to determine the attributes of a sensor. Then * we need to use that data to compute the size of the control and data * registers for sensor. * * The end result is that we have a number of structs that aren't used to * directly generate the input events, but their size, location and contents * are critical to determining where the data we are interested in lives. * * At this time, the driver does not yet comprehend all possible F11 * configuration options, but it should be sufficient to cover 99% of RMI4 F11 * devices currently in the field. */ /* maximum ABS_MT_POSITION displacement (in mm) */ #define DMAX … /* * Writing this to the F11 command register will cause the sensor to * calibrate to the current capacitive state. */ #define RMI_F11_REZERO … #define RMI_F11_HAS_QUERY9 … #define RMI_F11_HAS_QUERY11 … #define RMI_F11_HAS_QUERY12 … #define RMI_F11_HAS_QUERY27 … #define RMI_F11_HAS_QUERY28 … /** Defs for Query 1 */ #define RMI_F11_NR_FINGERS_MASK … #define RMI_F11_HAS_REL … #define RMI_F11_HAS_ABS … #define RMI_F11_HAS_GESTURES … #define RMI_F11_HAS_SENSITIVITY_ADJ … #define RMI_F11_CONFIGURABLE … /** Defs for Query 2, 3, and 4. */ #define RMI_F11_NR_ELECTRODES_MASK … /** Defs for Query 5 */ #define RMI_F11_ABS_DATA_SIZE_MASK … #define RMI_F11_HAS_ANCHORED_FINGER … #define RMI_F11_HAS_ADJ_HYST … #define RMI_F11_HAS_DRIBBLE … #define RMI_F11_HAS_BENDING_CORRECTION … #define RMI_F11_HAS_LARGE_OBJECT_SUPPRESSION … #define RMI_F11_HAS_JITTER_FILTER … /** Defs for Query 7 */ #define RMI_F11_HAS_SINGLE_TAP … #define RMI_F11_HAS_TAP_AND_HOLD … #define RMI_F11_HAS_DOUBLE_TAP … #define RMI_F11_HAS_EARLY_TAP … #define RMI_F11_HAS_FLICK … #define RMI_F11_HAS_PRESS … #define RMI_F11_HAS_PINCH … #define RMI_F11_HAS_CHIRAL … /** Defs for Query 8 */ #define RMI_F11_HAS_PALM_DET … #define RMI_F11_HAS_ROTATE … #define RMI_F11_HAS_TOUCH_SHAPES … #define RMI_F11_HAS_SCROLL_ZONES … #define RMI_F11_HAS_INDIVIDUAL_SCROLL_ZONES … #define RMI_F11_HAS_MF_SCROLL … #define RMI_F11_HAS_MF_EDGE_MOTION … #define RMI_F11_HAS_MF_SCROLL_INERTIA … /** Defs for Query 9. */ #define RMI_F11_HAS_PEN … #define RMI_F11_HAS_PROXIMITY … #define RMI_F11_HAS_PALM_DET_SENSITIVITY … #define RMI_F11_HAS_SUPPRESS_ON_PALM_DETECT … #define RMI_F11_HAS_TWO_PEN_THRESHOLDS … #define RMI_F11_HAS_CONTACT_GEOMETRY … #define RMI_F11_HAS_PEN_HOVER_DISCRIMINATION … #define RMI_F11_HAS_PEN_FILTERS … /** Defs for Query 10. */ #define RMI_F11_NR_TOUCH_SHAPES_MASK … /** Defs for Query 11 */ #define RMI_F11_HAS_Z_TUNING … #define RMI_F11_HAS_ALGORITHM_SELECTION … #define RMI_F11_HAS_W_TUNING … #define RMI_F11_HAS_PITCH_INFO … #define RMI_F11_HAS_FINGER_SIZE … #define RMI_F11_HAS_SEGMENTATION_AGGRESSIVENESS … #define RMI_F11_HAS_XY_CLIP … #define RMI_F11_HAS_DRUMMING_FILTER … /** Defs for Query 12. */ #define RMI_F11_HAS_GAPLESS_FINGER … #define RMI_F11_HAS_GAPLESS_FINGER_TUNING … #define RMI_F11_HAS_8BIT_W … #define RMI_F11_HAS_ADJUSTABLE_MAPPING … #define RMI_F11_HAS_INFO2 … #define RMI_F11_HAS_PHYSICAL_PROPS … #define RMI_F11_HAS_FINGER_LIMIT … #define RMI_F11_HAS_LINEAR_COEFF … /** Defs for Query 13. */ #define RMI_F11_JITTER_WINDOW_MASK … #define RMI_F11_JITTER_FILTER_MASK … #define RMI_F11_JITTER_FILTER_SHIFT … /** Defs for Query 14. */ #define RMI_F11_LIGHT_CONTROL_MASK … #define RMI_F11_IS_CLEAR … #define RMI_F11_CLICKPAD_PROPS_MASK … #define RMI_F11_CLICKPAD_PROPS_SHIFT … #define RMI_F11_MOUSE_BUTTONS_MASK … #define RMI_F11_MOUSE_BUTTONS_SHIFT … #define RMI_F11_HAS_ADVANCED_GESTURES … #define RMI_F11_QUERY_SIZE … #define RMI_F11_QUERY_GESTURE_SIZE … #define F11_LIGHT_CTL_NONE … #define F11_LUXPAD … #define F11_DUAL_MODE … #define F11_NOT_CLICKPAD … #define F11_HINGED_CLICKPAD … #define F11_UNIFORM_CLICKPAD … /** * struct f11_2d_sensor_queries - describes sensor capabilities * * Query registers 1 through 4 are always present. * * @nr_fingers: describes the maximum number of fingers the 2-D sensor * supports. * @has_rel: the sensor supports relative motion reporting. * @has_abs: the sensor supports absolute poition reporting. * @has_gestures: the sensor supports gesture reporting. * @has_sensitivity_adjust: the sensor supports a global sensitivity * adjustment. * @configurable: the sensor supports various configuration options. * @nr_x_electrodes: the maximum number of electrodes the 2-D sensor * supports on the X axis. * @nr_y_electrodes: the maximum number of electrodes the 2-D sensor * supports on the Y axis. * @max_electrodes: the total number of X and Y electrodes that may be * configured. * * Query 5 is present if the has_abs bit is set. * * @abs_data_size: describes the format of data reported by the absolute * data source. Only one format (the kind used here) is supported at this * time. * @has_anchored_finger: then the sensor supports the high-precision second * finger tracking provided by the manual tracking and motion sensitivity * options. * @has_adj_hyst: the difference between the finger release threshold and * the touch threshold. * @has_dribble: the sensor supports the generation of dribble interrupts, * which may be enabled or disabled with the dribble control bit. * @has_bending_correction: Bending related data registers 28 and 36, and * control register 52..57 are present. * @has_large_object_suppression: control register 58 and data register 28 * exist. * @has_jitter_filter: query 13 and control 73..76 exist. * * Query 6 is present if the has_rel it is set. * * @f11_2d_query6: this register is reserved. * * Gesture information queries 7 and 8 are present if has_gestures bit is set. * * @has_single_tap: a basic single-tap gesture is supported. * @has_tap_n_hold: tap-and-hold gesture is supported. * @has_double_tap: double-tap gesture is supported. * @has_early_tap: early tap is supported and reported as soon as the finger * lifts for any tap event that could be interpreted as either a single * tap or as the first tap of a double-tap or tap-and-hold gesture. * @has_flick: flick detection is supported. * @has_press: press gesture reporting is supported. * @has_pinch: pinch gesture detection is supported. * @has_chiral: chiral (circular) scrolling gesture detection is supported. * @has_palm_det: the 2-D sensor notifies the host whenever a large conductive * object such as a palm or a cheek touches the 2-D sensor. * @has_rotate: rotation gesture detection is supported. * @has_touch_shapes: TouchShapes are supported. A TouchShape is a fixed * rectangular area on the sensor that behaves like a capacitive button. * @has_scroll_zones: scrolling areas near the sensor edges are supported. * @has_individual_scroll_zones: if 1, then 4 scroll zones are supported; * if 0, then only two are supported. * @has_mf_scroll: the multifinger_scrolling bit will be set when * more than one finger is involved in a scrolling action. * @has_mf_edge_motion: indicates whether multi-finger edge motion gesture * is supported. * @has_mf_scroll_inertia: indicates whether multi-finger scroll inertia * feature is supported. * * Convenience for checking bytes in the gesture info registers. This is done * often enough that we put it here to declutter the conditionals * * @query7_nonzero: true if none of the query 7 bits are set * @query8_nonzero: true if none of the query 8 bits are set * * Query 9 is present if the has_query9 is set. * * @has_pen: detection of a stylus is supported and registers F11_2D_Ctrl20 * and F11_2D_Ctrl21 exist. * @has_proximity: detection of fingers near the sensor is supported and * registers F11_2D_Ctrl22 through F11_2D_Ctrl26 exist. * @has_palm_det_sensitivity: the sensor supports the palm detect sensitivity * feature and register F11_2D_Ctrl27 exists. * @has_suppress_on_palm_detect: the device supports the large object detect * suppression feature and register F11_2D_Ctrl27 exists. * @has_two_pen_thresholds: if has_pen is also set, then F11_2D_Ctrl35 exists. * @has_contact_geometry: the sensor supports the use of contact geometry to * map absolute X and Y target positions and registers F11_2D_Data18 * through F11_2D_Data27 exist. * @has_pen_hover_discrimination: if has_pen is also set, then registers * F11_2D_Data29 through F11_2D_Data31, F11_2D_Ctrl68.*, F11_2D_Ctrl69 * and F11_2D_Ctrl72 exist. * @has_pen_filters: if has_pen is also set, then registers F11_2D_Ctrl70 and * F11_2D_Ctrl71 exist. * * Touch shape info (query 10) is present if has_touch_shapes is set. * * @nr_touch_shapes: the total number of touch shapes supported. * * Query 11 is present if the has_query11 bit is set in query 0. * * @has_z_tuning: if set, the sensor supports Z tuning and registers * F11_2D_Ctrl29 through F11_2D_Ctrl33 exist. * @has_algorithm_selection: controls choice of noise suppression algorithm * @has_w_tuning: the sensor supports Wx and Wy scaling and registers * F11_2D_Ctrl36 through F11_2D_Ctrl39 exist. * @has_pitch_info: the X and Y pitches of the sensor electrodes can be * configured and registers F11_2D_Ctrl40 and F11_2D_Ctrl41 exist. * @has_finger_size: the default finger width settings for the sensor * can be configured and registers F11_2D_Ctrl42 through F11_2D_Ctrl44 * exist. * @has_segmentation_aggressiveness: the sensor’s ability to distinguish * multiple objects close together can be configured and register * F11_2D_Ctrl45 exists. * @has_XY_clip: the inactive outside borders of the sensor can be * configured and registers F11_2D_Ctrl46 through F11_2D_Ctrl49 exist. * @has_drumming_filter: the sensor can be configured to distinguish * between a fast flick and a quick drumming movement and registers * F11_2D_Ctrl50 and F11_2D_Ctrl51 exist. * * Query 12 is present if hasQuery12 bit is set. * * @has_gapless_finger: control registers relating to gapless finger are * present. * @has_gapless_finger_tuning: additional control and data registers relating * to gapless finger are present. * @has_8bit_w: larger W value reporting is supported. * @has_adjustable_mapping: TBD * @has_info2: the general info query14 is present * @has_physical_props: additional queries describing the physical properties * of the sensor are present. * @has_finger_limit: indicates that F11 Ctrl 80 exists. * @has_linear_coeff_2: indicates that F11 Ctrl 81 exists. * * Query 13 is present if Query 5's has_jitter_filter bit is set. * * @jitter_window_size: used by Design Studio 4. * @jitter_filter_type: used by Design Studio 4. * * Query 14 is present if query 12's has_general_info2 flag is set. * * @light_control: Indicates what light/led control features are present, * if any. * @is_clear: if set, this is a clear sensor (indicating direct pointing * application), otherwise it's opaque (indicating indirect pointing). * @clickpad_props: specifies if this is a clickpad, and if so what sort of * mechanism it uses * @mouse_buttons: specifies the number of mouse buttons present (if any). * @has_advanced_gestures: advanced driver gestures are supported. * * @x_sensor_size_mm: size of the sensor in millimeters on the X axis. * @y_sensor_size_mm: size of the sensor in millimeters on the Y axis. */ struct f11_2d_sensor_queries { … }; /* Defs for Ctrl0. */ #define RMI_F11_REPORT_MODE_MASK … #define RMI_F11_REPORT_MODE_CONTINUOUS … #define RMI_F11_REPORT_MODE_REDUCED … #define RMI_F11_REPORT_MODE_FS_CHANGE … #define RMI_F11_REPORT_MODE_FP_CHANGE … #define RMI_F11_ABS_POS_FILT … #define RMI_F11_REL_POS_FILT … #define RMI_F11_REL_BALLISTICS … #define RMI_F11_DRIBBLE … #define RMI_F11_REPORT_BEYOND_CLIP … /* Defs for Ctrl1. */ #define RMI_F11_PALM_DETECT_THRESH_MASK … #define RMI_F11_MOTION_SENSITIVITY_MASK … #define RMI_F11_MANUAL_TRACKING … #define RMI_F11_MANUAL_TRACKED_FINGER … #define RMI_F11_DELTA_X_THRESHOLD … #define RMI_F11_DELTA_Y_THRESHOLD … #define RMI_F11_CTRL_REG_COUNT … struct f11_2d_ctrl { … }; #define RMI_F11_ABS_BYTES … #define RMI_F11_REL_BYTES … /* Defs for Data 8 */ #define RMI_F11_SINGLE_TAP … #define RMI_F11_TAP_AND_HOLD … #define RMI_F11_DOUBLE_TAP … #define RMI_F11_EARLY_TAP … #define RMI_F11_FLICK … #define RMI_F11_PRESS … #define RMI_F11_PINCH … /* Defs for Data 9 */ #define RMI_F11_PALM_DETECT … #define RMI_F11_ROTATE … #define RMI_F11_SHAPE … #define RMI_F11_SCROLLZONE … #define RMI_F11_GESTURE_FINGER_COUNT_MASK … /** Handy pointers into our data buffer. * * @f_state - start of finger state registers. * @abs_pos - start of absolute position registers (if present). * @rel_pos - start of relative data registers (if present). * @gest_1 - gesture flags (if present). * @gest_2 - gesture flags & finger count (if present). * @pinch - pinch motion register (if present). * @flick - flick distance X & Y, flick time (if present). * @rotate - rotate motion and finger separation. * @multi_scroll - chiral deltas for X and Y (if present). * @scroll_zones - scroll deltas for 4 regions (if present). */ struct f11_2d_data { … }; /** Data pertaining to F11 in general. For per-sensor data, see struct * f11_2d_sensor. * * @dev_query - F11 device specific query registers. * @dev_controls - F11 device specific control registers. * @dev_controls_mutex - lock for the control registers. * @rezero_wait_ms - if nonzero, upon resume we will wait this many * milliseconds before rezeroing the sensor(s). This is useful in systems with * poor electrical behavior on resume, where the initial calibration of the * sensor(s) coming out of sleep state may be bogus. * @sensors - per sensor data structures. */ struct f11_data { … }; enum f11_finger_state { … }; static void rmi_f11_rel_pos_report(struct f11_data *f11, u8 n_finger) { … } 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) { … } 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 rmi_2d_sensor *sensor, int size) { … } static int f11_2d_construct_data(struct f11_data *f11) { … } static int f11_read_control_regs(struct rmi_function *fn, struct f11_2d_ctrl *ctrl, u16 ctrl_base_addr) { … } static int f11_write_control_regs(struct rmi_function *fn, struct f11_2d_sensor_queries *query, struct f11_2d_ctrl *ctrl, u16 ctrl_base_addr) { … } static int rmi_f11_get_query_parameters(struct rmi_device *rmi_dev, struct f11_data *f11, struct f11_2d_sensor_queries *sensor_query, u16 query_base_addr) { … } static int rmi_f11_initialize(struct rmi_function *fn) { … } static int rmi_f11_config(struct rmi_function *fn) { … } static irqreturn_t rmi_f11_attention(int irq, void *ctx) { … } static int rmi_f11_resume(struct rmi_function *fn) { … } static int rmi_f11_probe(struct rmi_function *fn) { … } struct rmi_function_handler rmi_f11_handler = …;