* Re: [PATCH] Add quirk HID_QUIRK_NO_INIT_REPORTS for RNDPLUS touchscreen
From: Benjamin Tissoires @ 2014-03-21 20:58 UTC (permalink / raw)
To: Yufeng Shen
Cc: linux-input, Jiri Kosina, linux-kernel@vger.kernel.org, linux-usb,
Andrew de los Reyes
In-Reply-To: <1395430798-25606-1-git-send-email-miletus@chromium.org>
On Fri, Mar 21, 2014 at 3:39 PM, Yufeng Shen <miletus@chromium.org> wrote:
> There is timeout error during initialization:
> kernel: [ 14.167086] hid-multitouch 0003:2512:5003.0001: usb_submit_urb(ctrl) failed: -1
> kernel: [ 14.167135] hid-multitouch 0003:2512:5003.0001: timeout initializing reports
> kernel: [ 14.167407] input: RNDPLUS Co., LTD PULSEIR TSR4601 as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input14
> kernel: [ 14.167975] cpufreq_interactive: monitoring input on RNDPLUS Co., LTD PULSEIR TSR4601
> kernel: [ 14.168266] hid-multitouch 0003:2512:5003.0001: input,hiddev0,hidraw1: USB HID v1.10 Mouse [RNDPLUS Co., LTD PULSEIR TSR4601] on usb-0000:00:1d.0-1.3/input0
>
> Adding quirk HID_QUIRK_NO_INIT_REPORTS can solve the problem.
I already asked you to test if HID_QUIRK_NO_INIT_INPUT_REPORTS was
working for the same same kind of timeout
(https://patchwork.kernel.org/patch/3544281/).
So I am asking again: please test HID_QUIRK_NO_INIT_INPUT_REPORTS and
if it works, use this quirk instead the one in this patch.
This *really* matters because the quirk HID_QUIRK_NO_INIT_REPORTS does
not initialize feature reports which contains important information
regarding hid-multitouch.
Cheers,
Benjamin
>
> Signed-off-by: Yufeng Shen <miletus@chromium.org>
> ---
> drivers/hid/hid-ids.h | 5 +++++
> drivers/hid/usbhid/hid-quirks.c | 3 +++
> 2 files changed, 8 insertions(+)
>
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index f9304cb..772f937 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -442,6 +442,11 @@
> #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
> #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651
>
> +#define USB_VENDOR_ID_IDSPULSE 0x2512
> +#define USB_DEVICE_ID_IDSPULSE_EVIR1 0x5003
> +#define USB_DEVICE_ID_IDSPULSE_EVIR2 0x5004
> +#define USB_DEVICE_ID_IDSPULSE_EVIR3 0x5005
> +
> #define USB_VENDOR_ID_ILITEK 0x222a
> #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
>
> diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
> index 0db9a67..e59ad07 100644
> --- a/drivers/hid/usbhid/hid-quirks.c
> +++ b/drivers/hid/usbhid/hid-quirks.c
> @@ -72,6 +72,9 @@ static const struct hid_blacklist {
> { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
> { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
> { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
> + { USB_VENDOR_ID_IDSPULSE, USB_DEVICE_ID_IDSPULSE_EVIR1, HID_QUIRK_NO_INIT_REPORTS },
> + { USB_VENDOR_ID_IDSPULSE, USB_DEVICE_ID_IDSPULSE_EVIR2, HID_QUIRK_NO_INIT_REPORTS },
> + { USB_VENDOR_ID_IDSPULSE, USB_DEVICE_ID_IDSPULSE_EVIR3, HID_QUIRK_NO_INIT_REPORTS },
> { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
> { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
> { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
> --
> 1.9.1.423.g4596e3a
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* [PATCH] Add quirk HID_QUIRK_NO_INIT_REPORTS for RNDPLUS touchscreen
From: Yufeng Shen @ 2014-03-21 19:39 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina, linux-kernel, linux-usb, Yufeng Shen, adlr
There is timeout error during initialization:
kernel: [ 14.167086] hid-multitouch 0003:2512:5003.0001: usb_submit_urb(ctrl) failed: -1
kernel: [ 14.167135] hid-multitouch 0003:2512:5003.0001: timeout initializing reports
kernel: [ 14.167407] input: RNDPLUS Co., LTD PULSEIR TSR4601 as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/input/input14
kernel: [ 14.167975] cpufreq_interactive: monitoring input on RNDPLUS Co., LTD PULSEIR TSR4601
kernel: [ 14.168266] hid-multitouch 0003:2512:5003.0001: input,hiddev0,hidraw1: USB HID v1.10 Mouse [RNDPLUS Co., LTD PULSEIR TSR4601] on usb-0000:00:1d.0-1.3/input0
Adding quirk HID_QUIRK_NO_INIT_REPORTS can solve the problem.
Signed-off-by: Yufeng Shen <miletus@chromium.org>
---
drivers/hid/hid-ids.h | 5 +++++
drivers/hid/usbhid/hid-quirks.c | 3 +++
2 files changed, 8 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index f9304cb..772f937 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -442,6 +442,11 @@
#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
#define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651
+#define USB_VENDOR_ID_IDSPULSE 0x2512
+#define USB_DEVICE_ID_IDSPULSE_EVIR1 0x5003
+#define USB_DEVICE_ID_IDSPULSE_EVIR2 0x5004
+#define USB_DEVICE_ID_IDSPULSE_EVIR3 0x5005
+
#define USB_VENDOR_ID_ILITEK 0x222a
#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 0db9a67..e59ad07 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -72,6 +72,9 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_IDSPULSE, USB_DEVICE_ID_IDSPULSE_EVIR1, HID_QUIRK_NO_INIT_REPORTS },
+ { USB_VENDOR_ID_IDSPULSE, USB_DEVICE_ID_IDSPULSE_EVIR2, HID_QUIRK_NO_INIT_REPORTS },
+ { USB_VENDOR_ID_IDSPULSE, USB_DEVICE_ID_IDSPULSE_EVIR3, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
--
1.9.1.423.g4596e3a
^ permalink raw reply related
* [RFC PATCH] HID: Stop hiding options with !EXPERT
From: Jean Delvare @ 2014-03-21 8:46 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina
Many HID driver options are hidden unless EXPERT is set. While I
understand the idea of simplifying the kernel configuration for most
users, in practice I believe it adds more confusion than it helps.
One thing that worries me is that, in non-EXPERT mode, these drivers
will be either built-in or modular based on apparent magic. For
example, switching INPUT and HID from m to y will cause all these
drivers to be built into the kernel when they were previously built
as modules. Short of enabling EXPERT mode altogether, the user has no
control over that.
Generally I do not think tristate options should depend on !EXPERT.
Of these, 11 of 15 are currently in the hid subsystem.
The HID_LOGITECH option is even worse than the others. Sub-options
depend on it, and this causes menuconfig and friends to display the
option even though the user can't change its value. The help page for
HID_LOGITECH will not explain why the value can't be changed. It only
says, for example:
Depends on: INPUT [=y] && HID [=y]
and that leaves the user puzzled about why the option is forced to y.
You might argue that this is a Kconfig bug, but that doesn't make it
less annoying for the user.
Even worse is that some of the sub-options of HID_LOGITECH select
INPUT_FF_MEMLESS, which in turn gets out of control for the user. So,
if you set INPUT=y and HID=y (something most general purpose
distributions would do these days, as both modules would get loaded on
a vast majority of systems otherwise), and you want support for
force-feedback game controllers, you can't have that as a module, it
has to be built-in, regardless of how rare these devices are.
Of course, all this madness goes away once EXPERT is enabled, but then
the rest of the kernel configuration becomes more complex, which
totally voids the original point.
For this reason, I would like all HID device tristate options to be
displayed regardless of EXPERT being set or not. We can let the
default settings still depend on EXPERT, that's not intrusive.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Cc: Jiri Kosina <jkosina@suse.cz>
---
drivers/hid/Kconfig | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
--- linux-3.14-rc7.orig/drivers/hid/Kconfig 2014-03-20 21:06:41.457316973 +0100
+++ linux-3.14-rc7/drivers/hid/Kconfig 2014-03-20 21:06:59.861752396 +0100
@@ -91,7 +91,7 @@ menu "Special HID drivers"
depends on HID
config HID_A4TECH
- tristate "A4 tech mice" if EXPERT
+ tristate "A4 tech mice"
depends on HID
default !EXPERT
---help---
@@ -112,7 +112,7 @@ config HID_ACRUX_FF
game controllers.
config HID_APPLE
- tristate "Apple {i,Power,Mac}Books" if EXPERT
+ tristate "Apple {i,Power,Mac}Books"
depends on HID
default !EXPERT
---help---
@@ -140,21 +140,21 @@ config HID_AUREAL
Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes.
config HID_BELKIN
- tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT
+ tristate "Belkin Flip KVM and Wireless keyboard"
depends on HID
default !EXPERT
---help---
Support for Belkin Flip KVM and Wireless keyboard.
config HID_CHERRY
- tristate "Cherry Cymotion keyboard" if EXPERT
+ tristate "Cherry Cymotion keyboard"
depends on HID
default !EXPERT
---help---
Support for Cherry Cymotion keyboard.
config HID_CHICONY
- tristate "Chicony Tactical pad" if EXPERT
+ tristate "Chicony Tactical pad"
depends on HID
default !EXPERT
---help---
@@ -176,7 +176,7 @@ config HID_PRODIKEYS
and some additional multimedia keys.
config HID_CYPRESS
- tristate "Cypress mouse and barcode readers" if EXPERT
+ tristate "Cypress mouse and barcode readers"
depends on HID
default !EXPERT
---help---
@@ -225,7 +225,7 @@ config HID_ELO
different devices than those handled by CONFIG_TOUCHSCREEN_USB_ELO.
config HID_EZKEY
- tristate "Ezkey BTC 8193 keyboard" if EXPERT
+ tristate "Ezkey BTC 8193 keyboard"
depends on HID
default !EXPERT
---help---
@@ -310,7 +310,7 @@ config HID_TWINHAN
Support for Twinhan IR remote control.
config HID_KENSINGTON
- tristate "Kensington Slimblade Trackball" if EXPERT
+ tristate "Kensington Slimblade Trackball"
depends on HID
default !EXPERT
---help---
@@ -336,7 +336,7 @@ config HID_LENOVO_TPKBD
controlling the mute and microphone mute LEDs.
config HID_LOGITECH
- tristate "Logitech devices" if EXPERT
+ tristate "Logitech devices"
depends on HID
default !EXPERT
---help---
@@ -413,14 +413,14 @@ config HID_MAGICMOUSE
Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad.
config HID_MICROSOFT
- tristate "Microsoft non-fully HID-compliant devices" if EXPERT
+ tristate "Microsoft non-fully HID-compliant devices"
depends on HID
default !EXPERT
---help---
Support for Microsoft devices that are not fully compliant with HID standard.
config HID_MONTEREY
- tristate "Monterey Genius KB29E keyboard" if EXPERT
+ tristate "Monterey Genius KB29E keyboard"
depends on HID
default !EXPERT
---help---
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply
* Re: [PATCH] Input: Support in the elantech driver of the trackpoint present on for instance Lenovo L530
From: ulrik.debie-os @ 2014-03-20 19:59 UTC (permalink / raw)
To: linux-input, Dmitry Torokhov
Cc: Hans de Goede, Benjamin Tissoires, David Herrmann
In-Reply-To: <20140214205126.GB15526@lantern>
Hi Dmitry,
Could you please have a look at this patch. It solves the bugzilla bug
https://bugzilla.kernel.org/show_bug.cgi?id=48161
Thanks,
Best regards,
Ulrik De Bie
On Fri, Feb 14, 2014 at 09:51:26PM +0100, Ulrik De Bie wrote:
> Date: Fri, 14 Feb 2014 21:51:26 +0100
> From: Ulrik De Bie <ulrik.debie-os@e2big.org>
> To: linux-input@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org, Dmitry Torokhov
> <dmitry.torokhov@gmail.com>, David Herrmann <dh.herrmann@gmail.com>,
> Jonathan Aquilina <eagles051387@gmail.com>, Ulrik De Bie
> <ulrik_opensource-kernel@yahoo.com>
> Subject: [PATCH] Input: Support in the elantech driver of the trackpoint
> present on for instance Lenovo L530
> X-Mailing-List: linux-input@vger.kernel.org
>
> Sorry it took me some time to have an email addres that would allow clean
> mails. Below you can find the updated patch previously sent on linux-input
> mailinglist. David Herrman asked to resent this patch as a proper git patch so
> here it is now.
>
> It also available on https://github.com/ulrikdb/linux.git elantech_trackpoint
> from commit 38dbfb59d1175ef458d006556061adeaa8751b72 (Linus 3.14-rc1) up to
> d69e103a35c944721966105790d14adf79098a4c
>
> Please when responding please send either to linux-input or put Ulrik De Bie <ulrik.debie-os@e2big.org> in CC:, Thanks.
>
>
> The Lenovo L530 trackpoint does not work out of the box. It gives sync errors
> as shown below when the trackpoint or trackpoint mouse buttons are pressed and
> no input is received by userspace:
> [ 29.010641] psmouse serio1: Touchpad at isa0060/serio1/input0 lost sync at byte 6
> The touchpad does work.
>
> The alternative is to do a downgrade to generic ps/2 mouse (modprobe psmouse proto=bare)
> but this has the disadvantage that touchpad can't be disabled (I want trackpoint, not touchpad).
>
> With this patch, the trackpoint is provided as another input device; currently called 'TPPS/2 IBM TrackPoint'
> The trackpoint now succesfully works and I can disable the touchpad with synclient TouchPadOff=1
> The patch will also output messages that do not follow the expected pattern.
> In the mean time I've seen 2 unknown packets occasionally:
> 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
> 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00
> I don't know what those are for, but they can be safely ignored.
>
> Currently all packets that are not known to v3 touchpad and where packet[3] (the fourth byte) lowest
> nibble is 6 are now recognized as PACKET_TRACKPOINT and processed by the new elantech_report_trackpoint.
>
> This has been verified to work on a laptop where the touchpad/trackpoint combined identify themselves as:
> psmouse serio1: elantech: assuming hardware version 3 (with firmware version 0x350f02)
> psmouse serio1: elantech: Synaptics capabilities query result 0xb9, 0x15, 0x0c.
>
> Since I can't send clean email from yahoo, I've switched to a different email address: ulrik.debie-os@e2big.org
> Signed-off-by: Ulrik De Bie <ulrik_opensource-kernel@yahoo.com>
> Signed-off-by: Ulrik De Bie <ulrik.debie-os@e2big.org>
>
> Signed-off-by: Ulrik De Bie <ulrik.debie-os@e2big.org>
> ---
> drivers/input/mouse/elantech.c | 78 +++++++++++++++++++++++++++++++++++++++++-
> drivers/input/mouse/elantech.h | 3 ++
> 2 files changed, 80 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
> index ef1cf52..21d693b 100644
> --- a/drivers/input/mouse/elantech.c
> +++ b/drivers/input/mouse/elantech.c
> @@ -402,6 +402,54 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
> input_sync(dev);
> }
>
> +static void elantech_report_trackpoint(struct psmouse *psmouse,
> + int packet_type)
> +{
> + /* byte 0: 0 0 ~sx ~sy 0 M R L */
> + /* byte 1: sx 0 0 0 0 0 0 0 */
> + /* byte 2: sy 0 0 0 0 0 0 0 */
> + /* byte 3: 0 0 sy sx 0 1 1 0 */
> + /* byte 4: x7 x6 x5 x4 x3 x2 x1 x0 */
> + /* byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */
> +
> + /*
> + * x and y are written in two's complement spread
> + * over 9 bits with sx/sy the relative top bit and
> + * x7..x0 and y7..y0 the lower bits.
> + * The sign of y is opposite to what the input driver
> + * expects for a relative movement
> + */
> +
> + struct elantech_data *etd = psmouse->private;
> + struct input_dev *dev2 = etd->dev2;
> + unsigned char *packet = psmouse->packet;
> + int x, y;
> + input_report_key(dev2, BTN_LEFT, packet[0] & 0x01);
> + input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02);
> + input_report_key(dev2, BTN_MIDDLE, packet[0] & 0x04);
> + x = (s32) ((u32) ((packet[1] & 0x80) ? 0UL : 0xFFFFFF00UL) | (u32)
> + packet[4]);
> + y = -(s32) ((u32) ((packet[2] & 0x80) ? 0UL : 0xFFFFFF00UL) | (u32)
> + packet[5]);
> + input_report_rel(dev2, REL_X, x);
> + input_report_rel(dev2, REL_Y, y);
> + switch ((((u32) packet[0] & 0xF8) << 24) | ((u32) packet[1] << 16)
> + | (u32) packet[2] << 8 | (u32) packet[3]) {
> + case 0x00808036UL:
> + case 0x10008026UL:
> + case 0x20800016UL:
> + case 0x30000006UL:
> + break;
> + default:
> + /* Dump unexpected packet sequences if debug=1 (default) */
> + if (etd->debug == 1)
> + elantech_packet_dump(psmouse);
> + break;
> + }
> +
> + input_sync(dev2);
> +}
> +
> /*
> * Interpret complete data packets and report absolute mode input events for
> * hardware version 3. (12 byte packets for two fingers)
> @@ -700,8 +748,11 @@ static int elantech_packet_check_v3(struct psmouse *psmouse)
>
> if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c)
> return PACKET_V3_TAIL;
> + if ((packet[3]&0x0f) == 0x06)
> + return PACKET_TRACKPOINT;
> }
>
> +
> return PACKET_UNKNOWN;
> }
>
> @@ -783,7 +834,10 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
> if (packet_type == PACKET_UNKNOWN)
> return PSMOUSE_BAD_DATA;
>
> - elantech_report_absolute_v3(psmouse, packet_type);
> + if (packet_type == PACKET_TRACKPOINT)
> + elantech_report_trackpoint(psmouse, packet_type);
> + else
> + elantech_report_absolute_v3(psmouse, packet_type);
> break;
>
> case 4:
> @@ -1400,10 +1454,15 @@ int elantech_init(struct psmouse *psmouse)
> struct elantech_data *etd;
> int i, error;
> unsigned char param[3];
> + struct input_dev *dev2;
>
> psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL);
> if (!etd)
> return -ENOMEM;
> + dev2 = input_allocate_device();
> + if (!dev2)
> + goto init_fail;
> + etd->dev2 = dev2;
>
> psmouse_reset(psmouse);
>
> @@ -1463,9 +1522,26 @@ int elantech_init(struct psmouse *psmouse)
> psmouse->reconnect = elantech_reconnect;
> psmouse->pktsize = etd->hw_version > 1 ? 6 : 4;
>
> + snprintf(etd->phys, sizeof(etd->phys), "%s/input1",
> + psmouse->ps2dev.serio->phys);
> + dev2->phys = etd->phys;
> + dev2->name = "TPPS/2 IBM TrackPoint";
> + dev2->id.bustype = BUS_I8042;
> + dev2->id.vendor = 0x0002;
> + dev2->id.product = PSMOUSE_ELANTECH;
> + dev2->id.version = 0x0000;
> + dev2->dev.parent = &psmouse->ps2dev.serio->dev;
> + dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
> + dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
> + dev2->keybit[BIT_WORD(BTN_LEFT)] =
> + BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
> +
> + if (input_register_device(etd->dev2))
> + goto init_fail;
> return 0;
>
> init_fail:
> + input_free_device(dev2);
> kfree(etd);
> return -1;
> }
> diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
> index 036a04a..27cf191 100644
> --- a/drivers/input/mouse/elantech.h
> +++ b/drivers/input/mouse/elantech.h
> @@ -94,6 +94,7 @@
> #define PACKET_V4_HEAD 0x05
> #define PACKET_V4_MOTION 0x06
> #define PACKET_V4_STATUS 0x07
> +#define PACKET_TRACKPOINT 0x08
>
> /*
> * track up to 5 fingers for v4 hardware
> @@ -114,6 +115,8 @@ struct finger_pos {
> };
>
> struct elantech_data {
> + struct input_dev *dev2; /* Relative device */
> + char phys[32];
> unsigned char reg_07;
> unsigned char reg_10;
> unsigned char reg_11;
> --
> 1.8.5.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] HID: multitouch: add support for Win 8.1 multitouch touchpads
From: Benjamin Tissoires @ 2014-03-20 17:36 UTC (permalink / raw)
To: Jiri Kosina, Derya
Cc: Andrew Duggan, Benjamin Tissoires, linux-input, Henrik Rydberg
In-Reply-To: <alpine.LNX.2.00.1403201002260.3690@pobox.suse.cz>
On Thu, Mar 20, 2014 at 5:02 AM, Jiri Kosina <jkosina@suse.cz> wrote:
> On Wed, 19 Mar 2014, Andrew Duggan wrote:
>
>> Multitouch touchpads built for Win 8.1 need to be sent an input mode feature report
>> in order to start reporting multitouch events. This is the same process sent
>> to Win 7 multitouch touchscreens except the value of the feature report is 3 for
>> touchpads.
>>
>> Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
>> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
>
> Applied, thanks.
Thanks Jiri.
Derya, can you test if this also solves the problem with the Surface 2
touch cover?
(if you remove the special vendor handling in hid_scan_report)
Cheers,
Benjamin
^ permalink raw reply
* Re: [PATCH 0/2] input/serio: Add a firmware_id sysfs attribute
From: Matthew Garrett @ 2014-03-20 17:21 UTC (permalink / raw)
To: Hans de Goede
Cc: Dmitry Torokhov, Benjamin Tissoires, Peter Hutterer,
platform-driver-x86, linux-input
In-Reply-To: <1395310330-3232-1-git-send-email-hdegoede@redhat.com>
On Thu, Mar 20, 2014 at 11:12:08AM +0100, Hans de Goede wrote:
> Which in the end turns out to be much nicer too, since it gets rid of needing
> a udev-helper too. After this much too long introduction I'll let the patches
> speak for themselves.
Yeah, I was coming to the conclusion that this was probably the best we
could do. It's unfortunate that "id" is already in use - we'd be able to
get away without any X server modifications otherwise.
Long term we probably still want to tie serio devices to the ACPI
devices in case the vendor provides power management calls there, but we
can leave that until there's an actual example.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply
* Re: [PATCHv5 5/5] Input: edt-ft5x06: Add support for M09 firmware version
From: Daniel Wagener @ 2014-03-20 14:15 UTC (permalink / raw)
To: Lothar Waßmann, Dmitry Torokhov, Fugang Duan, Grant Likely,
Henrik Rydberg, Ian Campbell, Jingoo Han, Kumar Gala,
Mark Rutland, Pawel Moll, Rob Herring, Rob Landley, Sachin Kamat,
devicetree, linux-doc, linux-input, linux-kernel, Simon Budig
In-Reply-To: <1395323075-12146-6-git-send-email-LW@KARO-electronics.de>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Am 20.03.2014 14:44, schrieb Lothar Waßmann:
> From: Daniel Wagener <daniel.wagener@kernelconcepts.de>
>
> There is a new firmware version for the EDT-FT5x06 chip. Add
> support for detecting the firmware version and handle the
> differences appropriately.
>
> Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de> ---
> drivers/input/touchscreen/edt-ft5x06.c | 358
> ++++++++++++++++++++++++-------- 1 file changed, 276 insertions(+),
> 82 deletions(-)
>
> diff --git a/drivers/input/touchscreen/edt-ft5x06.c
> b/drivers/input/touchscreen/edt-ft5x06.c index 565f0cd..936d269
> 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++
> b/drivers/input/touchscreen/edt-ft5x06.c @@ -1,5 +1,6 @@ /* *
> Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de> + *
> Daniel Wagener <daniel.wagener@kernelconcepts.de> (M09 firmware
> support) * Lothar Waßmann <LW@KARO-electronics.de> (DT support) * *
> This software is licensed under the terms of the GNU General
> Public @@ -47,6 +48,14 @@ #define WORK_REGISTER_NUM_X 0x33 #define
> WORK_REGISTER_NUM_Y 0x34
>
> +#define M09_REGISTER_THRESHOLD 0x80 +#define M09_REGISTER_GAIN
> 0x92 +#define M09_REGISTER_OFFSET 0x93 +#define M09_REGISTER_NUM_X
> 0x94 +#define M09_REGISTER_NUM_Y 0x95 + +#define NO_REGISTER
> 0xff + #define WORK_REGISTER_OPMODE 0x3c #define
> FACTORY_REGISTER_OPMODE 0x01
>
> @@ -61,6 +70,20 @@ #define EDT_RAW_DATA_RETRIES 100 #define
> EDT_RAW_DATA_DELAY 1 /* msec */
>
> +enum edt_ver { + M06, + M09, +}; + +struct edt_reg_addr { + int
> reg_threshold; + int reg_report_rate; + int reg_gain; + int
> reg_offset; + int reg_num_x; + int reg_num_y; +}; + struct
> edt_ft5x06_ts_data { struct i2c_client *client; struct input_dev
> *input; @@ -85,6 +108,9 @@ struct edt_ft5x06_ts_data { int
> report_rate;
>
> char name[EDT_NAME_LEN]; + + struct edt_reg_addr reg_addr; + enum
> edt_ver version; };
>
> static int edt_ft5x06_ts_readwrite(struct i2c_client *client, @@
> -142,33 +168,58 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq,
> void *dev_id) { struct edt_ft5x06_ts_data *tsdata = dev_id; struct
> device *dev = &tsdata->client->dev; - u8 cmd = 0xf9; - u8
> rdbuf[26]; + u8 cmd; + u8 rdbuf[29]; int i, type, x, y, id; + int
> offset, tplen, datalen; int error;
>
> + switch (tsdata->version) { + case M06: + cmd = 0xf9; /* tell the
> controller to send touch data */ + offset = 5; /* where the actual
> touch data starts */ + tplen = 4; /* data comes in so called
> frames */ + datalen = 26; /* how much bytes to listen for */ +
> break; + + case M09: + cmd = 0x02; + offset = 1; + tplen = 6; +
> datalen = 29; + break; + + default: + goto out; + } +
> memset(rdbuf, 0, sizeof(rdbuf));
>
> error = edt_ft5x06_ts_readwrite(tsdata->client, sizeof(cmd), &cmd,
> - sizeof(rdbuf), rdbuf); + datalen, rdbuf); if (error) {
> dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
> error); goto out; }
>
> - if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa || rdbuf[2] != 26) { -
> dev_err_ratelimited(dev, "Unexpected header: %02x%02x%02x!\n", -
> rdbuf[0], rdbuf[1], rdbuf[2]); - goto out; - } + /* M09 does not
> send header or CRC */ + if (tsdata->version == M06) { + if
> (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa || + rdbuf[2] != datalen)
> { + dev_err_ratelimited(dev, + "Unexpected header:
> %02x%02x%02x!\n", + rdbuf[0], rdbuf[1], rdbuf[2]); + goto
> out; + }
>
> - if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, 26)) - goto out; +
> if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, datalen)) + goto
> out; + }
>
> for (i = 0; i < MAX_SUPPORT_POINTS; i++) { - u8 *buf = &rdbuf[i *
> 4 + 5]; + u8 *buf = &rdbuf[i * tplen + offset]; bool down;
>
> type = buf[0] >> 6; @@ -176,8 +227,8 @@ static irqreturn_t
> edt_ft5x06_ts_isr(int irq, void *dev_id) if (type ==
> TOUCH_EVENT_RESERVED) continue;
>
> - /* ignore TOUCH_DOWN events, might have bogus coordinates */ -
> if (type == TOUCH_EVENT_DOWN) + /* M06 sometimes sends bogus
> coordinates in TOUCH_DOWN */ + if (tsdata->version == M06 && type
> == TOUCH_EVENT_DOWN) continue;
>
> x = ((buf[0] << 8) | buf[1]) & 0x0fff; @@ -207,12 +258,25 @@ static
> int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata, {
> u8 wrbuf[4];
>
> - wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; - wrbuf[1] =
> tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; - wrbuf[2] =
> value; - wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2]; - - return
> edt_ft5x06_ts_readwrite(tsdata->client, 4, wrbuf, 0, NULL); +
> switch (tsdata->version) { + case M06: + wrbuf[0] =
> tsdata->factory_mode ? 0xf3 : 0xfc; + wrbuf[1] =
> tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; + wrbuf[1] =
> tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; + wrbuf[2] =
> value; + wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2]; + return
> edt_ft5x06_ts_readwrite(tsdata->client, 4, + wrbuf, 0, NULL); +
> case M09: + wrbuf[0] = addr; + wrbuf[1] = value; + + return
> edt_ft5x06_ts_readwrite(tsdata->client, 3, + wrbuf, 0, NULL);
> + + default: + return -EINVAL; + } }
>
> static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data
> *tsdata, @@ -221,19 +285,35 @@ static int
> edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata, u8
> wrbuf[2], rdbuf[2]; int error;
>
> - wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; - wrbuf[1] =
> tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; - wrbuf[1] |=
> tsdata->factory_mode ? 0x80 : 0x40; + switch (tsdata->version) { +
> case M06: + wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; +
> wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; +
> wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
>
> - error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2,
> rdbuf); - if (error) + error =
> edt_ft5x06_ts_readwrite(tsdata->client, + 2, wrbuf, 2,
> rdbuf); return error;
>
> - if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) { -
> dev_err(&tsdata->client->dev, - "crc error: 0x%02x expected, got
> 0x%02x\n", - wrbuf[0] ^ wrbuf[1] ^ rdbuf[0], rdbuf[1]); - return
> -EIO; + if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) { +
> dev_err(&tsdata->client->dev, + "crc error: 0x%02x expected, got
> 0x%02x\n", + wrbuf[0] ^ wrbuf[1] ^ rdbuf[0], + rdbuf[1]); +
> return -EIO; + } + break; + + case M09: + wrbuf[0] = addr; +
> error = edt_ft5x06_ts_readwrite(tsdata->client, 1, + wrbuf, 1,
> rdbuf); + if (error) + return error; + break; + + default: +
> return -EINVAL; }
>
> return rdbuf[0]; @@ -244,19 +324,21 @@ struct edt_ft5x06_attribute
> { size_t field_offset; u8 limit_low; u8 limit_high; - u8 addr; + u8
> addr_m06; + u8 addr_m09; };
>
> -#define EDT_ATTR(_field, _mode, _addr, _limit_low, _limit_high)
> \ +#define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09, \ +
> _limit_low, _limit_high) \ struct edt_ft5x06_attribute
> edt_ft5x06_attr_##_field = { \ .dattr = __ATTR(_field, _mode, \
> edt_ft5x06_setting_show, \ edt_ft5x06_setting_store), \ -
> .field_offset = \ - offsetof(struct edt_ft5x06_ts_data,
> _field), \ + .field_offset = offsetof(struct edt_ft5x06_ts_data,
> _field), \ + .addr_m06 = _addr_m06, \ + .addr_m09 =
> _addr_m09, \ .limit_low = _limit_low, \ .limit_high =
> _limit_high, \ - .addr = _addr, \ }
>
> static ssize_t edt_ft5x06_setting_show(struct device *dev, @@
> -271,6 +353,7 @@ static ssize_t edt_ft5x06_setting_show(struct
> device *dev, int val; size_t count = 0; int error = 0; + u8 addr;
>
> mutex_lock(&tsdata->mutex);
>
> @@ -279,15 +362,33 @@ static ssize_t edt_ft5x06_setting_show(struct
> device *dev, goto out; }
>
> - val = edt_ft5x06_register_read(tsdata, attr->addr); - if (val <
> 0) { - error = val; - dev_err(&tsdata->client->dev, - "Failed
> to fetch attribute %s, error %d\n", - dattr->attr.name, error); +
> switch (tsdata->version) { + case M06: + addr = attr->addr_m06; +
> break; + + case M09: + addr = attr->addr_m09; + break; + +
> default: + error = -ENODEV; goto out; }
>
> + if (addr != NO_REGISTER) { + val =
> edt_ft5x06_register_read(tsdata, addr); + if (val < 0) { + error
> = val; + dev_err(&tsdata->client->dev, + "Failed to fetch
> attribute %s, error %d\n", + dattr->attr.name, error); + goto
> out; + } + } else { + val = *field; + } + if (val != *field) {
> dev_warn(&tsdata->client->dev, "%s: read (%d) and stored value (%d)
> differ\n", @@ -312,6 +413,7 @@ static ssize_t
> edt_ft5x06_setting_store(struct device *dev, u8 *field = (u8
> *)tsdata + attr->field_offset; unsigned int val; int error; + u8
> addr;
>
> mutex_lock(&tsdata->mutex);
>
> @@ -329,14 +431,29 @@ static ssize_t
> edt_ft5x06_setting_store(struct device *dev, goto out; }
>
> - error = edt_ft5x06_register_write(tsdata, attr->addr, val); - if
> (error) { - dev_err(&tsdata->client->dev, - "Failed to update
> attribute %s, error: %d\n", - dattr->attr.name, error); + switch
> (tsdata->version) { + case M06: + addr = attr->addr_m06; +
> break; + + case M09: + addr = attr->addr_m09; + break; + +
> default: + error = -ENODEV; goto out; }
>
> + if (addr != NO_REGISTER) { + error =
> edt_ft5x06_register_write(tsdata, addr, val); + if (error) { +
> dev_err(&tsdata->client->dev, + "Failed to update attribute %s,
> error: %d\n", + dattr->attr.name, error); + goto out; + } +
> } *field = val;
>
> out: @@ -344,12 +461,14 @@ out: return error ?: count; }
>
> -static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN, 0,
> 31); -static EDT_ATTR(offset, S_IWUSR | S_IRUGO,
> WORK_REGISTER_OFFSET, 0, 31); -static EDT_ATTR(threshold, S_IWUSR |
> S_IRUGO, - WORK_REGISTER_THRESHOLD, 20, 80); -static
> EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, -
> WORK_REGISTER_REPORT_RATE, 3, 14); +static EDT_ATTR(gain, S_IWUSR |
> S_IRUGO, WORK_REGISTER_GAIN, + M09_REGISTER_GAIN, 0, 31); +static
> EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET, +
> M09_REGISTER_OFFSET, 0, 31); +static EDT_ATTR(threshold, S_IWUSR |
> S_IRUGO, WORK_REGISTER_THRESHOLD, + M09_REGISTER_THRESHOLD, 20,
> 80); +static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO,
> WORK_REGISTER_REPORT_RATE, + NO_REGISTER, 3, 14);
>
> static struct attribute *edt_ft5x06_attrs[] = {
> &edt_ft5x06_attr_gain.dattr.attr, @@ -384,6 +503,9 @@ static int
> edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata) }
>
> /* mode register is 0x3c when in the work mode */ + if
> (tsdata->version == M09) + goto m09_out; + error =
> edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03); if
> (error) { dev_err(&client->dev, @@ -416,12 +538,18 @@ err_out:
> enable_irq(client->irq);
>
> return error; + +m09_out: + dev_err(&client->dev, "No factory mode
> support for M09\n"); + return -EINVAL; + }
>
> static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
> { struct i2c_client *client = tsdata->client; int retries =
> EDT_SWITCH_MODE_RETRIES; + struct edt_reg_addr *reg_addr =
> &tsdata->reg_addr; int ret; int error;
>
> @@ -454,13 +582,14 @@ static int edt_ft5x06_work_mode(struct
> edt_ft5x06_ts_data *tsdata) tsdata->raw_buffer = NULL;
>
> /* restore parameters */ - edt_ft5x06_register_write(tsdata,
> WORK_REGISTER_THRESHOLD, + edt_ft5x06_register_write(tsdata,
> reg_addr->reg_threshold, tsdata->threshold); -
> edt_ft5x06_register_write(tsdata, WORK_REGISTER_GAIN, +
> edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
> tsdata->gain); - edt_ft5x06_register_write(tsdata,
> WORK_REGISTER_OFFSET, + edt_ft5x06_register_write(tsdata,
> reg_addr->reg_offset, tsdata->offset); -
> edt_ft5x06_register_write(tsdata, WORK_REGISTER_REPORT_RATE, + if
> (reg_addr->reg_report_rate) + edt_ft5x06_register_write(tsdata,
> reg_addr->reg_report_rate, tsdata->report_rate);
>
> enable_irq(client->irq); @@ -663,30 +792,60 @@ static int
> edt_ft5x06_ts_reset(struct i2c_client *client, }
>
> static int edt_ft5x06_ts_identify(struct i2c_client *client, -
> char *model_name, - char *fw_version) + struct
> edt_ft5x06_ts_data *tsdata, + char *fw_version) { u8
> rdbuf[EDT_NAME_LEN]; char *p; int error; + char *model_name =
> tsdata->name;
>
> + /* see what we find if we assume it is a M06 * + * if we get
> less than EDT_NAME_LEN, we don't want + * to have garbage in
> there + */ + memset(rdbuf, 0, sizeof(rdbuf)); error =
> edt_ft5x06_ts_readwrite(client, 1, "\xbb", EDT_NAME_LEN - 1,
> rdbuf); if (error) return error;
>
> - /* remove last '$' end marker */ - rdbuf[EDT_NAME_LEN - 1] =
> '\0'; - if (rdbuf[EDT_NAME_LEN - 2] == '$') - rdbuf[EDT_NAME_LEN -
> 2] = '\0'; + /* if we find something consistent, stay with that
> assumption + * at least M09 won't send 3 bytes here + */ + if
> (!(strnicmp(rdbuf + 1, "EP0", 3))) { + tsdata->version = M06; + +
> /* remove last '$' end marker */ + rdbuf[EDT_NAME_LEN - 1] =
> '\0'; + if (rdbuf[EDT_NAME_LEN - 2] == '$') + rdbuf[EDT_NAME_LEN
> - 2] = '\0'; + + /* look for Model/Version separator */ + p =
> strchr(rdbuf, '*'); + if (p) + *p++ = '\0'; +
> strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN); +
> strlcpy(fw_version, p ? p : "", EDT_NAME_LEN); + } else { + /*
> since there are only two versions around (M06, M09) */ +
> tsdata->version = M09; + + error = edt_ft5x06_ts_readwrite(client,
> 1, "\xA6", + 2, rdbuf); + if (error) + return error;
>
> - /* look for Model/Version separator */ - p = strchr(rdbuf, '*');
> - if (p) - *p++ = '\0'; + strlcpy(fw_version, rdbuf, 2);
>
> - strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN); -
> strlcpy(fw_version, p ? p : "", EDT_NAME_LEN); + error =
> edt_ft5x06_ts_readwrite(client, 1, "\xA8", + 1, rdbuf); + if
> (error) + return error; + + snprintf(model_name, EDT_NAME_LEN,
> "EP0%i%i0M09", + rdbuf[0] >> 4, rdbuf[0] & 0x0F); + }
>
> return 0; } @@ -705,36 +864,69 @@ static int
> edt_ft5x06_ts_identify(struct i2c_client *client, static void
> edt_ft5x06_ts_get_dt_defaults(struct device_node *np, struct
> edt_ft5x06_ts_data *tsdata) { - EDT_GET_PROP(threshold,
> WORK_REGISTER_THRESHOLD); - EDT_GET_PROP(gain,
> WORK_REGISTER_GAIN); - EDT_GET_PROP(offset, WORK_REGISTER_OFFSET);
> + struct edt_reg_addr *reg_addr = &tsdata->reg_addr; + +
> EDT_GET_PROP(threshold, reg_addr->reg_threshold); +
> EDT_GET_PROP(gain, reg_addr->reg_gain); + EDT_GET_PROP(offset,
> reg_addr->reg_offset); }
>
> static void edt_ft5x06_ts_get_defaults(struct edt_ft5x06_ts_data
> *tsdata, const struct edt_ft5x06_platform_data *pdata) { + struct
> edt_reg_addr *reg_addr = &tsdata->reg_addr; + if
> (!pdata->use_parameters) return;
>
> /* pick up defaults from the platform data */ -
> EDT_ATTR_CHECKSET(threshold, WORK_REGISTER_THRESHOLD); -
> EDT_ATTR_CHECKSET(gain, WORK_REGISTER_GAIN); -
> EDT_ATTR_CHECKSET(offset, WORK_REGISTER_OFFSET); -
> EDT_ATTR_CHECKSET(report_rate, WORK_REGISTER_REPORT_RATE); +
> EDT_ATTR_CHECKSET(threshold, reg_addr->reg_threshold); +
> EDT_ATTR_CHECKSET(gain, reg_addr->reg_gain); +
> EDT_ATTR_CHECKSET(offset, reg_addr->reg_offset); + if
> (reg_addr->reg_report_rate != NO_REGISTER) +
> EDT_ATTR_CHECKSET(report_rate, reg_addr->reg_report_rate); }
>
> static void edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data
> *tsdata) { + struct edt_reg_addr *reg_addr = &tsdata->reg_addr; +
> tsdata->threshold = edt_ft5x06_register_read(tsdata, -
> WORK_REGISTER_THRESHOLD); - tsdata->gain =
> edt_ft5x06_register_read(tsdata, WORK_REGISTER_GAIN); -
> tsdata->offset = edt_ft5x06_register_read(tsdata,
> WORK_REGISTER_OFFSET); - tsdata->report_rate =
> edt_ft5x06_register_read(tsdata, -
> WORK_REGISTER_REPORT_RATE); - tsdata->num_x =
> edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_X); -
> tsdata->num_y = edt_ft5x06_register_read(tsdata,
> WORK_REGISTER_NUM_Y); + reg_addr->reg_threshold); +
> tsdata->gain = edt_ft5x06_register_read(tsdata,
> reg_addr->reg_gain); + tsdata->offset =
> edt_ft5x06_register_read(tsdata, reg_addr->reg_offset); + if
> (reg_addr->reg_report_rate != NO_REGISTER) + tsdata->report_rate =
> edt_ft5x06_register_read(tsdata, +
> reg_addr->reg_report_rate); + tsdata->num_x =
> edt_ft5x06_register_read(tsdata, reg_addr->reg_num_x); +
> tsdata->num_y = edt_ft5x06_register_read(tsdata,
> reg_addr->reg_num_y); +} + +static void
> +edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata) +{ +
> struct edt_reg_addr *reg_addr = &tsdata->reg_addr; + + switch
> (tsdata->version) { + case M06: + reg_addr->reg_threshold =
> WORK_REGISTER_THRESHOLD; + reg_addr->reg_report_rate =
> WORK_REGISTER_REPORT_RATE; + reg_addr->reg_gain =
> WORK_REGISTER_GAIN; + reg_addr->reg_offset =
> WORK_REGISTER_OFFSET; + reg_addr->reg_num_x =
> WORK_REGISTER_NUM_X; + reg_addr->reg_num_y = WORK_REGISTER_NUM_Y;
> + break; + + case M09: + reg_addr->reg_threshold =
> M09_REGISTER_THRESHOLD; + reg_addr->reg_gain = M09_REGISTER_GAIN;
> + reg_addr->reg_offset = M09_REGISTER_OFFSET; +
> reg_addr->reg_num_x = M09_REGISTER_NUM_X; + reg_addr->reg_num_y =
> M09_REGISTER_NUM_Y; + break; + } }
>
> #ifdef CONFIG_OF @@ -818,12 +1010,14 @@ static int
> edt_ft5x06_ts_probe(struct i2c_client *client, tsdata->input =
> input; tsdata->factory_mode = false;
>
> - error = edt_ft5x06_ts_identify(client, tsdata->name,
> fw_version); + error = edt_ft5x06_ts_identify(client, tsdata,
> fw_version); if (error) { dev_err(&client->dev, "touchscreen probe
> failed\n"); return error; }
>
> + edt_ft5x06_ts_set_regs(tsdata); + if (!pdata)
> edt_ft5x06_ts_get_dt_defaults(client->dev.of_node, tsdata); else
>
Signed-off-by: Daniel Wagener <daniel.wagener@kernelconcepts.de>
- --
kernel concepts GmbH Tel: +49-271-771091-10
Sieghuetter Hauptweg 48
D-57072 Siegen
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iQEcBAEBAgAGBQJTKvf0AAoJEFnf1IDLMXhxDZ8H/2QSfIGFawlanwmZNDa5TDqV
C7aqWI0wm0s/rE2qYk8nDTepFWcywXXrVtA/vRZ279Cm5Na6UMW/CZOto6iBa8Oh
RxNdzEplA3crLOKqq23TZ6ItgOBLomC6nEcanmSRIde2NKzYdCQzc0S6bgrbNe5g
FWvEwzENOGM8xcUp+6jhL77RNfsyAklfD5x5wE6M6lWHbryED2L9SFPCY9k/KS7c
zKAdSFetOpr0Iw4Dsi/J02kAjAvVGvJurjNBkKDdlL8pr/MF9BJuXV4NgmUns73m
k9Lm7bSRQbmcA56rFx6+IqbzGYG+WWAwYxg8Uw5yF3SFrtYoRk2PnrsfJdJysHI=
=OIc2
-----END PGP SIGNATURE-----
^ permalink raw reply
* [PATCHv5 3/5] Input: edt-ft5x06: Adjust delays to conform datasheet
From: Lothar Waßmann @ 2014-03-20 13:44 UTC (permalink / raw)
To: Dmitry Torokhov, Fugang Duan, Grant Likely, Henrik Rydberg,
Ian Campbell, Jingoo Han, Kumar Gala, Mark Rutland, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat, devicetree, linux-doc,
linux-input, linux-kernel, Simon Budig, Lothar Waßmann,
Daniel Wagener
In-Reply-To: <1395323075-12146-1-git-send-email-LW@KARO-electronics.de>
The FT5x06 datasheet specifies a minimum reset width of 5ms and a
delay between deassertion of reset and start of reporting of 300ms.
Adjust the delays to conform to the datasheet.
With the original delays I sometimes experienced communication
timeouts when initializing the controller.
Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
drivers/input/touchscreen/edt-ft5x06.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 03dab2f..0298568 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -635,7 +635,7 @@ static int edt_ft5x06_ts_reset(struct i2c_client *client,
return error;
}
- mdelay(5);
+ msleep(5);
gpio_set_value(tsdata->wake_pin, 1);
}
if (gpio_is_valid(tsdata->reset_pin)) {
@@ -650,9 +650,9 @@ static int edt_ft5x06_ts_reset(struct i2c_client *client,
return error;
}
- mdelay(50);
+ msleep(5);
gpio_set_value(tsdata->reset_pin, 1);
- mdelay(100);
+ msleep(300);
}
return 0;
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCHv5 5/5] Input: edt-ft5x06: Add support for M09 firmware version
From: Lothar Waßmann @ 2014-03-20 13:44 UTC (permalink / raw)
To: Dmitry Torokhov, Fugang Duan, Grant Likely, Henrik Rydberg,
Ian Campbell, Jingoo Han, Kumar Gala, Mark Rutland, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat, devicetree, linux-doc,
linux-input, linux-kernel, Simon Budig, Lothar Waßmann,
Daniel Wagener
In-Reply-To: <1395323075-12146-1-git-send-email-LW@KARO-electronics.de>
From: Daniel Wagener <daniel.wagener@kernelconcepts.de>
There is a new firmware version for the EDT-FT5x06 chip.
Add support for detecting the firmware version and handle the
differences appropriately.
Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
drivers/input/touchscreen/edt-ft5x06.c | 358 ++++++++++++++++++++++++--------
1 file changed, 276 insertions(+), 82 deletions(-)
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 565f0cd..936d269 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de>
+ * Daniel Wagener <daniel.wagener@kernelconcepts.de> (M09 firmware support)
* Lothar Waßmann <LW@KARO-electronics.de> (DT support)
*
* This software is licensed under the terms of the GNU General Public
@@ -47,6 +48,14 @@
#define WORK_REGISTER_NUM_X 0x33
#define WORK_REGISTER_NUM_Y 0x34
+#define M09_REGISTER_THRESHOLD 0x80
+#define M09_REGISTER_GAIN 0x92
+#define M09_REGISTER_OFFSET 0x93
+#define M09_REGISTER_NUM_X 0x94
+#define M09_REGISTER_NUM_Y 0x95
+
+#define NO_REGISTER 0xff
+
#define WORK_REGISTER_OPMODE 0x3c
#define FACTORY_REGISTER_OPMODE 0x01
@@ -61,6 +70,20 @@
#define EDT_RAW_DATA_RETRIES 100
#define EDT_RAW_DATA_DELAY 1 /* msec */
+enum edt_ver {
+ M06,
+ M09,
+};
+
+struct edt_reg_addr {
+ int reg_threshold;
+ int reg_report_rate;
+ int reg_gain;
+ int reg_offset;
+ int reg_num_x;
+ int reg_num_y;
+};
+
struct edt_ft5x06_ts_data {
struct i2c_client *client;
struct input_dev *input;
@@ -85,6 +108,9 @@ struct edt_ft5x06_ts_data {
int report_rate;
char name[EDT_NAME_LEN];
+
+ struct edt_reg_addr reg_addr;
+ enum edt_ver version;
};
static int edt_ft5x06_ts_readwrite(struct i2c_client *client,
@@ -142,33 +168,58 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
{
struct edt_ft5x06_ts_data *tsdata = dev_id;
struct device *dev = &tsdata->client->dev;
- u8 cmd = 0xf9;
- u8 rdbuf[26];
+ u8 cmd;
+ u8 rdbuf[29];
int i, type, x, y, id;
+ int offset, tplen, datalen;
int error;
+ switch (tsdata->version) {
+ case M06:
+ cmd = 0xf9; /* tell the controller to send touch data */
+ offset = 5; /* where the actual touch data starts */
+ tplen = 4; /* data comes in so called frames */
+ datalen = 26; /* how much bytes to listen for */
+ break;
+
+ case M09:
+ cmd = 0x02;
+ offset = 1;
+ tplen = 6;
+ datalen = 29;
+ break;
+
+ default:
+ goto out;
+ }
+
memset(rdbuf, 0, sizeof(rdbuf));
error = edt_ft5x06_ts_readwrite(tsdata->client,
sizeof(cmd), &cmd,
- sizeof(rdbuf), rdbuf);
+ datalen, rdbuf);
if (error) {
dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
error);
goto out;
}
- if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa || rdbuf[2] != 26) {
- dev_err_ratelimited(dev, "Unexpected header: %02x%02x%02x!\n",
- rdbuf[0], rdbuf[1], rdbuf[2]);
- goto out;
- }
+ /* M09 does not send header or CRC */
+ if (tsdata->version == M06) {
+ if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
+ rdbuf[2] != datalen) {
+ dev_err_ratelimited(dev,
+ "Unexpected header: %02x%02x%02x!\n",
+ rdbuf[0], rdbuf[1], rdbuf[2]);
+ goto out;
+ }
- if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, 26))
- goto out;
+ if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, datalen))
+ goto out;
+ }
for (i = 0; i < MAX_SUPPORT_POINTS; i++) {
- u8 *buf = &rdbuf[i * 4 + 5];
+ u8 *buf = &rdbuf[i * tplen + offset];
bool down;
type = buf[0] >> 6;
@@ -176,8 +227,8 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
if (type == TOUCH_EVENT_RESERVED)
continue;
- /* ignore TOUCH_DOWN events, might have bogus coordinates */
- if (type == TOUCH_EVENT_DOWN)
+ /* M06 sometimes sends bogus coordinates in TOUCH_DOWN */
+ if (tsdata->version == M06 && type == TOUCH_EVENT_DOWN)
continue;
x = ((buf[0] << 8) | buf[1]) & 0x0fff;
@@ -207,12 +258,25 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
{
u8 wrbuf[4];
- wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
- wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
- wrbuf[2] = value;
- wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
-
- return edt_ft5x06_ts_readwrite(tsdata->client, 4, wrbuf, 0, NULL);
+ switch (tsdata->version) {
+ case M06:
+ wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
+ wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
+ wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
+ wrbuf[2] = value;
+ wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
+ return edt_ft5x06_ts_readwrite(tsdata->client, 4,
+ wrbuf, 0, NULL);
+ case M09:
+ wrbuf[0] = addr;
+ wrbuf[1] = value;
+
+ return edt_ft5x06_ts_readwrite(tsdata->client, 3,
+ wrbuf, 0, NULL);
+
+ default:
+ return -EINVAL;
+ }
}
static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
@@ -221,19 +285,35 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
u8 wrbuf[2], rdbuf[2];
int error;
- wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
- wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
- wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
+ switch (tsdata->version) {
+ case M06:
+ wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
+ wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
+ wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
- error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2, rdbuf);
- if (error)
+ error = edt_ft5x06_ts_readwrite(tsdata->client,
+ 2, wrbuf, 2, rdbuf);
return error;
- if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
- dev_err(&tsdata->client->dev,
- "crc error: 0x%02x expected, got 0x%02x\n",
- wrbuf[0] ^ wrbuf[1] ^ rdbuf[0], rdbuf[1]);
- return -EIO;
+ if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
+ dev_err(&tsdata->client->dev,
+ "crc error: 0x%02x expected, got 0x%02x\n",
+ wrbuf[0] ^ wrbuf[1] ^ rdbuf[0],
+ rdbuf[1]);
+ return -EIO;
+ }
+ break;
+
+ case M09:
+ wrbuf[0] = addr;
+ error = edt_ft5x06_ts_readwrite(tsdata->client, 1,
+ wrbuf, 1, rdbuf);
+ if (error)
+ return error;
+ break;
+
+ default:
+ return -EINVAL;
}
return rdbuf[0];
@@ -244,19 +324,21 @@ struct edt_ft5x06_attribute {
size_t field_offset;
u8 limit_low;
u8 limit_high;
- u8 addr;
+ u8 addr_m06;
+ u8 addr_m09;
};
-#define EDT_ATTR(_field, _mode, _addr, _limit_low, _limit_high) \
+#define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09, \
+ _limit_low, _limit_high) \
struct edt_ft5x06_attribute edt_ft5x06_attr_##_field = { \
.dattr = __ATTR(_field, _mode, \
edt_ft5x06_setting_show, \
edt_ft5x06_setting_store), \
- .field_offset = \
- offsetof(struct edt_ft5x06_ts_data, _field), \
+ .field_offset = offsetof(struct edt_ft5x06_ts_data, _field), \
+ .addr_m06 = _addr_m06, \
+ .addr_m09 = _addr_m09, \
.limit_low = _limit_low, \
.limit_high = _limit_high, \
- .addr = _addr, \
}
static ssize_t edt_ft5x06_setting_show(struct device *dev,
@@ -271,6 +353,7 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
int val;
size_t count = 0;
int error = 0;
+ u8 addr;
mutex_lock(&tsdata->mutex);
@@ -279,15 +362,33 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
goto out;
}
- val = edt_ft5x06_register_read(tsdata, attr->addr);
- if (val < 0) {
- error = val;
- dev_err(&tsdata->client->dev,
- "Failed to fetch attribute %s, error %d\n",
- dattr->attr.name, error);
+ switch (tsdata->version) {
+ case M06:
+ addr = attr->addr_m06;
+ break;
+
+ case M09:
+ addr = attr->addr_m09;
+ break;
+
+ default:
+ error = -ENODEV;
goto out;
}
+ if (addr != NO_REGISTER) {
+ val = edt_ft5x06_register_read(tsdata, addr);
+ if (val < 0) {
+ error = val;
+ dev_err(&tsdata->client->dev,
+ "Failed to fetch attribute %s, error %d\n",
+ dattr->attr.name, error);
+ goto out;
+ }
+ } else {
+ val = *field;
+ }
+
if (val != *field) {
dev_warn(&tsdata->client->dev,
"%s: read (%d) and stored value (%d) differ\n",
@@ -312,6 +413,7 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
u8 *field = (u8 *)tsdata + attr->field_offset;
unsigned int val;
int error;
+ u8 addr;
mutex_lock(&tsdata->mutex);
@@ -329,14 +431,29 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
goto out;
}
- error = edt_ft5x06_register_write(tsdata, attr->addr, val);
- if (error) {
- dev_err(&tsdata->client->dev,
- "Failed to update attribute %s, error: %d\n",
- dattr->attr.name, error);
+ switch (tsdata->version) {
+ case M06:
+ addr = attr->addr_m06;
+ break;
+
+ case M09:
+ addr = attr->addr_m09;
+ break;
+
+ default:
+ error = -ENODEV;
goto out;
}
+ if (addr != NO_REGISTER) {
+ error = edt_ft5x06_register_write(tsdata, addr, val);
+ if (error) {
+ dev_err(&tsdata->client->dev,
+ "Failed to update attribute %s, error: %d\n",
+ dattr->attr.name, error);
+ goto out;
+ }
+ }
*field = val;
out:
@@ -344,12 +461,14 @@ out:
return error ?: count;
}
-static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN, 0, 31);
-static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET, 0, 31);
-static EDT_ATTR(threshold, S_IWUSR | S_IRUGO,
- WORK_REGISTER_THRESHOLD, 20, 80);
-static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO,
- WORK_REGISTER_REPORT_RATE, 3, 14);
+static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN,
+ M09_REGISTER_GAIN, 0, 31);
+static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET,
+ M09_REGISTER_OFFSET, 0, 31);
+static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
+ M09_REGISTER_THRESHOLD, 20, 80);
+static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
+ NO_REGISTER, 3, 14);
static struct attribute *edt_ft5x06_attrs[] = {
&edt_ft5x06_attr_gain.dattr.attr,
@@ -384,6 +503,9 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
}
/* mode register is 0x3c when in the work mode */
+ if (tsdata->version == M09)
+ goto m09_out;
+
error = edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03);
if (error) {
dev_err(&client->dev,
@@ -416,12 +538,18 @@ err_out:
enable_irq(client->irq);
return error;
+
+m09_out:
+ dev_err(&client->dev, "No factory mode support for M09\n");
+ return -EINVAL;
+
}
static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
{
struct i2c_client *client = tsdata->client;
int retries = EDT_SWITCH_MODE_RETRIES;
+ struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
int ret;
int error;
@@ -454,13 +582,14 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
tsdata->raw_buffer = NULL;
/* restore parameters */
- edt_ft5x06_register_write(tsdata, WORK_REGISTER_THRESHOLD,
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold,
tsdata->threshold);
- edt_ft5x06_register_write(tsdata, WORK_REGISTER_GAIN,
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
tsdata->gain);
- edt_ft5x06_register_write(tsdata, WORK_REGISTER_OFFSET,
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
tsdata->offset);
- edt_ft5x06_register_write(tsdata, WORK_REGISTER_REPORT_RATE,
+ if (reg_addr->reg_report_rate)
+ edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
tsdata->report_rate);
enable_irq(client->irq);
@@ -663,30 +792,60 @@ static int edt_ft5x06_ts_reset(struct i2c_client *client,
}
static int edt_ft5x06_ts_identify(struct i2c_client *client,
- char *model_name,
- char *fw_version)
+ struct edt_ft5x06_ts_data *tsdata,
+ char *fw_version)
{
u8 rdbuf[EDT_NAME_LEN];
char *p;
int error;
+ char *model_name = tsdata->name;
+ /* see what we find if we assume it is a M06 *
+ * if we get less than EDT_NAME_LEN, we don't want
+ * to have garbage in there
+ */
+ memset(rdbuf, 0, sizeof(rdbuf));
error = edt_ft5x06_ts_readwrite(client, 1, "\xbb",
EDT_NAME_LEN - 1, rdbuf);
if (error)
return error;
- /* remove last '$' end marker */
- rdbuf[EDT_NAME_LEN - 1] = '\0';
- if (rdbuf[EDT_NAME_LEN - 2] == '$')
- rdbuf[EDT_NAME_LEN - 2] = '\0';
+ /* if we find something consistent, stay with that assumption
+ * at least M09 won't send 3 bytes here
+ */
+ if (!(strnicmp(rdbuf + 1, "EP0", 3))) {
+ tsdata->version = M06;
+
+ /* remove last '$' end marker */
+ rdbuf[EDT_NAME_LEN - 1] = '\0';
+ if (rdbuf[EDT_NAME_LEN - 2] == '$')
+ rdbuf[EDT_NAME_LEN - 2] = '\0';
+
+ /* look for Model/Version separator */
+ p = strchr(rdbuf, '*');
+ if (p)
+ *p++ = '\0';
+ strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
+ strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
+ } else {
+ /* since there are only two versions around (M06, M09) */
+ tsdata->version = M09;
+
+ error = edt_ft5x06_ts_readwrite(client, 1, "\xA6",
+ 2, rdbuf);
+ if (error)
+ return error;
- /* look for Model/Version separator */
- p = strchr(rdbuf, '*');
- if (p)
- *p++ = '\0';
+ strlcpy(fw_version, rdbuf, 2);
- strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
- strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
+ error = edt_ft5x06_ts_readwrite(client, 1, "\xA8",
+ 1, rdbuf);
+ if (error)
+ return error;
+
+ snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0M09",
+ rdbuf[0] >> 4, rdbuf[0] & 0x0F);
+ }
return 0;
}
@@ -705,36 +864,69 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
static void edt_ft5x06_ts_get_dt_defaults(struct device_node *np,
struct edt_ft5x06_ts_data *tsdata)
{
- EDT_GET_PROP(threshold, WORK_REGISTER_THRESHOLD);
- EDT_GET_PROP(gain, WORK_REGISTER_GAIN);
- EDT_GET_PROP(offset, WORK_REGISTER_OFFSET);
+ struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
+
+ EDT_GET_PROP(threshold, reg_addr->reg_threshold);
+ EDT_GET_PROP(gain, reg_addr->reg_gain);
+ EDT_GET_PROP(offset, reg_addr->reg_offset);
}
static void
edt_ft5x06_ts_get_defaults(struct edt_ft5x06_ts_data *tsdata,
const struct edt_ft5x06_platform_data *pdata)
{
+ struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
+
if (!pdata->use_parameters)
return;
/* pick up defaults from the platform data */
- EDT_ATTR_CHECKSET(threshold, WORK_REGISTER_THRESHOLD);
- EDT_ATTR_CHECKSET(gain, WORK_REGISTER_GAIN);
- EDT_ATTR_CHECKSET(offset, WORK_REGISTER_OFFSET);
- EDT_ATTR_CHECKSET(report_rate, WORK_REGISTER_REPORT_RATE);
+ EDT_ATTR_CHECKSET(threshold, reg_addr->reg_threshold);
+ EDT_ATTR_CHECKSET(gain, reg_addr->reg_gain);
+ EDT_ATTR_CHECKSET(offset, reg_addr->reg_offset);
+ if (reg_addr->reg_report_rate != NO_REGISTER)
+ EDT_ATTR_CHECKSET(report_rate, reg_addr->reg_report_rate);
}
static void
edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
{
+ struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
+
tsdata->threshold = edt_ft5x06_register_read(tsdata,
- WORK_REGISTER_THRESHOLD);
- tsdata->gain = edt_ft5x06_register_read(tsdata, WORK_REGISTER_GAIN);
- tsdata->offset = edt_ft5x06_register_read(tsdata, WORK_REGISTER_OFFSET);
- tsdata->report_rate = edt_ft5x06_register_read(tsdata,
- WORK_REGISTER_REPORT_RATE);
- tsdata->num_x = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_X);
- tsdata->num_y = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_Y);
+ reg_addr->reg_threshold);
+ tsdata->gain = edt_ft5x06_register_read(tsdata, reg_addr->reg_gain);
+ tsdata->offset = edt_ft5x06_register_read(tsdata, reg_addr->reg_offset);
+ if (reg_addr->reg_report_rate != NO_REGISTER)
+ tsdata->report_rate = edt_ft5x06_register_read(tsdata,
+ reg_addr->reg_report_rate);
+ tsdata->num_x = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_x);
+ tsdata->num_y = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_y);
+}
+
+static void
+edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
+{
+ struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
+
+ switch (tsdata->version) {
+ case M06:
+ reg_addr->reg_threshold = WORK_REGISTER_THRESHOLD;
+ reg_addr->reg_report_rate = WORK_REGISTER_REPORT_RATE;
+ reg_addr->reg_gain = WORK_REGISTER_GAIN;
+ reg_addr->reg_offset = WORK_REGISTER_OFFSET;
+ reg_addr->reg_num_x = WORK_REGISTER_NUM_X;
+ reg_addr->reg_num_y = WORK_REGISTER_NUM_Y;
+ break;
+
+ case M09:
+ reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
+ reg_addr->reg_gain = M09_REGISTER_GAIN;
+ reg_addr->reg_offset = M09_REGISTER_OFFSET;
+ reg_addr->reg_num_x = M09_REGISTER_NUM_X;
+ reg_addr->reg_num_y = M09_REGISTER_NUM_Y;
+ break;
+ }
}
#ifdef CONFIG_OF
@@ -818,12 +1010,14 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
tsdata->input = input;
tsdata->factory_mode = false;
- error = edt_ft5x06_ts_identify(client, tsdata->name, fw_version);
+ error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
if (error) {
dev_err(&client->dev, "touchscreen probe failed\n");
return error;
}
+ edt_ft5x06_ts_set_regs(tsdata);
+
if (!pdata)
edt_ft5x06_ts_get_dt_defaults(client->dev.of_node, tsdata);
else
--
1.7.10.4
^ permalink raw reply related
* [PATCHv5 4/5] Input: edt-ft5x06: Ignore touchdown events
From: Lothar Waßmann @ 2014-03-20 13:44 UTC (permalink / raw)
To: Dmitry Torokhov, Fugang Duan, Grant Likely, Henrik Rydberg,
Ian Campbell, Jingoo Han, Kumar Gala, Mark Rutland, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat, devicetree, linux-doc,
linux-input, linux-kernel, Simon Budig, Lothar Waßmann,
Daniel Wagener
In-Reply-To: <1395323075-12146-1-git-send-email-LW@KARO-electronics.de>
The chip may report invalid coordinates on touchdown events, so don't
report the initial touchdown event.
Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
drivers/input/touchscreen/edt-ft5x06.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 0298568..565f0cd 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -176,6 +176,10 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
if (type == TOUCH_EVENT_RESERVED)
continue;
+ /* ignore TOUCH_DOWN events, might have bogus coordinates */
+ if (type == TOUCH_EVENT_DOWN)
+ continue;
+
x = ((buf[0] << 8) | buf[1]) & 0x0fff;
y = ((buf[2] << 8) | buf[3]) & 0x0fff;
id = (buf[2] >> 4) & 0x0f;
--
1.7.10.4
^ permalink raw reply related
* [PATCHv5 2/5] Input: edt-ft5x06: Add DT support
From: Lothar Waßmann @ 2014-03-20 13:44 UTC (permalink / raw)
To: Dmitry Torokhov, Fugang Duan, Grant Likely, Henrik Rydberg,
Ian Campbell, Jingoo Han, Kumar Gala, Mark Rutland, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Simon Budig,
Lothar Waßmann, Daniel Wagener
In-Reply-To: <1395323075-12146-1-git-send-email-LW-bxm8fMRDkQLDiMYJYoSAnRvVK+yQ3ZXh@public.gmane.org>
Signed-off-by: Lothar Waßmann <LW-bxm8fMRDkQLDiMYJYoSAnRvVK+yQ3ZXh@public.gmane.org>
---
.../bindings/input/touchscreen/edt-ft5x06.txt | 55 ++++++++
drivers/input/touchscreen/edt-ft5x06.c | 143 +++++++++++++++-----
2 files changed, 167 insertions(+), 31 deletions(-)
create mode 100644 Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
new file mode 100644
index 0000000..76db967
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
@@ -0,0 +1,55 @@
+FocalTech EDT-FT5x06 Polytouch driver
+=====================================
+
+There are 3 variants of the chip for various touch panel sizes
+FT5206GE1 2.8" .. 3.8"
+FT5306DE4 4.3" .. 7"
+FT5406EE8 7" .. 8.9"
+
+The software interface is identical for all those chips, so that
+currently there is no need for the driver to distinguish between the
+different chips. Nevertheless distinct compatible strings are used so
+that a distinction can be added if necessary without changing the DT
+bindings.
+
+
+Required properties:
+ - compatible: "edt,edt-ft5206"
+ or: "edt,edt-ft5306"
+ or: "edt,edt-ft5406"
+
+ - reg: I2C slave address of the chip (0x38)
+ - interrupt-parent: a phandle pointing to the interrupt controller
+ serving the interrupt for this chip
+ - interrupts: interrupt specification for the touchdetect
+ interrupt
+
+Optional properties:
+ - reset-gpios: GPIO specification for the RESET input
+ - wake-gpios: GPIO specification for the WAKE input
+
+ - pinctrl-names: should be "default"
+ - pinctrl-0: a phandle pointing to the pin settings for the
+ control gpios
+
+ - threshold: allows setting the "click"-threshold in the range
+ from 20 to 80.
+
+ - gain: allows setting the sensitivity in the range from 0 to
+ 31. Note that lower values indicate higher
+ sensitivity.
+
+ - offset: allows setting the edge compensation in the range from
+ 0 to 31.
+
+Example:
+ polytouch: edt-ft5x06@38 {
+ compatible = "edt,edt-ft5406", "edt,edt-ft5x06";
+ reg = <0x38>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&edt_ft5x06_pins>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <5 0>;
+ reset-gpios = <&gpio2 6 1>;
+ wake-gpios = <&gpio4 9 0>;
+ };
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 155ab3b..03dab2f 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Simon Budig, <simon.budig-t93Ne7XHvje5bSeCtf/tX7NAH6kLmebB@public.gmane.org>
+ * Lothar Waßmann <LW-bxm8fMRDkQLDiMYJYoSAnRvVK+yQ3ZXh@public.gmane.org> (DT support)
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -33,6 +34,7 @@
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include <linux/input/mt.h>
#include <linux/input/edt-ft5x06.h>
@@ -65,6 +67,10 @@ struct edt_ft5x06_ts_data {
u16 num_x;
u16 num_y;
+ int reset_pin;
+ int irq_pin;
+ int wake_pin;
+
#if defined(CONFIG_DEBUG_FS)
struct dentry *debug_dir;
u8 *raw_buffer;
@@ -614,24 +620,38 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
#endif /* CONFIG_DEBUGFS */
static int edt_ft5x06_ts_reset(struct i2c_client *client,
- int reset_pin)
+ struct edt_ft5x06_ts_data *tsdata)
{
int error;
- if (gpio_is_valid(reset_pin)) {
+ if (gpio_is_valid(tsdata->wake_pin)) {
+ error = devm_gpio_request_one(&client->dev,
+ tsdata->wake_pin, GPIOF_OUT_INIT_LOW,
+ "edt-ft5x06 wake");
+ if (error) {
+ dev_err(&client->dev,
+ "Failed to request GPIO %d as wake pin, error %d\n",
+ tsdata->wake_pin, error);
+ return error;
+ }
+
+ mdelay(5);
+ gpio_set_value(tsdata->wake_pin, 1);
+ }
+ if (gpio_is_valid(tsdata->reset_pin)) {
/* this pulls reset down, enabling the low active reset */
- error = devm_gpio_request_one(&client->dev, reset_pin,
- GPIOF_OUT_INIT_LOW,
- "edt-ft5x06 reset");
+ error = devm_gpio_request_one(&client->dev,
+ tsdata->reset_pin, GPIOF_OUT_INIT_LOW,
+ "edt-ft5x06 reset");
if (error) {
dev_err(&client->dev,
"Failed to request GPIO %d as reset pin, error %d\n",
- reset_pin, error);
+ tsdata->reset_pin, error);
return error;
}
mdelay(50);
- gpio_set_value(reset_pin, 1);
+ gpio_set_value(tsdata->reset_pin, 1);
mdelay(100);
}
@@ -672,6 +692,20 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
pdata->name <= edt_ft5x06_attr_##name.limit_high) \
edt_ft5x06_register_write(tsdata, reg, pdata->name)
+#define EDT_GET_PROP(name, reg) { \
+ u32 val; \
+ if (of_property_read_u32(np, #name, val) == 0) \
+ edt_ft5x06_register_write(tsdata, reg, val); \
+}
+
+static void edt_ft5x06_ts_get_dt_defaults(struct device_node *np,
+ struct edt_ft5x06_ts_data *tsdata)
+{
+ EDT_GET_PROP(threshold, WORK_REGISTER_THRESHOLD);
+ EDT_GET_PROP(gain, WORK_REGISTER_GAIN);
+ EDT_GET_PROP(offset, WORK_REGISTER_OFFSET);
+}
+
static void
edt_ft5x06_ts_get_defaults(struct edt_ft5x06_ts_data *tsdata,
const struct edt_ft5x06_platform_data *pdata)
@@ -699,6 +733,30 @@ edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
tsdata->num_y = edt_ft5x06_register_read(tsdata, WORK_REGISTER_NUM_Y);
}
+#ifdef CONFIG_OF
+static int edt_ft5x06_i2c_ts_probe_dt(struct device *dev,
+ struct edt_ft5x06_ts_data *tsdata)
+{
+ struct device_node *np = dev->of_node;
+
+ /*
+ * irq_pin is not needed for DT setup.
+ * irq is associated via 'interrupts' property in DT
+ */
+ tsdata->irq_pin = -EINVAL;
+ tsdata->reset_pin = of_get_named_gpio(np, "reset-gpios", 0);
+ tsdata->wake_pin = of_get_named_gpio(np, "wake-gpios", 0);
+
+ return 0;
+}
+#else
+static inline int edt_ft5x06_i2c_ts_probe_dt(struct device *dev,
+ struct edt_ft5x06_i2c_ts_data *tsdata)
+{
+ return -ENODEV;
+}
+#endif
+
static int edt_ft5x06_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -711,32 +769,40 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
+ tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL);
+ if (!tsdata) {
+ dev_err(&client->dev, "failed to allocate driver data.\n");
+ return -ENOMEM;
+ }
+
if (!pdata) {
- dev_err(&client->dev, "no platform data?\n");
- return -EINVAL;
+ error = edt_ft5x06_i2c_ts_probe_dt(&client->dev, tsdata);
+ if (error) {
+ dev_err(&client->dev,
+ "DT probe failed and no platform data present\n");
+ return error;
+ }
+ } else {
+ tsdata->reset_pin = pdata->reset_pin;
+ tsdata->irq_pin = pdata->irq_pin;
+ tsdata->wake_pin = -EINVAL;
}
- error = edt_ft5x06_ts_reset(client, pdata->reset_pin);
+ error = edt_ft5x06_ts_reset(client, tsdata);
if (error)
return error;
- if (gpio_is_valid(pdata->irq_pin)) {
- error = devm_gpio_request_one(&client->dev, pdata->irq_pin,
- GPIOF_IN, "edt-ft5x06 irq");
+ if (gpio_is_valid(tsdata->irq_pin)) {
+ error = devm_gpio_request_one(&client->dev, tsdata->irq_pin,
+ GPIOF_IN, "edt-ft5x06 irq");
if (error) {
dev_err(&client->dev,
"Failed to request GPIO %d, error %d\n",
- pdata->irq_pin, error);
+ tsdata->irq_pin, error);
return error;
}
}
- tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL);
- if (!tsdata) {
- dev_err(&client->dev, "failed to allocate driver data.\n");
- return -ENOMEM;
- }
-
input = devm_input_allocate_device(&client->dev);
if (!input) {
dev_err(&client->dev, "failed to allocate input device.\n");
@@ -754,7 +820,11 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
return error;
}
- edt_ft5x06_ts_get_defaults(tsdata, pdata);
+ if (!pdata)
+ edt_ft5x06_ts_get_dt_defaults(client->dev.of_node, tsdata);
+ else
+ edt_ft5x06_ts_get_defaults(tsdata, pdata);
+
edt_ft5x06_ts_get_parameters(tsdata);
dev_dbg(&client->dev,
@@ -784,10 +854,10 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
input_set_drvdata(input, tsdata);
i2c_set_clientdata(client, tsdata);
- error = devm_request_threaded_irq(&client->dev, client->irq,
- NULL, edt_ft5x06_ts_isr,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- client->name, tsdata);
+ error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+ edt_ft5x06_ts_isr,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ client->name, tsdata);
if (error) {
dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
return error;
@@ -798,19 +868,21 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
return error;
error = input_register_device(input);
- if (error) {
- sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
- return error;
- }
+ if (error)
+ goto err_remove_attrs;
edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
device_init_wakeup(&client->dev, 1);
dev_dbg(&client->dev,
- "EDT FT5x06 initialized: IRQ pin %d, Reset pin %d.\n",
- pdata->irq_pin, pdata->reset_pin);
+ "EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n",
+ client->irq, tsdata->wake_pin, tsdata->reset_pin);
return 0;
+
+err_remove_attrs:
+ sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
+ return error;
}
static int edt_ft5x06_ts_remove(struct i2c_client *client)
@@ -854,10 +926,19 @@ static const struct i2c_device_id edt_ft5x06_ts_id[] = {
};
MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
+static const struct of_device_id edt_ft5x06_of_match[] = {
+ { .compatible = "edt,edt-ft5206", },
+ { .compatible = "edt,edt-ft5306", },
+ { .compatible = "edt,edt-ft5406", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
+
static struct i2c_driver edt_ft5x06_ts_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "edt_ft5x06",
+ .of_match_table = edt_ft5x06_of_match,
.pm = &edt_ft5x06_ts_pm_ops,
},
.id_table = edt_ft5x06_ts_id,
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCHv5 1/5] Input: edt-ft5x06: several cleanups; no functional change
From: Lothar Waßmann @ 2014-03-20 13:44 UTC (permalink / raw)
To: Dmitry Torokhov, Fugang Duan, Grant Likely, Henrik Rydberg,
Ian Campbell, Jingoo Han, Kumar Gala, Mark Rutland, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat, devicetree, linux-doc,
linux-input, linux-kernel, Simon Budig, Lothar Waßmann,
Daniel Wagener
In-Reply-To: <1395323075-12146-1-git-send-email-LW@KARO-electronics.de>
- remove redundant parens
- remove redundant type casts
- fix mixed tab/space indentation
Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
drivers/input/touchscreen/edt-ft5x06.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 412a85e..155ab3b 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -173,7 +173,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
x = ((buf[0] << 8) | buf[1]) & 0x0fff;
y = ((buf[2] << 8) | buf[3]) & 0x0fff;
id = (buf[2] >> 4) & 0x0f;
- down = (type != TOUCH_EVENT_UP);
+ down = type != TOUCH_EVENT_UP;
input_mt_slot(tsdata->input, id);
input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, down);
@@ -257,7 +257,7 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
struct edt_ft5x06_attribute *attr =
container_of(dattr, struct edt_ft5x06_attribute, dattr);
- u8 *field = (u8 *)((char *)tsdata + attr->field_offset);
+ u8 *field = (u8 *)tsdata + attr->field_offset;
int val;
size_t count = 0;
int error = 0;
@@ -299,7 +299,7 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
struct edt_ft5x06_attribute *attr =
container_of(dattr, struct edt_ft5x06_attribute, dattr);
- u8 *field = (u8 *)((char *)tsdata + attr->field_offset);
+ u8 *field = (u8 *)tsdata + attr->field_offset;
unsigned int val;
int error;
@@ -479,7 +479,7 @@ static int edt_ft5x06_debugfs_mode_set(void *data, u64 mode)
if (mode != tsdata->factory_mode) {
retval = mode ? edt_ft5x06_factory_mode(tsdata) :
- edt_ft5x06_work_mode(tsdata);
+ edt_ft5x06_work_mode(tsdata);
}
mutex_unlock(&tsdata->mutex);
@@ -568,7 +568,6 @@ out:
return error ?: read;
};
-
static const struct file_operations debugfs_raw_data_fops = {
.open = simple_open,
.read = edt_ft5x06_debugfs_raw_data_read,
@@ -614,8 +613,6 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
#endif /* CONFIG_DEBUGFS */
-
-
static int edt_ft5x06_ts_reset(struct i2c_client *client,
int reset_pin)
{
@@ -852,8 +849,8 @@ static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops,
edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume);
static const struct i2c_device_id edt_ft5x06_ts_id[] = {
- { "edt-ft5x06", 0 },
- { }
+ { "edt-ft5x06", 0, },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv5 0/5] Input: edt-ft5x06: Add DT support
From: Lothar Waßmann @ 2014-03-20 13:44 UTC (permalink / raw)
To: Dmitry Torokhov, Fugang Duan, Grant Likely, Henrik Rydberg,
Ian Campbell, Jingoo Han, Kumar Gala, Mark Rutland, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat, devicetree, linux-doc,
linux-input, linux-kernel, Simon Budig, Lothar Waßmann,
Daniel Wagener
In-Reply-To: <1395234563-11034-1-git-send-email-LW@KARO-electronics.de>
Changes wrt. v1:
addressed the comments from Jingoo Han and Mark Rutland
- added another patch to convert the driver to use devm_* functions
- removed sysfs reference from bindings documentation
- changed '_' to '-' in property name
- added 'edt,' prefix to properties names
- added sanity check for parameters read from DT
- cleaned up the gpio handling code
Changes wrt. v2:
- fixed the devm_* messup reported by Dmitry Torokhov
- added unit for report-rate property to the binding doc
- added separate patch to fix the reset delays
Changes wrt: v3:
- removed patches that have already been applied in the mean time
- ignore touchdown events, since those may report bad coordinates
- added support for a new firmware version
Changes wrt: v4:
- removed some empty lines in the cleanup patch
- addressed comments by Mark Rutland concerning the binding doc
- use of_property_read_u32() instead of of_property_get()
- dropped the 'report_rate' property
- addressed comments by Fugang Duan
- added Daniel Wagener and myself to the Copyright header in the
source file
- use msleep() rather than mdelay() for the reset/wake pin timing
^ permalink raw reply
* Re: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
From: Mark Rutland @ 2014-03-20 13:21 UTC (permalink / raw)
To: Lothar Waßmann
Cc: Dmitry Torokhov, Fugang Duan, grant.likely@linaro.org,
Henrik Rydberg, Ian Campbell, Jingoo Han, Kumar Gala, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat,
devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
Simon Budig
In-Reply-To: <20140320124055.53d469e7@ipc1.ka-ro>
On Thu, Mar 20, 2014 at 11:40:55AM +0000, Lothar Waßmann wrote:
> Hi,
>
> Mark Rutland wrote:
> > On Wed, Mar 19, 2014 at 01:09:20PM +0000, Lothar Waßmann wrote:
> > >
> > > Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
> > > ---
> > > .../bindings/input/touchscreen/edt-ft5x06.txt | 41 ++++++
> > > drivers/input/touchscreen/edt-ft5x06.c | 144 +++++++++++++++-----
> > > 2 files changed, 154 insertions(+), 31 deletions(-)
> > > create mode 100644 Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> > >
> > > diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> > > new file mode 100644
> > > index 0000000..e5adc76
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> > > @@ -0,0 +1,41 @@
> > > +FocalTech EDT-FT5x06 Polytouch driver
> > > +=====================================
> > > +
> > > +Required properties:
> > > + - compatible: "edt,edt-ft5x06"
> >
> > Is the 'x' part of a particular product name, or is this a class of
> > devices?
> >
> The FT5x06 datasheet lists 3 variants for different panel sizes.
> I'll add distinct compatible strings for those chips, though their SW
> interface is (currently) identical:
> |Required properties:
> | - compatible: "edt,edt-ft5206", "edt,edt-ft5x06"
> | or: "edt,edt-ft5306", "edt,edt-ft5x06"
> | or: "edt,edt-ft5406", "edt,edt-ft5x06"
Drop the "edt,edt-ft5x06" string. If they really appear to be identical
from a programmer's perspective, choose a particular variant to be used
as the fallback.
There could be a future variant that would appear to match the x string
yet was completely incompatible with the expected programming interface.
> > > + - reg: I2C slave address of the chip (0x38)
> > > + - interrupt-parent: a phandle pointing to the interrupt controller
> > > + serving the interrupt for this chip
> > > + - interrupts: interrupt specification for this chip
> >
> > How many? What are they for?
> >
> I'll change it to:
> | - interrupts: interrupt specification for the touchdetect
> | interrupt
That sounds fine to me.
> > > + - report_rate: allows setting the report rate in the range from 3 to
> > > + 14.
> >
> > However, why can the kernel not decide the report rate? This doesn't
> > sound like something that needs to vary per-board.
> >
> > Also, s/_/-/ in property names, please.
> >
> OK, I'll drop the property, which also simplyfies the code a bit.
Sounds good to me.
>
> > > +#define EDT_GET_PROP(name, reg) { \
> > > + const u32 *prop = of_get_property(np, #name, NULL); \
> > > + if (prop) \
> > > + edt_ft5x06_register_write(tsdata, reg, be32_to_cpu(*prop)); \
> > > +}
> >
> > Use of_property_read_u32, it'll handle endianness conversion for you.
> >
> > Use of of_get_property is almost always wrong.
> >
> Sure.
Cheers,
Mark.
^ permalink raw reply
* Re: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
From: Mark Rutland @ 2014-03-20 13:19 UTC (permalink / raw)
To: Simon Budig
Cc: Lothar Waßmann, Dmitry Torokhov, Fugang Duan,
grant.likely@linaro.org, Henrik Rydberg, Ian Campbell, Jingoo Han,
Kumar Gala, Pawel Moll, Rob Herring, Rob Landley, Sachin Kamat,
devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <532ACE72.6030807@kernelconcepts.de>
On Thu, Mar 20, 2014 at 11:18:10AM +0000, Simon Budig wrote:
> On 20/03/14 10:37, Mark Rutland wrote:
> > On Wed, Mar 19, 2014 at 01:09:20PM +0000, Lothar Waßmann wrote:
> >> +FocalTech EDT-FT5x06 Polytouch driver
> >> +=====================================
> >> +
> >> +Required properties:
> >> + - compatible: "edt,edt-ft5x06"
> >
> > Is the 'x' part of a particular product name, or is this a class of
> > devices?
>
> The driver is intended for the EDT "polytouch" family touches, which are
> based on a focaltec controller. The current line of touches uses e.g.
> the ft5306 as well as the ft5406 focaltec controller.
Ok. The name of the driver and the strings used in DT bindings don't
have to be the same. The bindings strings should describe the hardware
as accurately as possible.
>
> > It's preferable to have a specific string which another similar variants
> > can claim compatibility with (while also additionally having a more
> > specific string), as this makes it possible to handle variants more
> > specially in future, target workarounds, etc.
>
> I chose the driver name since I wanted to differentiate from other EDT
> touches, which used a different controller. With hindsight it was
> unfortunately confusing, since I get quite some request from people, who
> also have a device based on the focaltec controllers, but with a very
> different firmware (and communication protocol). They got tricked into
> thinking that this driver would be suitable...
>
> If I were to chose the name again I'd probably pick "edt-polytouch" or
> something like this. But I doubt that it is useful to change the name now.
I'm not arguing to rename the driver. All I want are the compatible
strings to be as specific as possible.
Cheers,
Mark.
^ permalink raw reply
* [PATCH 0/2] input/serio: Add a firmware_id sysfs attribute
From: Hans de Goede @ 2014-03-20 10:12 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Matthew Garrett, Benjamin Tissoires, Peter Hutterer,
platform-driver-x86, linux-input
Hi All,
For firmware instantiated serio devices, such as devices instantiated
through ACPI, it may be useful for userspace to know the firmware-id
(pnp-id in case of ACPI) through which the device was instantiated.
One concrete example of this is the new ps/2 touchpads found in Lenovo
Thinkpad X240 T440 and T540 laptops, which not only have a special
bottom right click area to emulate right clicks, but also top middle
and top right areas to emulate middle and right clicks for the trackpoint.
Lenove has given these touchpads a unique LENxxxx pnp-id and we would like
to use this to automatically enable emulation of middle and right buttons
in the top area of the clickpad.
Matthew Garret wrote a patch to set the parent of the serio port to the
/sys/devices/pnp0/00:xx device so that we could get the necessary info that
way, but Dmitry rightfully pointed out that that would break suspend/resume
ordering, see:
https://lkml.org/lkml/2014/2/23/63
https://lkml.org/lkml/2014/3/7/428
So while discussing this with Peter Hutterer I made the plan to add a
/dev/devices/platform/i8042/serioX/firmware_parent symlink pointing to the
relevant /sys/devices/pnp0/00:xx device, and add a little udev-helper + rules
file to read this symlink and add an attribute to the udevdb with the
pnp-id this way.
This however is harder then it sounds, I spend a couple of hours on how
to do this in a race free manner and I could not come up with one. The
problem is that the sysfs_create_symlink call needs to be done after the
device_add call, at which point an add uevent has already been fired.
Causing a theoretical race where the udev-helper would not find the symlink,
this can be fixed with an extra change event after adding the symlink, but
then any higher userspace levels need to re-check on a change event as well.
So after spending too much time on this I decided to go for an alternative
solution.
Which in the end turns out to be much nicer too, since it gets rid of needing
a udev-helper too. After this much too long introduction I'll let the patches
speak for themselves.
With this patch-set one can now do:
[hans@shalem linux]$ udevadm info -p /devices/platform/i8042/serio1
P: /devices/platform/i8042/serio1
E: DEVPATH=/devices/platform/i8042/serio1
E: MODALIAS=serio:ty01pr00id00ex00
E: SERIO_EXTRA=00
E: SERIO_FIRMWARE_ID=PNP0f03 PNP0f13
E: SERIO_ID=00
E: SERIO_PROTO=00
E: SERIO_TYPE=01
E: SUBSYSTEM=serio
And the info we need is just there in the new SERIO_FIRMWARE_ID attribute,
for completeness the patch-set also adds:
[hans@shalem linux]$ cat /sys/devices/platform/i8042/serio1/firmware_id
PNP0f03 PNP0f13
Regards,
Hans
^ permalink raw reply
* Re: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
From: Lothar Waßmann @ 2014-03-20 12:05 UTC (permalink / raw)
To: Simon Budig
Cc: Mark Rutland, Dmitry Torokhov, Fugang Duan,
grant.likely@linaro.org, Henrik Rydberg, Ian Campbell, Jingoo Han,
Kumar Gala, Pawel Moll, Rob Herring, Rob Landley, Sachin Kamat,
devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <532AD571.9000907@kernelconcepts.de>
Hi,
Simon Budig wrote:
> On 20/03/14 12:40, Lothar Waßmann wrote:
> > The FT5x06 datasheet lists 3 variants for different panel sizes.
> > I'll add distinct compatible strings for those chips, though their SW
> > interface is (currently) identical:
> > |Required properties:
> > | - compatible: "edt,edt-ft5206", "edt,edt-ft5x06"
> > | or: "edt,edt-ft5306", "edt,edt-ft5x06"
> > | or: "edt,edt-ft5406", "edt,edt-ft5x06"
>
> Please note that the M09 variants of the polytouch family will use the
> same chips, but a different sw protocol (see Patch 5/5).
>
The firmware version can be detected by SW, thus there is no need to
distinguish it via DT.
> I don't know anything about the naming scheme used in the device tree,
> but I am not sure if the chip-ID is actually useful here.
>
Since the chip variants handle different panel sizes, it might be useful
to be able to distinguish them.
Lothar Waßmann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________
^ permalink raw reply
* Re: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
From: Simon Budig @ 2014-03-20 11:48 UTC (permalink / raw)
To: Lothar Waßmann, Mark Rutland
Cc: Dmitry Torokhov, Fugang Duan, grant.likely@linaro.org,
Henrik Rydberg, Ian Campbell, Jingoo Han, Kumar Gala, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat,
devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20140320124055.53d469e7@ipc1.ka-ro>
[-- Attachment #1: Type: text/plain, Size: 901 bytes --]
On 20/03/14 12:40, Lothar Waßmann wrote:
> The FT5x06 datasheet lists 3 variants for different panel sizes.
> I'll add distinct compatible strings for those chips, though their SW
> interface is (currently) identical:
> |Required properties:
> | - compatible: "edt,edt-ft5206", "edt,edt-ft5x06"
> | or: "edt,edt-ft5306", "edt,edt-ft5x06"
> | or: "edt,edt-ft5406", "edt,edt-ft5x06"
Please note that the M09 variants of the polytouch family will use the
same chips, but a different sw protocol (see Patch 5/5).
I don't know anything about the naming scheme used in the device tree,
but I am not sure if the chip-ID is actually useful here.
Bye,
Simon
--
Simon Budig kernel concepts GmbH
simon.budig@kernelconcepts.de Sieghuetter Hauptweg 48
+49-271-771091-17 D-57072 Siegen
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]
^ permalink raw reply
* [PATCH 1/2] input/serio: Add a firmware_id sysfs attribute
From: Hans de Goede @ 2014-03-20 10:12 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Matthew Garrett, Benjamin Tissoires, Peter Hutterer,
platform-driver-x86, linux-input, Hans de Goede
In-Reply-To: <1395310330-3232-1-git-send-email-hdegoede@redhat.com>
serio devices exposed via platform firmware interfaces such as ACPI
may provide additional identifying information of use to userspace.
We don't associate the serio devices with the firmware device (we don't
set it as parent), so there's no way for userspace to make use of this
information.
We cannot change the parent for serio devices instantiated though a firmware
interface as that would break suspend / resume ordering.
Therefor this patch adds a new firmware_id sysfs attribute so that userspace
can get a string from there with any additional identifying information the
firmware interface may provide.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/input/serio/serio.c | 12 ++++++++++++
include/linux/serio.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 8f4c4ab..1788a4d 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -451,6 +451,13 @@ static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute *
return retval;
}
+static ssize_t firmware_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct serio *serio = to_serio_port(dev);
+
+ return sprintf(buf, "%s\n", serio->firmware_id);
+}
+
static DEVICE_ATTR_RO(type);
static DEVICE_ATTR_RO(proto);
static DEVICE_ATTR_RO(id);
@@ -473,12 +480,14 @@ static DEVICE_ATTR_RO(modalias);
static DEVICE_ATTR_WO(drvctl);
static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);
static DEVICE_ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode);
+static DEVICE_ATTR_RO(firmware_id);
static struct attribute *serio_device_attrs[] = {
&dev_attr_modalias.attr,
&dev_attr_description.attr,
&dev_attr_drvctl.attr,
&dev_attr_bind_mode.attr,
+ &dev_attr_firmware_id.attr,
NULL
};
@@ -923,6 +932,9 @@ static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
+ if (serio->firmware_id[0])
+ SERIO_ADD_UEVENT_VAR("SERIO_FIRMWARE_ID=%s",
+ serio->firmware_id);
return 0;
}
diff --git a/include/linux/serio.h b/include/linux/serio.h
index 36aac73..9f779c7 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -23,6 +23,7 @@ struct serio {
char name[32];
char phys[32];
+ char firmware_id[128];
bool manual_bind;
--
1.9.0
^ permalink raw reply related
* Re: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
From: Lothar Waßmann @ 2014-03-20 11:44 UTC (permalink / raw)
To: fugang.duan@freescale.com
Cc: Dmitry Torokhov, Grant Likely, Henrik Rydberg, Ian Campbell,
Jingoo Han, Kumar Gala, Mark Rutland, Pawel Moll, Rob Herring,
Rob Landley, Sachin Kamat, devicetree@vger.kernel.org,
linux-doc@vger.kernel.org, linux-input@vger.kernel.org,
linux-kernel@vger.kernel.org, Simon Budig
In-Reply-To: <c9718f7215eb41439606b0107a8e2a02@BLUPR03MB373.namprd03.prod.outlook.com>
Hi,
fugang.duan@freescale.com wrote:
> From: Lothar Waßmann <LW@KARO-electronics.de>
> Data: Wednesday, March 19, 2014 9:09 PM
>
> >To: Dmitry Torokhov; Duan Fugang-B38611; Grant Likely; Henrik Rydberg; Ian
> >Campbell; Jingoo Han; Kumar Gala; Mark Rutland; Pawel Moll; Rob Herring; Rob
> >Landley; Sachin Kamat; devicetree@vger.kernel.org; linux-doc@vger.kernel.org;
> >linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Simon Budig; Lothar
> >Waßmann
> >Subject: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
> >
> >
No need to quote the mail headers here.
[...]
> >diff --git a/drivers/input/touchscreen/edt-ft5x06.c
> >b/drivers/input/touchscreen/edt-ft5x06.c
> >index 7b4470d..257a1c8 100644
> >--- a/drivers/input/touchscreen/edt-ft5x06.c
> >+++ b/drivers/input/touchscreen/edt-ft5x06.c
> >@@ -33,6 +33,7 @@
> > #include <linux/debugfs.h>
> > #include <linux/slab.h>
> > #include <linux/gpio.h>
> >+#include <linux/of_gpio.h>
> > #include <linux/input/mt.h>
> > #include <linux/input/edt-ft5x06.h>
> >
> [...]
> >+#ifdef CONFIG_OF
> >+static int edt_ft5x06_i2c_ts_probe_dt(struct device *dev,
> >+ struct edt_ft5x06_ts_data *tsdata)
> >+{
> >+ struct device_node *np = dev->of_node;
> >+
> >+ if (!np)
> >+ return -ENODEV;
> Don't need to check the device node valid. If the device node is not existed, the driver don't run probe.
>
Perfectly right. I'll drop this in the next version.
Lothar Waßmann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________
^ permalink raw reply
* Re: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
From: Lothar Waßmann @ 2014-03-20 11:40 UTC (permalink / raw)
To: Mark Rutland
Cc: Dmitry Torokhov, Fugang Duan, grant.likely@linaro.org,
Henrik Rydberg, Ian Campbell, Jingoo Han, Kumar Gala, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat,
devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
Simon Budig
In-Reply-To: <20140320093719.GB14420@e106331-lin.cambridge.arm.com>
Hi,
Mark Rutland wrote:
> On Wed, Mar 19, 2014 at 01:09:20PM +0000, Lothar Waßmann wrote:
> >
> > Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
> > ---
> > .../bindings/input/touchscreen/edt-ft5x06.txt | 41 ++++++
> > drivers/input/touchscreen/edt-ft5x06.c | 144 +++++++++++++++-----
> > 2 files changed, 154 insertions(+), 31 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> >
> > diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> > new file mode 100644
> > index 0000000..e5adc76
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> > @@ -0,0 +1,41 @@
> > +FocalTech EDT-FT5x06 Polytouch driver
> > +=====================================
> > +
> > +Required properties:
> > + - compatible: "edt,edt-ft5x06"
>
> Is the 'x' part of a particular product name, or is this a class of
> devices?
>
The FT5x06 datasheet lists 3 variants for different panel sizes.
I'll add distinct compatible strings for those chips, though their SW
interface is (currently) identical:
|Required properties:
| - compatible: "edt,edt-ft5206", "edt,edt-ft5x06"
| or: "edt,edt-ft5306", "edt,edt-ft5x06"
| or: "edt,edt-ft5406", "edt,edt-ft5x06"
> > + - reg: I2C slave address of the chip (0x38)
> > + - interrupt-parent: a phandle pointing to the interrupt controller
> > + serving the interrupt for this chip
> > + - interrupts: interrupt specification for this chip
>
> How many? What are they for?
>
I'll change it to:
| - interrupts: interrupt specification for the touchdetect
| interrupt
> > + - report_rate: allows setting the report rate in the range from 3 to
> > + 14.
>
> However, why can the kernel not decide the report rate? This doesn't
> sound like something that needs to vary per-board.
>
> Also, s/_/-/ in property names, please.
>
OK, I'll drop the property, which also simplyfies the code a bit.
> > +#define EDT_GET_PROP(name, reg) { \
> > + const u32 *prop = of_get_property(np, #name, NULL); \
> > + if (prop) \
> > + edt_ft5x06_register_write(tsdata, reg, be32_to_cpu(*prop)); \
> > +}
>
> Use of_property_read_u32, it'll handle endianness conversion for you.
>
> Use of of_get_property is almost always wrong.
>
Sure.
Lothar Waßmann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________
^ permalink raw reply
* Re: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
From: Simon Budig @ 2014-03-20 11:18 UTC (permalink / raw)
To: Mark Rutland, Lothar Waßmann
Cc: Dmitry Torokhov, Fugang Duan,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
Henrik Rydberg, Ian Campbell, Jingoo Han, Kumar Gala, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20140320093719.GB14420-NuALmloUBlrZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1633 bytes --]
On 20/03/14 10:37, Mark Rutland wrote:
> On Wed, Mar 19, 2014 at 01:09:20PM +0000, Lothar Waßmann wrote:
>> +FocalTech EDT-FT5x06 Polytouch driver
>> +=====================================
>> +
>> +Required properties:
>> + - compatible: "edt,edt-ft5x06"
>
> Is the 'x' part of a particular product name, or is this a class of
> devices?
The driver is intended for the EDT "polytouch" family touches, which are
based on a focaltec controller. The current line of touches uses e.g.
the ft5306 as well as the ft5406 focaltec controller.
> It's preferable to have a specific string which another similar variants
> can claim compatibility with (while also additionally having a more
> specific string), as this makes it possible to handle variants more
> specially in future, target workarounds, etc.
I chose the driver name since I wanted to differentiate from other EDT
touches, which used a different controller. With hindsight it was
unfortunately confusing, since I get quite some request from people, who
also have a device based on the focaltec controllers, but with a very
different firmware (and communication protocol). They got tricked into
thinking that this driver would be suitable...
If I were to chose the name again I'd probably pick "edt-polytouch" or
something like this. But I doubt that it is useful to change the name now.
Bye,
Simon
--
Simon Budig kernel concepts GmbH
simon.budig-t93Ne7XHvje5bSeCtf/tX7NAH6kLmebB@public.gmane.org Sieghuetter Hauptweg 48
+49-271-771091-17 D-57072 Siegen
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]
^ permalink raw reply
* [PATCH 2/2] input/serio/8042: Add firmware_id support
From: Hans de Goede @ 2014-03-20 10:12 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Matthew Garrett, Benjamin Tissoires, Peter Hutterer,
platform-driver-x86, linux-input, Hans de Goede
In-Reply-To: <1395310330-3232-1-git-send-email-hdegoede@redhat.com>
Fill in the new serio firmware_id sysfs attribute for pnp instantiated
8042 serio ports.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/input/serio/i8042-x86ia64io.h | 26 ++++++++++++++++++++++++++
drivers/input/serio/i8042.c | 6 ++++++
2 files changed, 32 insertions(+)
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 0ec9abb..3f9da83 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -704,6 +704,8 @@ static char i8042_pnp_aux_name[32];
static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
{
+ struct pnp_id *id = dev->id;
+
if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
i8042_pnp_data_reg = pnp_port_start(dev,0);
@@ -719,6 +721,17 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
}
+ if (id) {
+ strlcpy(i8042_kbd_firmware_id, id->id,
+ sizeof(i8042_kbd_firmware_id));
+ for (id = id->next; id; id = id->next) {
+ strlcat(i8042_kbd_firmware_id, " ",
+ sizeof(i8042_kbd_firmware_id));
+ strlcat(i8042_kbd_firmware_id, id->id,
+ sizeof(i8042_kbd_firmware_id));
+ }
+ }
+
/* Keyboard ports are always supposed to be wakeup-enabled */
device_set_wakeup_enable(&dev->dev, true);
@@ -728,6 +741,8 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
{
+ struct pnp_id *id = dev->id;
+
if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
i8042_pnp_data_reg = pnp_port_start(dev,0);
@@ -743,6 +758,17 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *
strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
}
+ if (id) {
+ strlcpy(i8042_aux_firmware_id, id->id,
+ sizeof(i8042_aux_firmware_id));
+ for (id = id->next; id; id = id->next) {
+ strlcat(i8042_aux_firmware_id, " ",
+ sizeof(i8042_aux_firmware_id));
+ strlcat(i8042_aux_firmware_id, id->id,
+ sizeof(i8042_aux_firmware_id));
+ }
+ }
+
i8042_pnp_aux_devices++;
return 0;
}
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 020053f..3807c3e 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -87,6 +87,8 @@ MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
#endif
static bool i8042_bypass_aux_irq_test;
+static char i8042_kbd_firmware_id[128];
+static char i8042_aux_firmware_id[128];
#include "i8042.h"
@@ -1218,6 +1220,8 @@ static int __init i8042_create_kbd_port(void)
serio->dev.parent = &i8042_platform_device->dev;
strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
+ strlcpy(serio->firmware_id, i8042_kbd_firmware_id,
+ sizeof(serio->firmware_id));
port->serio = serio;
port->irq = I8042_KBD_IRQ;
@@ -1244,6 +1248,8 @@ static int __init i8042_create_aux_port(int idx)
if (idx < 0) {
strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name));
strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+ strlcpy(serio->firmware_id, i8042_aux_firmware_id,
+ sizeof(serio->firmware_id));
serio->close = i8042_port_close;
} else {
snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx);
--
1.9.0
^ permalink raw reply related
* Re: [PATCHv4 2/5] Input: edt-ft5x06: Add DT support
From: Mark Rutland @ 2014-03-20 9:37 UTC (permalink / raw)
To: Lothar Waßmann
Cc: Dmitry Torokhov, Fugang Duan, grant.likely@linaro.org,
Henrik Rydberg, Ian Campbell, Jingoo Han, Kumar Gala, Pawel Moll,
Rob Herring, Rob Landley, Sachin Kamat,
devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
Simon Budig
In-Reply-To: <1395234563-11034-3-git-send-email-LW@KARO-electronics.de>
On Wed, Mar 19, 2014 at 01:09:20PM +0000, Lothar Waßmann wrote:
>
> Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
> ---
> .../bindings/input/touchscreen/edt-ft5x06.txt | 41 ++++++
> drivers/input/touchscreen/edt-ft5x06.c | 144 +++++++++++++++-----
> 2 files changed, 154 insertions(+), 31 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
>
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> new file mode 100644
> index 0000000..e5adc76
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> @@ -0,0 +1,41 @@
> +FocalTech EDT-FT5x06 Polytouch driver
> +=====================================
> +
> +Required properties:
> + - compatible: "edt,edt-ft5x06"
Is the 'x' part of a particular product name, or is this a class of
devices?
It's preferable to have a specific string which another similar variants
can claim compatibility with (while also additionally having a more
specific string), as this makes it possible to handle variants more
specially in future, target workarounds, etc.
> + - reg: I2C slave address of the chip (0x38)
> + - interrupt-parent: a phandle pointing to the interrupt controller
> + serving the interrupt for this chip
> + - interrupts: interrupt specification for this chip
How many? What are they for?
> +
> +Optional properties:
> + - reset-gpios: GPIO specification for the RESET input
> + - wake-gpios: GPIO specification for the WAKE input
> +
> + - pinctrl-names: should be "default"
> + - pinctrl-0: a phandle pointing to the pin settings for the
> + control gpios
These all looks fine.
> +
> + - threshold: allows setting the "click"-threshold in the range
> + from 20 to 80.
> +
> + - gain: allows setting the sensitivity in the range from 0 to
> + 31. Note that lower values indicate higher
> + sensitivity.
> +
> + - offset: allows setting the edge compensation in the range from
> + 0 to 31.
I can see why the sane values for these may differ between boards.
> + - report_rate: allows setting the report rate in the range from 3 to
> + 14.
However, why can the kernel not decide the report rate? This doesn't
sound like something that needs to vary per-board.
Also, s/_/-/ in property names, please.
[...]
> +#define EDT_GET_PROP(name, reg) { \
> + const u32 *prop = of_get_property(np, #name, NULL); \
> + if (prop) \
> + edt_ft5x06_register_write(tsdata, reg, be32_to_cpu(*prop)); \
> +}
Use of_property_read_u32, it'll handle endianness conversion for you.
Use of of_get_property is almost always wrong.
Cheers,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] HID: multitouch: add support for Win 8.1 multitouch touchpads
From: Jiri Kosina @ 2014-03-20 9:02 UTC (permalink / raw)
To: Andrew Duggan; +Cc: benjamin.tissoires, linux-input, rydberg
In-Reply-To: <1395261543-3103-1-git-send-email-aduggan@synaptics.com>
On Wed, 19 Mar 2014, Andrew Duggan wrote:
> Multitouch touchpads built for Win 8.1 need to be sent an input mode feature report
> in order to start reporting multitouch events. This is the same process sent
> to Win 7 multitouch touchscreens except the value of the feature report is 3 for
> touchpads.
>
> Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox