|
@@ -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 */
|
|
@@ -1242,10 +1259,19 @@ 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) {
|
|
|
+ /*
|
|
|
+ * The valid data in the attention report is less then
|
|
|
+ * expected. Only process the complete fingers.
|
|
|
+ */
|
|
|
+ if (f11->sensor.attn_size > rmi_dev->xport->attn_size)
|
|
|
+ valid_bytes = rmi_dev->xport->attn_size;
|
|
|
+ else
|
|
|
+ valid_bytes = f11->sensor.attn_size;
|
|
|
memcpy(f11->sensor.data_pkt, rmi_dev->xport->attn_data,
|
|
|
- f11->sensor.attn_size);
|
|
|
+ valid_bytes);
|
|
|
rmi_dev->xport->attn_data += f11->sensor.attn_size;
|
|
|
rmi_dev->xport->attn_size -= f11->sensor.attn_size;
|
|
|
} else {
|
|
@@ -1257,7 +1283,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;
|
|
|
}
|