On Mon, Aug 25, 2014 at 10:48 AM, Christian Gmeiner <christian.gmeiner@xxxxxxxxx> wrote: > This driver is a cleaned up version of > http://git.android-x86.org/?p=kernel/cdv.git;a=blob_plain;f=drivers/hid/hid-penmount.c;hb=HEAD This is definitively weird. According to your driver, it should go by default through hid-multitouch and behave correctly (at least the multi-touch versions, and I would say yours too). Can you send me some touch recordings of your device with hid-recorder[1] please? No need to remove your driver, it will capture raw input events, so you should be just fine. If the default binding does not work and if we can not make this work through hid-multitouch, then I'll have some comments on your patch, but I keep that for later :) Cheers, Benjamin [1] http://bentiss.github.io/hid-replay-docs/ > > As I only have a PenMount 6000 to test I removed the multi touch support from the dirver. > > Bus 002 Device 006: ID 14e1:6000 Dialogue Technology Corp. > Device Descriptor: > bLength 18 > bDescriptorType 1 > bcdUSB 1.10 > bDeviceClass 0 (Defined at Interface level) > bDeviceSubClass 0 > bDeviceProtocol 0 > bMaxPacketSize0 64 > idVendor 0x14e1 Dialogue Technology Corp. > idProduct 0x6000 > bcdDevice a4.b4 > iManufacturer 1 DIALOGUE INC > iProduct 2 PenMount USB > iSerial 0 > bNumConfigurations 1 > Configuration Descriptor: > bLength 9 > bDescriptorType 2 > wTotalLength 41 > bNumInterfaces 1 > bConfigurationValue 1 > iConfiguration 4 full speed > bmAttributes 0xa0 > (Bus Powered) > Remote Wakeup > MaxPower 500mA > Interface Descriptor: > bLength 9 > bDescriptorType 4 > bInterfaceNumber 0 > bAlternateSetting 0 > bNumEndpoints 2 > bInterfaceClass 3 Human Interface Device > bInterfaceSubClass 0 No Subclass > bInterfaceProtocol 0 None > iInterface 3 EndPoint1 Interrupt Pipe > HID Device Descriptor: > bLength 9 > bDescriptorType 33 > bcdHID 1.01 > bCountryCode 0 Not supported > bNumDescriptors 1 > bDescriptorType 34 Report > wDescriptorLength 76 > Report Descriptors: > ** UNAVAILABLE ** > Endpoint Descriptor: > bLength 7 > bDescriptorType 5 > bEndpointAddress 0x81 EP 1 IN > bmAttributes 3 > Transfer Type Interrupt > Synch Type None > Usage Type Data > wMaxPacketSize 0x0005 1x 5 bytes > bInterval 1 > Endpoint Descriptor: > bLength 7 > bDescriptorType 5 > bEndpointAddress 0x02 EP 2 OUT > bmAttributes 3 > Transfer Type Interrupt > Synch Type None > Usage Type Data > wMaxPacketSize 0x0005 1x 5 bytes > bInterval 1 > Device Status: 0x0000 > (Bus Powered) > > Signed-off-by: Christian Gmeiner <christian.gmeiner@xxxxxxxxx> > --- > drivers/hid/Kconfig | 6 ++ > drivers/hid/Makefile | 1 + > drivers/hid/hid-core.c | 1 + > drivers/hid/hid-ids.h | 1 + > drivers/hid/hid-penmount.c | 200 +++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 209 insertions(+) > create mode 100644 drivers/hid/hid-penmount.c > > diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig > index c18d5d7..0351b66 100644 > --- a/drivers/hid/Kconfig > +++ b/drivers/hid/Kconfig > @@ -530,6 +530,12 @@ config PANTHERLORD_FF > Say Y here if you have a PantherLord/GreenAsia based game controller > or adapter and want to enable force feedback support for it. > > +config HID_PENMOUNT > + tristate "Penmount touch device" > + depends on USB_HID > + ---help--- > + Say Y here if you have a Penmount based touch controller. > + > config HID_PETALYNX > tristate "Petalynx Maxter remote control" > depends on HID > diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile > index 4dbac7f..e2850d8 100644 > --- a/drivers/hid/Makefile > +++ b/drivers/hid/Makefile > @@ -71,6 +71,7 @@ obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o > obj-$(CONFIG_HID_ORTEK) += hid-ortek.o > obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o > obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o > +obj-$(CONFIG_HID_PENMOUNT) += hid-penmount.o > obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o > obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o > hid-picolcd-y += hid-picolcd_core.o > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c > index 12b6e67..6827196 100644 > --- a/drivers/hid/hid-core.c > +++ b/drivers/hid/hid-core.c > @@ -1880,6 +1880,7 @@ static const struct hid_device_id hid_have_special_driver[] = { > { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, > { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, > { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, > + { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, > { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, > { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, > #if IS_ENABLED(CONFIG_HID_ROCCAT) > diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h > index 25cd674..3943ffe 100644 > --- a/drivers/hid/hid-ids.h > +++ b/drivers/hid/hid-ids.h > @@ -722,6 +722,7 @@ > #define USB_DEVICE_ID_PENMOUNT_PCI 0x3500 > #define USB_DEVICE_ID_PENMOUNT_1610 0x1610 > #define USB_DEVICE_ID_PENMOUNT_1640 0x1640 > +#define USB_DEVICE_ID_PENMOUNT_6000 0x6000 > > #define USB_VENDOR_ID_PETALYNX 0x18b1 > #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 > diff --git a/drivers/hid/hid-penmount.c b/drivers/hid/hid-penmount.c > new file mode 100644 > index 0000000..3a630d1 > --- /dev/null > +++ b/drivers/hid/hid-penmount.c > @@ -0,0 +1,200 @@ > +/* > + * HID driver for PenMount touchscreens > + * > + * Copyright (c) 2011 PenMount Touch Solutions <penmount@xxxxxxxxxxx> > + * > + */ > + > +/* > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the Free > + * Software Foundation; either version 2 of the License, or (at your option) > + * any later version. > + */ > + > +#include <linux/module.h> > +#include <linux/hid.h> > +#include <linux/version.h> > +#include <linux/input/mt.h> > +#include "hid-ids.h" > + > +struct penmount_priv { > + u8 touch; > + bool touching; > + u16 x; > + u16 y; > +}; > + > +static int penmount_input_mapping(struct hid_device *hdev, > + struct hid_input *hi, struct hid_field *field, > + struct hid_usage *usage, unsigned long **bit, int *max) > +{ > + struct input_dev *dev = hi->input; > + int mapped = 0; > + > + switch (usage->hid & HID_USAGE_PAGE) { > + case HID_UP_GENDESK: > + switch (usage->hid) { > + case HID_GD_X: > + hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_X); > + mapped = 1; > + break; > + case HID_GD_Y: > + hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_Y); > + mapped = 1; > + break; > + } > + break; > + case HID_UP_BUTTON: > + hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); > + mapped = 1; > + break; > + case HID_UP_DIGITIZER: > + switch (usage->hid) { > + case HID_DG_TIPSWITCH: > + hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); > + mapped = 1; > + break; > + case HID_DG_CONTACTID: > + input_mt_init_slots(dev, 1, 0); > + mapped = -1; > + break; > + case HID_DG_INRANGE: > + case HID_DG_CONFIDENCE: > + mapped = -1; > + break; > + } > + break; > + } > + > + return mapped; > +} > + > +static void penmount_process(struct input_dev *dev, struct penmount_priv *priv) > +{ > + if (!priv->touching) { > + if (priv->touch) { > + input_report_key(dev, BTN_TOUCH, 1); > + priv->touching = true; > + } > + } else { > + if (!priv->touch) { > + input_report_key(dev, BTN_TOUCH, 0); > + priv->touching = false; > + } > + } > + > + input_report_abs(dev, ABS_X, priv->x); > + input_report_abs(dev, ABS_Y, priv->y); > + input_sync(dev); > + > + priv->touch = 0; > +} > + > +static int penmount_event(struct hid_device *hdev, struct hid_field *field, > + struct hid_usage *usage, __s32 value) > +{ > + if (hdev->claimed & HID_CLAIMED_INPUT) { > + struct penmount_priv *priv = hid_get_drvdata(hdev); > + struct input_dev *dev = field->hidinput->input; > + > + switch (usage->hid) { > + case HID_DG_TIPSWITCH: > + priv->touch = value; > + break; > + case HID_GD_X: > + priv->x = value; > + break; > + case HID_GD_Y: > + priv->y = value; > + break; > + default: > + /* fallback to the generic hidinput handling */ > + return 0; > + } > + > + penmount_process(dev, priv); > + } > + > + if ((hdev->claimed & HID_CLAIMED_HIDDEV) && (hdev->hiddev_hid_event)) > + hdev->hiddev_hid_event(hdev, field, usage, value); > + > + return 1; > +} > + > +static int penmount_probe(struct hid_device *hdev, > + const struct hid_device_id *id) > +{ > + struct penmount_priv *priv; > + int ret = 0; > + > + priv = kzalloc(sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + hid_set_drvdata(hdev, priv); > + > + ret = hid_parse(hdev); > + if (ret) { > + hid_err(hdev, "parse failed\n"); > + goto err_free; > + } > + > + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); > + if (ret) { > + hid_err(hdev, "hw start failed\n"); > + goto err_free; > + } > + > + return 0; > + > +err_free: > + kfree(priv); > + return ret; > +} > + > +static void penmount_remove(struct hid_device *hdev) > +{ > + struct penmount_priv *priv = hid_get_drvdata(hdev); > + > + hid_hw_stop(hdev); > + kfree(priv); > +} > + > +static const struct hid_device_id penmount_devices[] = { > + { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, > + { } > +}; > +MODULE_DEVICE_TABLE(hid, penmount_devices); > + > +static const struct hid_usage_id penmount_usages[] = { > + { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, > + { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } > +}; > + > +static struct hid_driver penmount_driver = { > + .name = "hid-penmount", > + .id_table = penmount_devices, > + .probe = penmount_probe, > + .remove = penmount_remove, > + .input_mapping = penmount_input_mapping, > + .usage_table = penmount_usages, > + .event = penmount_event, > +}; > + > +static int __init penmount_init(void) > +{ > + return hid_register_driver(&penmount_driver); > +} > + > +static void __exit penmount_exit(void) > +{ > + hid_unregister_driver(&penmount_driver); > +} > + > +module_init(penmount_init); > +module_exit(penmount_exit); > + > +MODULE_AUTHOR("PenMount Touch Solutions <penmount@xxxxxxxxxxx>"); > +MODULE_DESCRIPTION("PenMount HID TouchScreen Driver"); > +MODULE_LICENSE("GPL"); > -- > 1.9.3 > > -- > 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 -- 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