/* * 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 10
/* * Writing this to the F11 command register will cause the sensor to * calibrate to the current capacitive state.
*/ #define RMI_F11_REZERO 0x01
/** * 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 { /* query1 */
u8 nr_fingers; bool has_rel; bool has_abs; bool has_gestures; bool has_sensitivity_adjust; bool configurable;
/** 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 {
u8 *f_state;
u8 *abs_pos;
s8 *rel_pos;
u8 *gest_1;
u8 *gest_2;
s8 *pinch;
u8 *flick;
u8 *rotate;
u8 *shapes;
s8 *multi_scroll;
s8 *scroll_zones;
};
/** 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 { bool has_query9; bool has_query11; bool has_query12; bool has_query27; bool has_query28; bool has_acm; struct f11_2d_ctrl dev_controls; struct mutex dev_controls_mutex;
u16 rezero_wait_ms; 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; unsignedlong *abs_mask; unsignedlong *rel_mask;
};
staticvoid rmi_f11_finger_handler(struct f11_data *f11, struct rmi_2d_sensor *sensor, int size)
{ const u8 *f_state = f11->data.f_state;
u8 finger_state;
u8 i; int abs_fingers; int rel_fingers; int abs_size = sensor->nbr_fingers * RMI_F11_ABS_BYTES;
if (sensor->report_abs) { if (abs_size > size)
abs_fingers = size / RMI_F11_ABS_BYTES; else
abs_fingers = sensor->nbr_fingers;
for (i = 0; i < abs_fingers; i++) { /* Possible of having 4 fingers per f_state register */
finger_state = rmi_f11_parse_finger_state(f_state, i); if (finger_state == F11_RESERVED) {
pr_err("Invalid finger state[%d]: 0x%02x", i,
finger_state); continue;
}
/* * the absolute part is made in 2 parts to allow the kernel * tracking to take place.
*/ if (sensor->kernel_tracking)
input_mt_assign_slots(sensor->input,
sensor->tracking_slots,
sensor->tracking_pos,
sensor->nbr_fingers,
sensor->dmax);
for (i = 0; i < abs_fingers; i++) {
finger_state = rmi_f11_parse_finger_state(f_state, i); if (finger_state == F11_RESERVED) /* no need to send twice the error */ continue;
if (!sensor->report_abs) /* * If device doesn't have abs or if it has been disables * fallback to reporting rel data.
*/
sensor->report_rel = f11->sens_query.has_rel;
ctrl = &f11->dev_controls; if (sensor->axis_align.delta_x_threshold)
ctrl->ctrl0_11[RMI_F11_DELTA_X_THRESHOLD] =
sensor->axis_align.delta_x_threshold;
if (sensor->axis_align.delta_y_threshold)
ctrl->ctrl0_11[RMI_F11_DELTA_Y_THRESHOLD] =
sensor->axis_align.delta_y_threshold;
/* * If distance threshold values are set, switch to reduced reporting * mode so they actually get used by the controller.
*/ if (sensor->axis_align.delta_x_threshold ||
sensor->axis_align.delta_y_threshold) {
ctrl->ctrl0_11[0] &= ~RMI_F11_REPORT_MODE_MASK;
ctrl->ctrl0_11[0] |= RMI_F11_REPORT_MODE_REDUCED;
}
if (f11->sens_query.has_dribble) { switch (sensor->dribble) { case RMI_REG_STATE_OFF:
ctrl->ctrl0_11[0] &= ~BIT(6); break; case RMI_REG_STATE_ON:
ctrl->ctrl0_11[0] |= BIT(6); break; case RMI_REG_STATE_DEFAULT: default: break;
}
}
if (f11->sens_query.has_palm_det) { switch (sensor->palm_detect) { case RMI_REG_STATE_OFF:
ctrl->ctrl0_11[11] &= ~BIT(0); break; case RMI_REG_STATE_ON:
ctrl->ctrl0_11[11] |= BIT(0); break; case RMI_REG_STATE_DEFAULT: default: break;
}
}
rc = f11_write_control_regs(fn, &f11->sens_query,
&f11->dev_controls, fn->fd.control_base_addr); if (rc)
dev_warn(&fn->dev, "Failed to write control registers\n");
if (drvdata->attn_data.data) { /* * The valid data in the attention report is less then * expected. Only process the complete fingers.
*/ if (f11->sensor.attn_size > drvdata->attn_data.size)
valid_bytes = drvdata->attn_data.size; else
valid_bytes = f11->sensor.attn_size;
memcpy(f11->sensor.data_pkt, drvdata->attn_data.data,
valid_bytes);
drvdata->attn_data.data += valid_bytes;
drvdata->attn_data.size -= valid_bytes;
} else {
error = rmi_read_block(rmi_dev,
data_base_addr, f11->sensor.data_pkt,
f11->sensor.pkt_size); if (error < 0) return IRQ_RETVAL(error);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.