Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 323425
b: refs/heads/master
c: 3e1b501
h: refs/heads/master
i:
  323423: a3250b5
v: v3
  • Loading branch information
Henrik Rydberg committed Sep 19, 2012
1 parent eb1773d commit b89186c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 66 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 76f5902aebdabcac5b1c34b8d9a238bad397364f
refs/heads/master: 3e1b5015d94ec0bdfa5bd8c80a19bcba82bc505c
88 changes: 23 additions & 65 deletions trunk/drivers/hid/hid-multitouch.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ struct mt_slot {
__s32 x, y, p, w, h;
__s32 contactid; /* the device ContactID assigned to this slot */
bool touch_state; /* is the touch valid? */
bool seen_in_this_frame;/* has this slot been updated */
};

struct mt_class {
Expand Down Expand Up @@ -94,7 +93,6 @@ struct mt_device {
* > 1 means hybrid (multitouch) protocol */
bool serial_maybe; /* need to check for serial protocol */
bool curvalid; /* is the current contact valid? */
struct mt_slot *slots;
unsigned mt_flags; /* flags to pass to input-mt */
};

Expand Down Expand Up @@ -136,25 +134,6 @@ static int cypress_compute_slot(struct mt_device *td)
return -1;
}

static int find_slot_from_contactid(struct mt_device *td)
{
int i;
for (i = 0; i < td->maxcontacts; ++i) {
if (td->slots[i].contactid == td->curdata.contactid &&
td->slots[i].touch_state)
return i;
}
for (i = 0; i < td->maxcontacts; ++i) {
if (!td->slots[i].seen_in_this_frame &&
!td->slots[i].touch_state)
return i;
}
/* should not occurs. If this happens that means
* that the device sent more touches that it says
* in the report descriptor. It is ignored then. */
return -1;
}

static struct mt_class mt_classes[] = {
{ .name = MT_CLS_DEFAULT,
.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
Expand Down Expand Up @@ -448,7 +427,7 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
return -1;
}

static int mt_compute_slot(struct mt_device *td)
static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
{
__s32 quirks = td->mtclass.quirks;

Expand All @@ -464,42 +443,23 @@ static int mt_compute_slot(struct mt_device *td)
if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
return td->curdata.contactid - 1;

return find_slot_from_contactid(td);
return input_mt_get_slot_by_key(input, td->curdata.contactid);
}

/*
* this function is called when a whole contact has been processed,
* so that it can assign it to a slot and store the data there
*/
static void mt_complete_slot(struct mt_device *td)
static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
{
td->curdata.seen_in_this_frame = true;
if (td->curvalid) {
int slotnum = mt_compute_slot(td);

if (slotnum >= 0 && slotnum < td->maxcontacts)
td->slots[slotnum] = td->curdata;
}
td->num_received++;
}


/*
* this function is called when a whole packet has been received and processed,
* so that it can decide what to send to the input layer.
*/
static void mt_emit_event(struct mt_device *td, struct input_dev *input)
{
int i;
int slotnum = mt_compute_slot(td, input);
struct mt_slot *s = &td->curdata;

for (i = 0; i < td->maxcontacts; ++i) {
struct mt_slot *s = &(td->slots[i]);
if ((td->mtclass.quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
!s->seen_in_this_frame) {
s->touch_state = false;
}
if (slotnum < 0 || slotnum >= td->maxcontacts)
return;

input_mt_slot(input, i);
input_mt_slot(input, slotnum);
input_mt_report_slot_state(input, MT_TOOL_FINGER,
s->touch_state);
if (s->touch_state) {
Expand All @@ -516,24 +476,29 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input)
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
}
s->seen_in_this_frame = false;

}

td->num_received++;
}

/*
* this function is called when a whole packet has been received and processed,
* so that it can decide what to send to the input layer.
*/
static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
{
input_mt_sync_frame(input);
input_sync(input);
td->num_received = 0;
}



static int mt_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
struct mt_device *td = hid_get_drvdata(hid);
__s32 quirks = td->mtclass.quirks;

if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
if (hid->claimed & HID_CLAIMED_INPUT) {
switch (usage->hid) {
case HID_DG_INRANGE:
if (quirks & MT_QUIRK_ALWAYS_VALID)
Expand Down Expand Up @@ -586,11 +551,11 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
}

if (usage->hid == td->last_slot_field)
mt_complete_slot(td);
mt_complete_slot(td, field->hidinput->input);

if (field->index == td->last_field_index
&& td->num_received >= td->num_expected)
mt_emit_event(td, field->hidinput->input);
mt_sync_frame(td, field->hidinput->input);

}

Expand Down Expand Up @@ -690,6 +655,9 @@ static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
if (cls->is_indirect)
td->mt_flags |= INPUT_MT_POINTER;

if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
td->mt_flags |= INPUT_MT_DROP_UNUSED;

input_mt_init_slots(input, td->maxcontacts, td->mt_flags);

td->mt_flags = 0;
Expand Down Expand Up @@ -743,15 +711,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (ret)
goto fail;

td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
GFP_KERNEL);
if (!td->slots) {
dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
hid_hw_stop(hdev);
ret = -ENOMEM;
goto fail;
}

ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);

mt_set_maxcontacts(hdev);
Expand Down Expand Up @@ -782,7 +741,6 @@ static void mt_remove(struct hid_device *hdev)
struct mt_device *td = hid_get_drvdata(hdev);
sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
hid_hw_stop(hdev);
kfree(td->slots);
kfree(td);
hid_set_drvdata(hdev, NULL);
}
Expand Down

0 comments on commit b89186c

Please sign in to comment.