From: Benjamin Tissoires <benjamin.tissoires@enac.fr>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
Henrik Rydberg <rydberg@euromail.se>,
Benjamin Tissoires <benjamin.tissoires@enac.fr>,
Jiri Kosina <jkosina@suse.cz>,
Stephane Chatty <chatty@lii-enac.fr>,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 1/5] hid-multitouch: Auto detection of maxcontacts
Date: Fri, 18 Mar 2011 14:27:52 +0100 [thread overview]
Message-ID: <1300454876-5017-2-git-send-email-benjamin.tissoires@enac.fr> (raw)
In-Reply-To: <1300454876-5017-1-git-send-email-benjamin.tissoires@enac.fr>
This patch enables support of autodetection of maxcontacts.
When adding support for a new device, one is now able to let
the device tell how many contacts it supports, or to manually
set the value if the device happens to provide wrong information.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
Reviewed-by: Stéphane Chatty <chatty@enac.fr>
---
changes since v2:
* reverted "if (td->mtclass->maxcontacts)" test
* reverted MT_DEFAULT_MAXCONTACT
* add a test on td->slots before kzalloc
* remove device in case td->slots was not allocated
drivers/hid/hid-multitouch.c | 52 +++++++++++++++++++++++++++++------------
1 files changed, 37 insertions(+), 15 deletions(-)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index ee01e65..b9f9eec 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -60,8 +60,9 @@ struct mt_device {
__s8 inputmode; /* InputMode HID feature, -1 if non-existent */
__u8 num_received; /* how many contacts we received */
__u8 num_expected; /* expected last contact index */
+ __u8 maxcontacts;
bool curvalid; /* is the current contact valid? */
- struct mt_slot slots[0]; /* first slot */
+ struct mt_slot *slots;
};
struct mt_class {
@@ -79,6 +80,8 @@ struct mt_class {
#define MT_CLS_CYPRESS 4
#define MT_CLS_EGALAX 5
+#define MT_DEFAULT_MAXCONTACT 10
+
/*
* these device-dependent functions determine what slot corresponds
* to a valid contact that was just read.
@@ -95,12 +98,12 @@ static int cypress_compute_slot(struct mt_device *td)
static int find_slot_from_contactid(struct mt_device *td)
{
int i;
- for (i = 0; i < td->mtclass->maxcontacts; ++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->mtclass->maxcontacts; ++i) {
+ for (i = 0; i < td->maxcontacts; ++i) {
if (!td->slots[i].seen_in_this_frame &&
!td->slots[i].touch_state)
return i;
@@ -113,8 +116,7 @@ static int find_slot_from_contactid(struct mt_device *td)
struct mt_class mt_classes[] = {
{ .name = MT_CLS_DEFAULT,
- .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
- .maxcontacts = 10 },
+ .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
{ .name = MT_CLS_DUAL_INRANGE_CONTACTID,
.quirks = MT_QUIRK_VALID_IS_INRANGE |
MT_QUIRK_SLOT_IS_CONTACTID,
@@ -142,9 +144,19 @@ struct mt_class mt_classes[] = {
static void mt_feature_mapping(struct hid_device *hdev,
struct hid_field *field, struct hid_usage *usage)
{
- if (usage->hid == HID_DG_INPUTMODE) {
- struct mt_device *td = hid_get_drvdata(hdev);
+ struct mt_device *td = hid_get_drvdata(hdev);
+
+ switch (usage->hid) {
+ case HID_DG_INPUTMODE:
td->inputmode = field->report->id;
+ break;
+ case HID_DG_CONTACTMAX:
+ td->maxcontacts = field->value[0];
+ if (td->mtclass->maxcontacts)
+ /* check if the maxcontacts is given by the class */
+ td->maxcontacts = td->mtclass->maxcontacts;
+
+ break;
}
}
@@ -208,8 +220,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
td->last_slot_field = usage->hid;
return 1;
case HID_DG_CONTACTID:
- input_mt_init_slots(hi->input,
- td->mtclass->maxcontacts);
+ input_mt_init_slots(hi->input, td->maxcontacts);
td->last_slot_field = usage->hid;
return 1;
case HID_DG_WIDTH:
@@ -292,7 +303,7 @@ static void mt_complete_slot(struct mt_device *td)
if (td->curvalid) {
int slotnum = mt_compute_slot(td);
- if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts)
+ if (slotnum >= 0 && slotnum < td->maxcontacts)
td->slots[slotnum] = td->curdata;
}
td->num_received++;
@@ -307,7 +318,7 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input)
{
int i;
- for (i = 0; i < td->mtclass->maxcontacts; ++i) {
+ 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) {
@@ -341,7 +352,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
struct mt_device *td = hid_get_drvdata(hid);
__s32 quirks = td->mtclass->quirks;
- if (hid->claimed & HID_CLAIMED_INPUT) {
+ if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
switch (usage->hid) {
case HID_DG_INRANGE:
if (quirks & MT_QUIRK_VALID_IS_INRANGE)
@@ -442,9 +453,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
*/
hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
- td = kzalloc(sizeof(struct mt_device) +
- mtclass->maxcontacts * sizeof(struct mt_slot),
- GFP_KERNEL);
+ td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
if (!td) {
dev_err(&hdev->dev, "cannot allocate multitouch data\n");
return -ENOMEM;
@@ -461,6 +470,18 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (ret)
goto fail;
+ if (!td->maxcontacts)
+ td->maxcontacts = MT_DEFAULT_MAXCONTACT;
+
+ 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;
+ }
+
mt_set_input_mode(hdev);
return 0;
@@ -482,6 +503,7 @@ static void mt_remove(struct hid_device *hdev)
{
struct mt_device *td = hid_get_drvdata(hdev);
hid_hw_stop(hdev);
+ kfree(td->slots);
kfree(td);
hid_set_drvdata(hdev, NULL);
}
--
1.7.4
next prev parent reply other threads:[~2011-03-18 13:27 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-18 13:27 [PATCH 0/5] Migrations to hid-multitouch, round 3 Benjamin Tissoires
2011-03-18 13:27 ` Benjamin Tissoires [this message]
2011-03-21 8:47 ` [PATCH v3 1/5] hid-multitouch: Auto detection of maxcontacts Henrik Rydberg
2011-03-18 13:27 ` [PATCH v3 2/5] hid-multitouch: migrate support for Stantum panels to the unified driver Benjamin Tissoires
2011-03-21 8:49 ` Henrik Rydberg
2011-03-18 13:27 ` [PATCH v3 3/5] hid-multitouch: migrate Cando dual touch panels to hid-multitouch Benjamin Tissoires
2011-03-21 8:50 ` Henrik Rydberg
2011-03-18 13:27 ` [PATCH v3 4/5] hid-multitouch: refactor initialization of ABS_MT_ORIENTATION Benjamin Tissoires
2011-03-21 9:02 ` Henrik Rydberg
2011-03-21 13:32 ` Benjamin Tissoires
2011-03-21 13:50 ` Henrik Rydberg
2011-03-18 13:27 ` [PATCH v3 5/5] hid-multitouch: migrate 3M PCT touch screens to hid-multitouch Benjamin Tissoires
2011-03-21 9:05 ` Henrik Rydberg
2011-03-21 10:13 ` Benjamin Tissoires
2011-03-21 10:34 ` Henrik Rydberg
2011-03-21 19:06 ` Henrik Rydberg
2011-03-21 19:56 ` Benjamin Tissoires
2011-03-22 16:34 ` [PATCH v4] " Benjamin Tissoires
2011-03-22 16:58 ` Henrik Rydberg
2011-03-24 11:46 ` Jiri Kosina
2011-03-21 16:09 ` [PATCH 0/5] Migrations to hid-multitouch, round 3 Jiri Kosina
2011-03-21 18:22 ` Henrik Rydberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1300454876-5017-2-git-send-email-benjamin.tissoires@enac.fr \
--to=benjamin.tissoires@enac.fr \
--cc=chatty@lii-enac.fr \
--cc=dmitry.torokhov@gmail.com \
--cc=jkosina@suse.cz \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rydberg@euromail.se \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®