Re: [PATCH 4/4] input: wacom - add 0xE5 (MT device) support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Dec 28, 2011 at 1:48 PM, Chris Bagwell <chris@xxxxxxxxxxxxxx> wrote:
> On Tue, Dec 27, 2011 at 6:48 PM, Ping Cheng <pinglinux@xxxxxxxxx> wrote:
>> On Wed, Dec 21, 2011 at 8:14 PM, Chris Bagwell <chris@xxxxxxxxxxxxxx> wrote:
>>>
>>> On Wed, Dec 21, 2011 at 12:43 PM, Ping Cheng <pinglinux@xxxxxxxxx> wrote:
>>> > On Sun, Dec 18, 2011 at 6:07 PM, Chris Bagwell <chris@xxxxxxxxxxxxxx> wrote:
>>> >>
>>> >> On Fri, Dec 16, 2011 at 6:38 PM, Ping Cheng <pinglinux@xxxxxxxxx> wrote:
>>> >> > Signed-off-by: Ping Cheng <pingc@xxxxxxxxx>
>>> >> > ---
>>> >> >  drivers/input/tablet/wacom_sys.c |   26 ++++++------
>>> >> >  drivers/input/tablet/wacom_wac.c |   82
>>> >> > +++++++++++++++++++++++++++++++++++++-
>>> >> >  drivers/input/tablet/wacom_wac.h |    8 ++++
>>> >> >  3 files changed, 101 insertions(+), 15 deletions(-)
>>> >> >
>>> >> > diff --git a/drivers/input/tablet/wacom_sys.c
>>> >> > b/drivers/input/tablet/wacom_sys.c
>>> >> > index b9736fb..eee06ef 100644
>>> >> > --- a/drivers/input/tablet/wacom_sys.c
>>> >> > +++ b/drivers/input/tablet/wacom_sys.c
>>> >> > @@ -297,6 +297,10 @@ static int wacom_parse_hid(struct usb_interface
>>> >> > *intf,
>>> >> >                                                        features->pktlen
>>> >> > = WACOM_PKGLEN_TPC2FG;
>>> >> >
>>> >> >  features->touch_max = 2;
>>> >> >                                                }
>>> >> > +
>>> >> > +                                               if (features->type ==
>>> >> > MTSCREEN)
>>> >> > +                                                       features->pktlen
>>> >> > = WACOM_PKGLEN_MTOUCH;
>>> >> > +
>>> >> >                                                if (features->type ==
>>> >> > BAMBOO_PT) {
>>> >> >                                                        /* need to reset
>>> >> > back */
>>> >> >                                                        features->pktlen
>>> >> > = WACOM_PKGLEN_BBTOUCH;
>>> >> > @@ -331,18 +335,15 @@ static int wacom_parse_hid(struct usb_interface
>>> >> > *intf,
>>> >> >                        case HID_USAGE_Y:
>>> >> >                                if (usage == WCM_DESKTOP) {
>>> >> >                                        if (finger) {
>>> >> > -                                               features->device_type =
>>> >> > BTN_TOOL_FINGER;
>>> >> > -                                               if (features->type ==
>>> >> > TABLETPC2FG) {
>>> >> > -                                                       /* need to reset
>>> >> > back */
>>> >> > -                                                       features->pktlen
>>> >> > = WACOM_PKGLEN_TPC2FG;
>>> >> > +                                               int type =
>>> >> > features->type;
>>> >> > +
>>> >> > +                                               if (type == TABLETPC2FG
>>> >> > || type == MTSCREEN) {
>>> >> >                                                        features->y_max =
>>> >> >
>>> >> >  get_unaligned_le16(&report[i + 3]);
>>> >> >                                                        features->y_phy =
>>> >> >
>>> >> >  get_unaligned_le16(&report[i + 6]);
>>> >> >                                                        i += 7;
>>> >> > -                                               } else if
>>> >> > (features->type == BAMBOO_PT) {
>>> >> > -                                                       /* need to reset
>>> >> > back */
>>> >> > -                                                       features->pktlen
>>> >> > = WACOM_PKGLEN_BBTOUCH;
>>> >> > +                                               } else if (type ==
>>> >> > BAMBOO_PT) {
>>> >> >                                                        features->y_phy =
>>> >> >
>>> >> >  get_unaligned_le16(&report[i + 3]);distracted me.
>>> >> >                                                        features->y_max =
>>> >> > @@ -356,10 +357,6 @@ static int wacom_parse_hid(struct usb_interface
>>> >> > *intf,
>>> >> >                                                        i += 4;
>>> >> >                                                }
>>> >> >                                        } else if (pen) {
>>> >> > -                                               /* penabled only accepts
>>> >> > exact bytes of data */
>>> >> > -                                               if (features->type ==
>>> >> > TABLETPC2FG)
>>> >> > -                                                       features->pktlen
>>> >> > = WACOM_PKGLEN_GRAPHIRE;
>>> >> > -                                               features->device_type =
>>> >> > BTN_TOOL_PEN;
>>> >>
>>> >> All makes sense.  Getting rid of duplicate code since X/Y will always
>>> >> be present.  Maybe worth a 1 line comment now that its cleaned up so
>>> >> someone doesn't let it creep back in.
>>> >
>>> >
>>> > I'll add some comments in v2.
>>> >
>>> >>
>>> >> >                                                features->y_max =
>>> >> >
>>> >> >  get_unaligned_le16(&report[i + 3]);
>>> >> >                                                i += 4;
>>> >> > @@ -432,7 +429,8 @@ static int wacom_query_tablet_data(struct
>>> >> > usb_interface *intf, struct wacom_feat
>>> >> >
>>> >> >        /* ask to report tablet data if it is MT Tablet PC or
>>> >> >         * not a Tablet PC */
>>> >> > -       if (features->type == TABLETPC2FG) {
>>> >> > +       if (((features->type == TABLETPC2FG) || (features->type ==
>>> >> > MTSCREEN))
>>> >> > +                       && features->device_type != BTN_TOOL_PEN) {
>>> >>
>>> >> Glad to see this device_type check.  I thought it was probably needed.
>>> >>
>>> >> I'll have to trust you on this one but its different than Bamboo's.
>>> >> The set on Bamboo is on Pen and causes it to start sending pen
>>> >> packets.  IIR, the touch packets are always sending.  So this is
>>> >> opposite and enables something related to touch?
>>> >
>>> >
>>> > There are two types' of devices: tabletPC or non-tabletPC. For all tabletPC
>>> > devices that support more than one finger/contact, a set call is needed. For
>>> > all non-tabletPC devices, a set call is needed. Bamboo is a non-tabletPC
>>> > device.
>>> >
>>> >>
>>> >> Assuming you say yes, do you mind changing that to an affirmative
>>> >> check for TOUCH so it reads:
>>> >
>>> >
>>> > Well, it does not depend on whether it is touch or pen. It depends on the
>>> > type of the device as explained above. Do you still want me to use your
>>> > below logic?
>>>
>>> Let me ask this way.  On Bamboo there are 2 interfaces, 1 pen and 1
>>> touch.  I need to set feature report 2 to a specific value on the pen
>>> interface to get useful packets.  If I set feature report 2 to
>>> something on touch interface, I get an error response back from
>>> device.  This aligns with HID descriptor because only the pen
>>> interface declares that feature report #2.
>>>
>>> I'm sure its similar for Tablet PC's.   Its also writing to feature
>>> report #2 but unique data values. What ever the values are, it
>>> probably also doesn't make sense to write to both pen interface and
>>> touch interface on Tablet PC.
>>>
>>> If the feature report is only on one of two interfaces I do suggest
>>> changing the if() to something like below to make it more obvious ("if
>>> (TOUCH)" is more obvious that your looking for specific interface then
>>> "if (!PEN)").  If its on both and only 1 needs to be written to then
>>> that would probably be a good comment as well.
>>
>> I see your point. I'll use TOUCH/PEN for the if-statement and add a comment.
>>
>
> Thanks.
>
>>> >>
>>> >>  if (TOUCH)
>>> >>    /* do TOUCH set's */
>>> >>  if (PEN)
>>> >>    /* do PEN set's */
>>> >>
>>> >>
>>> >> >                do {
>>> >> >                        rep_data[0] = 3;
>>> >> >                        rep_data[1] = 4;
>>> >> > @@ -479,9 +477,9 @@ static int wacom_retrieve_hid_descriptor(struct
>>> >> > usb_interface *intf,
>>> >> >        features->pressure_fuzz = 0;
>>> >> >        features->distance_fuzz = 0;
>>> >> >
>>> >> > -       /* only Tablet PCs and Bamboo P&T need to retrieve the info */
>>> >> > +       /* only devices that support touch need to retrieve the info */
>>> >> >        if ((features->type != TABLETPC) && (features->type !=
>>> >> > TABLETPC2FG) &&
>>> >> > -           (features->type != BAMBOO_PT))
>>> >> > +           (features->type != BAMBOO_PT) && (features->type !=
>>> >> > MTSCREEN))
>>> >> >                goto out;
>>> >> >
>>> >> >        if (usb_get_extra_descriptor(interface, HID_DEVICET_HID,
>>> >> > &hid_desc)) {
>>> >> > diff --git a/drivers/input/tablet/wacom_wac.c
>>> >> > b/drivers/input/tablet/wacom_wac.c
>>> >> > index 8dc185d..1a887a1 100644
>>> >> > --- a/drivers/input/tablet/wacom_wac.c
>>> >> > +++ b/drivers/input/tablet/wacom_wac.c
>>> >> > @@ -729,6 +729,73 @@ static int wacom_intuos_irq(struct wacom_wac
>>> >> > *wacom)
>>> >> >        return 1;
>>> >> >  }
>>> >> >
>>> >> > +static int wacom_mt_touch(struct wacom_wac *wacom)
>>> >> > +{
>>> >> > +       struct wacom_features *features = &wacom->features;
>>> >> > +       struct input_dev *input = wacom->input;
>>> >> > +       char *data = wacom->data;
>>> >> > +       struct input_mt_slot *mt;
>>> >> > +       int i, id = -1, j = 0, k = 4;
>>> >> > +       int x = 0, y = 0;
>>> >> > +       int current_num_contacts = data[2];
>>> >> > +       int contacts_to_send = 0;
>>> >> > +       bool touch = false;
>>> >> > +
>>> >> > +       /* reset the counter by the first packet */
>>> >> > +       if (current_num_contacts) {
>>> >> > +               features->num_contacts = current_num_contacts;
>>> >> > +               features->num_contacts_left = current_num_contacts;
>>> >> > +       }
>>> >>
>>> >> It seems that the saved contact values are only processed in case were
>>> >> data[2] indicates no contact counts in packet.  I would think that
>>> >> packets with no contacts could be ignored (return) unless there is
>>> >> some data that must be implied.  Why is it not ignored?
>>> >
>>> >
>>> > current_num_contacts is only reported, hence updated, by the first set of
>>> > data. Later touch data will be processed as long as number of contacts does
>>> > not exceed current_num_contacts.
>>> >
>>> >>
>>> >>
>>> >> > +
>>> >> > +       /* There are at most 5 contacts per packet */
>>> >> > +       contacts_to_send = min(5, (int)features->num_contacts_left);
>>> >>
>>> >> Its not obvious to me if data[2] contains touches in packet or total
>>> >> touches on screen.
>>> >
>>> >
>>> > Total touches on the screen.
>>>
>>> OK.  I understand now.  It would be nice to add that to above comment
>>> (the fact that num_contacts_left is total on screen).
>>
>> num_contacts_left is normally not the total on the screen. It is the
>> number of contacts that need to be processed. num_contacts is the
>> total on the screen. contacts_to_send is the number of contacts we are
>> going to send.
>
> OK.  With understanding that data[2] is # of touches in packet and not
> total touches on screen then my questions change slightly.
>
> I assume if user put 6 touches a screen and moves around you'd get 2
> packets with movement; 1 with data[2] == 5 and 1 with data[2] == 1.
> There is this code then:
>
> int current_num_contacts = data[2];
> if (current_num_contacts) {
>    features->num_contacts = current_num_contacts;
>    features->num_contacts_left = current_num_contacts;
> }
>
> So it seems to me that num_contacts can never reach 6 (total touches
> on screen).  Maybe that needs to be a += or something?

I get it now.  In first touch packet received, data[2] will contain
the total touches to be reported.  There will (data[2] / 5) additional
packets following this packet and they will all have data[2] set to 0.

So I understand how your logic is meant to work with that firmware
behaviour.  If you could throw in something about data[2] == 0 being a
continuation packet then I think it would help future readers.

So that wraps up all the concerns/questions/comments I had on the patches.

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux