diff options
Diffstat (limited to 'drivers/input/rmi4/rmi_f11.c')
-rw-r--r-- | drivers/input/rmi4/rmi_f11.c | 98 |
1 files changed, 74 insertions, 24 deletions
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c index 20c7134b3d3b..68279f3c5130 100644 --- a/drivers/input/rmi4/rmi_f11.c +++ b/drivers/input/rmi4/rmi_f11.c @@ -572,31 +572,48 @@ 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, - unsigned long *irq_bits, int num_irq_regs) + unsigned long *irq_bits, int num_irq_regs, + 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; int abs_bits = bitmap_and(f11->result_bits, irq_bits, f11->abs_mask, num_irq_regs * 8); int rel_bits = bitmap_and(f11->result_bits, irq_bits, f11->rel_mask, num_irq_regs * 8); - for (i = 0; i < sensor->nbr_fingers; i++) { - /* Possible of having 4 fingers per f_statet 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; - } + if (abs_bits) { + 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; + } - if (abs_bits) rmi_f11_abs_pos_process(f11, sensor, &sensor->objs[i], finger_state, i); + } + } + + if (rel_bits) { + if ((abs_size + sensor->nbr_fingers * RMI_F11_REL_BYTES) > size) + rel_fingers = (size - abs_size) / RMI_F11_REL_BYTES; + else + rel_fingers = sensor->nbr_fingers; - if (rel_bits) + for (i = 0; i < rel_fingers; i++) rmi_f11_rel_pos_report(f11, i); } @@ -612,7 +629,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11, sensor->nbr_fingers, sensor->dmax); - for (i = 0; i < sensor->nbr_fingers; i++) { + 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 */ @@ -1063,8 +1080,8 @@ static int rmi_f11_initialize(struct rmi_function *fn) 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; + } else { + f11->sensor_pdata = pdata->sensor_pdata; } f11->rezero_wait_ms = f11->sensor_pdata.rezero_wait; @@ -1125,6 +1142,8 @@ static int rmi_f11_initialize(struct rmi_function *fn) sensor->topbuttonpad = f11->sensor_pdata.topbuttonpad; sensor->kernel_tracking = f11->sensor_pdata.kernel_tracking; sensor->dmax = f11->sensor_pdata.dmax; + sensor->dribble = f11->sensor_pdata.dribble; + sensor->palm_detect = f11->sensor_pdata.palm_detect; if (f11->sens_query.has_physical_props) { sensor->x_mm = f11->sens_query.x_sensor_size_mm; @@ -1192,11 +1211,33 @@ static int rmi_f11_initialize(struct rmi_function *fn) ctrl->ctrl0_11[RMI_F11_DELTA_Y_THRESHOLD] = sensor->axis_align.delta_y_threshold; - if (f11->sens_query.has_dribble) - ctrl->ctrl0_11[0] = ctrl->ctrl0_11[0] & ~BIT(6); + 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) - ctrl->ctrl0_11[11] = ctrl->ctrl0_11[11] & ~BIT(0); + 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.query_base_addr); @@ -1242,12 +1283,21 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits) struct f11_data *f11 = dev_get_drvdata(&fn->dev); u16 data_base_addr = fn->fd.data_base_addr; int error; + int valid_bytes = f11->sensor.pkt_size; - if (rmi_dev->xport->attn_data) { - memcpy(f11->sensor.data_pkt, rmi_dev->xport->attn_data, - f11->sensor.attn_size); - rmi_dev->xport->attn_data += f11->sensor.attn_size; - rmi_dev->xport->attn_size -= f11->sensor.attn_size; + 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 += f11->sensor.attn_size; + drvdata->attn_data.size -= f11->sensor.attn_size; } else { error = rmi_read_block(rmi_dev, data_base_addr, f11->sensor.data_pkt, @@ -1257,7 +1307,7 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits) } rmi_f11_finger_handler(f11, &f11->sensor, irq_bits, - drvdata->num_of_irq_regs); + drvdata->num_of_irq_regs, valid_bytes); return 0; } |