* Re: [PATCH 2/4] HID: sony: Use standard output reports instead of raw reports to send data to the Dualshock 4.
From: David Herrmann @ 2014-01-17 11:09 UTC (permalink / raw)
To: Frank Praznik; +Cc: open list:HID CORE LAYER, Jiri Kosina
In-Reply-To: <alpine.DEB.2.10.1401162134560.15779@franz-virtual-machine>
Hi
On Fri, Jan 17, 2014 at 3:42 AM, Frank Praznik <frank.praznik@oh.rr.com> wrote:
> Use regular HID output reports instead of raw reports in the
> dualshock4_state_worker function. (Thanks Simon Mungewell)
This description is actually wrong. hid_output_raw_report() is used
for regular HID output reports. What you do, is using SET_REPORT to
synchronously set output-reports. Anyhow, see below for comments.
> Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
>
> ---
>
> Apply against jikos/hid.git/for-3.14/sony
>
> drivers/hid/hid-sony.c | 45 ++++++++++++++++++++++++++++-----------------
> 1 file changed, 28 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
> index 2f992e1..e623131 100644
> --- a/drivers/hid/hid-sony.c
> +++ b/drivers/hid/hid-sony.c
> @@ -664,28 +664,39 @@ static void sixaxis_state_worker(struct work_struct *work)
> static void dualshock4_state_worker(struct work_struct *work)
> {
> struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
> - unsigned char buf[] = {
> - 0x05,
> - 0x03, 0x00, 0x00, 0x00, 0x00,
> - 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x00, 0x00, 0x00, 0x00, 0x00,
> - 0x00,
> - };
> + struct hid_device *hdev = sc->hdev;
> + struct list_head *head, *list;
> + struct hid_report *report;
> + __s32 *value;
> +
> + list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list;
> +
> + list_for_each(head, list) {
> + report = list_entry(head, struct hid_report, list);
> +
> + /* Report 5 is used to send data to the controller via USB */
> + if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && report->id == 5)
> + break;
> + }
> +
> + if (head == list) {
> + hid_err(hdev, "Dualshock 4 output report not found\n");
Are you sure you want to print this error on *every* invokation? I'd
rather like to see this "list_for_each()" in ->probe() and then print
the error once. In ->probe() after you called hid_parse(), the
report-descriptor will not get changed again so it's safe to cache the
report pointer there. At least I don't know any code-path where we'd
change it again. Maybe @Jiri can confirm that.
I'd also like to see a safety check that the given report is long
enough. Otherwise, you might write out of buffer bounds below. But you
can do all this in ->probe().
Thanks
David
> + return;
> + }
> +
> + value = report->field[0]->value;
> + value[0] = 0x03;
>
> #ifdef CONFIG_SONY_FF
> - buf[4] = sc->right;
> - buf[5] = sc->left;
> + value[3] = sc->right;
> + value[4] = sc->left;
> #endif
>
> - buf[6] = sc->led_state[0];
> - buf[7] = sc->led_state[1];
> - buf[8] = sc->led_state[2];
> + value[5] = sc->led_state[0];
> + value[6] = sc->led_state[1];
> + value[7] = sc->led_state[2];
>
> - sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf),
> - HID_OUTPUT_REPORT);
> + hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
> }
>
> #ifdef CONFIG_SONY_FF
> --
> 1.8.3.2
>
> --
> 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 0/4] HID: sony: Additional fixes and improvements for the Dualshock 4
From: Jiri Kosina @ 2014-01-17 9:48 UTC (permalink / raw)
To: Frank Praznik; +Cc: linux-input
In-Reply-To: <alpine.DEB.2.10.1401162110240.15779@franz-virtual-machine>
On Thu, 16 Jan 2014, Frank Praznik wrote:
> These series of patches makes some fixes and improvements to the Dualshock
> 4 driver.
Applied.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 1/5] HID: logitech-dj: Fix USB 3.0 issue
From: Nestor Lopez Casado @ 2014-01-17 8:48 UTC (permalink / raw)
To: Jiri Kosina
Cc: Benjamin Tissoires, Benjamin Tissoires, Andrew de los Reyes,
open list:HID CORE LAYER, linux-kernel@vger.kernel.org
In-Reply-To: <alpine.LNX.2.00.1401162249150.23018@pobox.suse.cz>
On Thu, Jan 16, 2014 at 10:50 PM, Jiri Kosina <jkosina@suse.cz> wrote:
> On Wed, 8 Jan 2014, Benjamin Tissoires wrote:
>
>> From: Benjamin Tisssoires <benjamin.tissoires@redhat.com>
>>
>> This fix (not very clean though) should fix the long time USB3
>> issue that was spotted last year. The rational has been given by
>> Hans de Goede:
>
> Man this is so ugly ... makes one wonder how come that other OSes don't
> suffer from this. Are they really *that much* slower? :)
>
> I have applied this (and just this) one for 3.14.
This is clearly a workaround for an underlying bug.
Most probably the issue is in the receiver firmware, and the bug
happens to become apparent easier when it is plugged in a usb 3.0
port.
We are experiencing some issues when the receiver is plugged to usb
3.0 ports in other OSes as well, these could also be explained by the
same phenomenon of vendor requests being missed by the receiver. But
we dont have a clear understanding of the problem yet.
>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
Cheers,
-nestor
^ permalink raw reply
* [PATCH 4/4] HID: sony: Map gyroscopes and accelerometers to axes
From: Frank Praznik @ 2014-01-17 2:43 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina
Use a modified HID descriptor for the Dualshock 4 to assign the gyroscope
sensors and accelerometers to axes.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
Apply against jikos/hid.git/for-3.14/sony
drivers/hid/hid-sony.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index a7c8167..225a4cf 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -73,6 +73,73 @@ static const u8 sixaxis_rdesc_fixup2[] = {
0xb1, 0x02, 0xc0, 0xc0,
};
+static u8 dualshock4_usb_rdesc[] = {
+ 0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01,
+ 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35,
+ 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
+ 0x04, 0x81, 0x02, 0x09, 0x39, 0x15, 0x00, 0x25,
+ 0x07, 0x35, 0x00, 0x46, 0x3b, 0x01, 0x65, 0x14,
+ 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x65, 0x00,
+ 0x05, 0x09, 0x19, 0x01, 0x29, 0x0e, 0x15, 0x00,
+ 0x25, 0x01, 0x75, 0x01, 0x95, 0x0e, 0x81, 0x02,
+ 0x06, 0x00, 0xff, 0x09, 0x20, 0x75, 0x06, 0x95,
+ 0x01, 0x15, 0x00, 0x25, 0x7f, 0x81, 0x02, 0x05,
+ 0x01, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x26,
+ 0xff, 0x00, 0x75, 0x08, 0x95, 0x02, 0x81, 0x02,
+ 0x06, 0x00, 0xff, 0x09, 0x21, 0x95, 0x03, 0x81,
+ 0x02, 0x05, 0x01, 0x19, 0x40, 0x29, 0x42, 0x16,
+ 0x00, 0x80, 0x26, 0x00, 0x7f, 0x75, 0x10, 0x95,
+ 0x03, 0x81, 0x02, 0x05, 0x01, 0x19, 0x43, 0x29,
+ 0x45, 0x16, 0xff, 0xbf, 0x26, 0x00, 0x40, 0x95,
+ 0x03, 0x81, 0x02, 0x06, 0x00, 0xff, 0x09, 0x21,
+ 0x75, 0x08, 0x95, 0x27, 0x81, 0x02, 0x85, 0x05,
+ 0x09, 0x22, 0x95, 0x1f, 0x91, 0x02, 0x85, 0x04,
+ 0x09, 0x23, 0x95, 0x24, 0xb1, 0x02, 0x85, 0x02,
+ 0x09, 0x24, 0x95, 0x24, 0xb1, 0x02, 0x85, 0x08,
+ 0x09, 0x25, 0x95, 0x03, 0xb1, 0x02, 0x85, 0x10,
+ 0x09, 0x26, 0x95, 0x04, 0xb1, 0x02, 0x85, 0x11,
+ 0x09, 0x27, 0x95, 0x02, 0xb1, 0x02, 0x85, 0x12,
+ 0x06, 0x02, 0xff, 0x09, 0x21, 0x95, 0x0f, 0xb1,
+ 0x02, 0x85, 0x13, 0x09, 0x22, 0x95, 0x16, 0xb1,
+ 0x02, 0x85, 0x14, 0x06, 0x05, 0xff, 0x09, 0x20,
+ 0x95, 0x10, 0xb1, 0x02, 0x85, 0x15, 0x09, 0x21,
+ 0x95, 0x2c, 0xb1, 0x02, 0x06, 0x80, 0xff, 0x85,
+ 0x80, 0x09, 0x20, 0x95, 0x06, 0xb1, 0x02, 0x85,
+ 0x81, 0x09, 0x21, 0x95, 0x06, 0xb1, 0x02, 0x85,
+ 0x82, 0x09, 0x22, 0x95, 0x05, 0xb1, 0x02, 0x85,
+ 0x83, 0x09, 0x23, 0x95, 0x01, 0xb1, 0x02, 0x85,
+ 0x84, 0x09, 0x24, 0x95, 0x04, 0xb1, 0x02, 0x85,
+ 0x85, 0x09, 0x25, 0x95, 0x06, 0xb1, 0x02, 0x85,
+ 0x86, 0x09, 0x26, 0x95, 0x06, 0xb1, 0x02, 0x85,
+ 0x87, 0x09, 0x27, 0x95, 0x23, 0xb1, 0x02, 0x85,
+ 0x88, 0x09, 0x28, 0x95, 0x22, 0xb1, 0x02, 0x85,
+ 0x89, 0x09, 0x29, 0x95, 0x02, 0xb1, 0x02, 0x85,
+ 0x90, 0x09, 0x30, 0x95, 0x05, 0xb1, 0x02, 0x85,
+ 0x91, 0x09, 0x31, 0x95, 0x03, 0xb1, 0x02, 0x85,
+ 0x92, 0x09, 0x32, 0x95, 0x03, 0xb1, 0x02, 0x85,
+ 0x93, 0x09, 0x33, 0x95, 0x0c, 0xb1, 0x02, 0x85,
+ 0xa0, 0x09, 0x40, 0x95, 0x06, 0xb1, 0x02, 0x85,
+ 0xa1, 0x09, 0x41, 0x95, 0x01, 0xb1, 0x02, 0x85,
+ 0xa2, 0x09, 0x42, 0x95, 0x01, 0xb1, 0x02, 0x85,
+ 0xa3, 0x09, 0x43, 0x95, 0x30, 0xb1, 0x02, 0x85,
+ 0xa4, 0x09, 0x44, 0x95, 0x0d, 0xb1, 0x02, 0x85,
+ 0xa5, 0x09, 0x45, 0x95, 0x15, 0xb1, 0x02, 0x85,
+ 0xa6, 0x09, 0x46, 0x95, 0x15, 0xb1, 0x02, 0x85,
+ 0xf0, 0x09, 0x47, 0x95, 0x3f, 0xb1, 0x02, 0x85,
+ 0xf1, 0x09, 0x48, 0x95, 0x3f, 0xb1, 0x02, 0x85,
+ 0xf2, 0x09, 0x49, 0x95, 0x0f, 0xb1, 0x02, 0x85,
+ 0xa7, 0x09, 0x4a, 0x95, 0x01, 0xb1, 0x02, 0x85,
+ 0xa8, 0x09, 0x4b, 0x95, 0x01, 0xb1, 0x02, 0x85,
+ 0xa9, 0x09, 0x4c, 0x95, 0x08, 0xb1, 0x02, 0x85,
+ 0xaa, 0x09, 0x4e, 0x95, 0x01, 0xb1, 0x02, 0x85,
+ 0xab, 0x09, 0x4f, 0x95, 0x39, 0xb1, 0x02, 0x85,
+ 0xac, 0x09, 0x50, 0x95, 0x39, 0xb1, 0x02, 0x85,
+ 0xad, 0x09, 0x51, 0x95, 0x0b, 0xb1, 0x02, 0x85,
+ 0xae, 0x09, 0x52, 0x95, 0x01, 0xb1, 0x02, 0x85,
+ 0xaf, 0x09, 0x53, 0x95, 0x02, 0xb1, 0x02, 0x85,
+ 0xb0, 0x09, 0x54, 0x95, 0x3f, 0xb1, 0x02, 0xc0,
+};
+
static __u8 ps3remote_rdesc[] = {
0x05, 0x01, /* GUsagePage Generic Desktop */
0x09, 0x05, /* LUsage 0x05 [Game Pad] */
@@ -307,6 +374,17 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[55] = 0x06;
}
+ /*
+ * The default Dualshock 4 USB descriptor doesn't assign
+ * the gyroscope values to corresponding axes so we need a
+ * modified one.
+ */
+ if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) {
+ hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
+ rdesc = dualshock4_usb_rdesc;
+ *rsize = sizeof(dualshock4_usb_rdesc);
+ }
+
/* The HID descriptor exposed over BT has a trailing zero byte */
if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
--
1.8.3.2
^ permalink raw reply related
* [PATCH 3/4] HID: sony: Fix spacing in the device definitions.
From: Frank Praznik @ 2014-01-17 2:43 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina
Fix cosmetic spacing in the device definitions.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
Apply against jikos/hid.git/for-3.14/sony
drivers/hid/hid-sony.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index e623131..a7c8167 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -33,11 +33,11 @@
#include "hid-ids.h"
-#define VAIO_RDESC_CONSTANT BIT(0)
-#define SIXAXIS_CONTROLLER_USB BIT(1)
-#define SIXAXIS_CONTROLLER_BT BIT(2)
-#define BUZZ_CONTROLLER BIT(3)
-#define PS3REMOTE BIT(4)
+#define VAIO_RDESC_CONSTANT BIT(0)
+#define SIXAXIS_CONTROLLER_USB BIT(1)
+#define SIXAXIS_CONTROLLER_BT BIT(2)
+#define BUZZ_CONTROLLER BIT(3)
+#define PS3REMOTE BIT(4)
#define DUALSHOCK4_CONTROLLER_USB BIT(5)
#define DUALSHOCK4_CONTROLLER_BT BIT(6)
--
1.8.3.2
^ permalink raw reply related
* [PATCH 2/4] HID: sony: Use standard output reports instead of raw reports to send data to the Dualshock 4.
From: Frank Praznik @ 2014-01-17 2:42 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina
Use regular HID output reports instead of raw reports in the
dualshock4_state_worker function. (Thanks Simon Mungewell)
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
Apply against jikos/hid.git/for-3.14/sony
drivers/hid/hid-sony.c | 45 ++++++++++++++++++++++++++++-----------------
1 file changed, 28 insertions(+), 17 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 2f992e1..e623131 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -664,28 +664,39 @@ static void sixaxis_state_worker(struct work_struct *work)
static void dualshock4_state_worker(struct work_struct *work)
{
struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
- unsigned char buf[] = {
- 0x05,
- 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00,
- };
+ struct hid_device *hdev = sc->hdev;
+ struct list_head *head, *list;
+ struct hid_report *report;
+ __s32 *value;
+
+ list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list;
+
+ list_for_each(head, list) {
+ report = list_entry(head, struct hid_report, list);
+
+ /* Report 5 is used to send data to the controller via USB */
+ if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && report->id == 5)
+ break;
+ }
+
+ if (head == list) {
+ hid_err(hdev, "Dualshock 4 output report not found\n");
+ return;
+ }
+
+ value = report->field[0]->value;
+ value[0] = 0x03;
#ifdef CONFIG_SONY_FF
- buf[4] = sc->right;
- buf[5] = sc->left;
+ value[3] = sc->right;
+ value[4] = sc->left;
#endif
- buf[6] = sc->led_state[0];
- buf[7] = sc->led_state[1];
- buf[8] = sc->led_state[2];
+ value[5] = sc->led_state[0];
+ value[6] = sc->led_state[1];
+ value[7] = sc->led_state[2];
- sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf),
- HID_OUTPUT_REPORT);
+ hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
}
#ifdef CONFIG_SONY_FF
--
1.8.3.2
^ permalink raw reply related
* [PATCH 1/4] HID: sony: Use separate identifiers for USB and Bluetooth connected Dualshock 4 controllers.
From: Frank Praznik @ 2014-01-17 2:42 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina
Use separate identifiers for Dualshock 4 controllers connected via USB and
Bluetooth.
Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---
Apply against jikos/hid.git/for-3.14/sony
drivers/hid/hid-sony.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 1dfed23..2f992e1 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -38,9 +38,10 @@
#define SIXAXIS_CONTROLLER_BT BIT(2)
#define BUZZ_CONTROLLER BIT(3)
#define PS3REMOTE BIT(4)
-#define DUALSHOCK4_CONTROLLER BIT(5)
+#define DUALSHOCK4_CONTROLLER_USB BIT(5)
+#define DUALSHOCK4_CONTROLLER_BT BIT(6)
-#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER)
+#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB)
#define MAX_LEDS 4
@@ -478,7 +479,7 @@ static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count)
if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) {
buzz_set_leds(hdev, leds);
} else if ((drv_data->quirks & SIXAXIS_CONTROLLER_USB) ||
- (drv_data->quirks & DUALSHOCK4_CONTROLLER)) {
+ (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB)) {
for (n = 0; n < count; n++)
drv_data->led_state[n] = leds[n];
schedule_work(&drv_data->state_worker);
@@ -583,7 +584,7 @@ static int sony_leds_init(struct hid_device *hdev)
name_fmt = "%s::sony%d";
}
- if (drv_data->quirks & DUALSHOCK4_CONTROLLER) {
+ if (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) {
drv_data->led_count = 3;
max_brightness = 255;
} else {
@@ -775,7 +776,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
}
else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
ret = sixaxis_set_operational_bt(hdev);
- else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
+ else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
ret = 0;
INIT_WORK(&sc->state_worker, dualshock4_state_worker);
} else {
@@ -840,9 +841,9 @@ static const struct hid_device_id sony_devices[] = {
.driver_data = PS3REMOTE },
/* Sony Dualshock 4 controllers for PS4 */
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
- .driver_data = DUALSHOCK4_CONTROLLER },
+ .driver_data = DUALSHOCK4_CONTROLLER_USB },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
- .driver_data = DUALSHOCK4_CONTROLLER },
+ .driver_data = DUALSHOCK4_CONTROLLER_BT },
{ }
};
MODULE_DEVICE_TABLE(hid, sony_devices);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 0/4] HID: sony: Additional fixes and improvements for the Dualshock 4
From: Frank Praznik @ 2014-01-17 2:42 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina
These series of patches makes some fixes and improvements to the Dualshock
4 driver.
There seems to be an issue in Bluez that prevents these controllers from
connecting via bluetooth, so rumble and LED support for Bluetooth devices
is currently missing from the driver since it can't be tested. The
first two patches will make it easier to add these capabilities later once
the issues are fixed.
The first patch adds separate identifiers for USB and Bluetooth connected
controllers as they each require different report formats when
communicating with the controller.
The second changes the dualshock4_worker function to use the standard HID
output report system to write data to the controller instead of using a
raw packet. Thanks to Simon Mungewell for the concept code.
The third patch is just minor cosmetic fixes.
The fourth patch adds support for the accelerometers and gyroscope
sensors. To do this, a modified HID descriptor is used instead of the
defauly with additional usage fields to map the 6 signed short values to axes.
^ permalink raw reply
* Re: [PATCH 2/2] Input: edt-ft5x06: Add DT support
From: Simon Budig @ 2014-01-17 1:39 UTC (permalink / raw)
To: Lothar Waßmann
Cc: Mark Rutland, linux-input@vger.kernel.org, Rob Herring,
Pawel Moll, Ian Campbell, Kumar Gala, Rob Landley,
Dmitry Torokhov, grant.likely@linaro.org, Thierry Reding,
Jonathan Cameron, Shawn Guo, Silvio F, Guennadi Liakhovetski,
Jingoo Han, Fugang Duan, Sachin Kamat, devicetree@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20140116084943.17da0226@ipc1.ka-ro>
[-- Attachment #1: Type: text/plain, Size: 1608 bytes --]
On 16/01/14 08:49, Lothar Waßmann wrote:
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
>>> @@ -0,0 +1,31 @@
>>> +* EDT FT5x06 Multiple Touch Controller
>>> +
> [...]
>>> +- threshold: allows setting the "click"-threshold in the range from 20 to 80.
>>> +- gain: sensitivity (0..31) (lower value -> higher sensitivity)
>>> +- offset: edge compensation (0..31)
>>> +- report_rate: report rate (3..14)
>>
>> s/_/-/ on property names please. Also, it may make sense to prefix these
>> as they're rather generic sounding names.
>>
>> Could you elaborate on these a litle please? What units are each of
>> these in? Why does it make sense to have them in the dt?
>>
> I just converted them from being passed via platform_data. I have no
> idea what they actually control and what units they use. I could not
> even find a manual where they are documented.
> Maybe Simon Budig can help out here as the original driver author.
The units are not specified in the datasheets available to me. I suspect
that these are some sort of counter values related to the cap sensing.
The defaults differ for the different size glasses, so I really suspect
these are basically just numbers.
The only somewhat reasonable unit is available for the report-rate: it
is specified as about <value> * 10 touch reports per second.
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
* Re: [PATCHv2 3/3] Input: edt-ft5x06: Add DT support
From: Simon Budig @ 2014-01-17 1:46 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Lothar Waßmann, linux-input, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Thierry Reding, Grant Likely, Jonathan Cameron, Shawn Guo,
Silvio F, Guennadi Liakhovetski, Jingoo Han, Fugang Duan,
Sachin Kamat, devicetree, linux-doc, linux-kernel
In-Reply-To: <20140117002649.GA837@core.coreip.homeip.net>
[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]
Hi Dmitry
On 17/01/14 01:26, Dmitry Torokhov wrote:
>> + The following properties provide default values for the
>> + corresponding parameters (see Documentation/input/edt-ft5x06.txt)
>> +- edt,threshold: allows setting the "click"-threshold in the range from 20 to 80.
>> +- edt,gain: sensitivity (0..31) (lower value -> higher sensitivity)
>> +- edt,offset: edge compensation (0..31)
>> +- edt,report-rate: report rate (3..14)
>
> I wonder if we really need to have it in device tree? Can users needing
> top tweak the settings do it via udev rules?
IMO it makes sense to have these in the device tree. These values need
to be adjusted if you have glass or acrylics in front of the touch
glass. The defaults are tailored to the touchscreen without any
(additional) material in front of it.
So manufacturers need to provide different defaults depending on the way
a specific device is built. So these properties can be viewed in the
same way you specify display resolution or display type in the device tree.
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
* Re: [PATCHv2 3/3] Input: edt-ft5x06: Add DT support
From: Jingoo Han @ 2014-01-17 1:36 UTC (permalink / raw)
To: 'Lothar Waßmann', 'Dmitry Torokhov'
Cc: linux-input, 'Simon Budig', 'Rob Herring',
'Pawel Moll', 'Mark Rutland',
'Ian Campbell', 'Kumar Gala',
'Rob Landley', 'Thierry Reding',
'Grant Likely', 'Jonathan Cameron',
'Shawn Guo', 'Silvio F',
'Guennadi Liakhovetski', 'Fugang Duan',
'Sachin Kamat', devicetree, linux-doc, linux-kernel,
'Jingoo Han'
In-Reply-To: <20140117002649.GA837@core.coreip.homeip.net>
On Friday, January 17, 2014 9:27 AM, Dmitry Torokhov wrote:
> On Thu, Jan 16, 2014 at 09:02:18AM +0100, Lothar Waßmann wrote:
> >
> > Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
> > ---
> > .../bindings/input/touchscreen/edt-ft5x06.txt | 29 +++++
> > drivers/input/touchscreen/edt-ft5x06.c | 121 +++++++++++++++++---
> > 2 files changed, 132 insertions(+), 18 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> >
[.....]
> > + 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,
> > + 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);
> > - mdelay(100);
> > + mdelay(5);
> > + gpio_set_value(tsdata->reset_pin, 1);
> > + mdelay(300);
>
> Hmm, this change seems unrelated to DT support.
Right, modifying delay timing is not related to DT support.
In this case, this patch should be split, and the patch should
address the reason why delay timing is modified.
Also, 300 msec is a huge delay. Thus, comment will be helpful.
Best regards,
Jingoo Han
^ permalink raw reply
* Re: [PATCH 4/4] Input: synaptics-rmi4 - switch to using i2c_transfer()
From: Dmitry Torokhov @ 2014-01-17 0:35 UTC (permalink / raw)
To: Christopher Heiny
Cc: Andrew Duggan, Vincent Huang, Vivian Ly, Daniel Rosenberg,
Linus Walleij, Benjamin Tissoires, Linux Input, Linux Kernel
In-Reply-To: <52D4F4C7.8000706@synaptics.com>
On Tue, Jan 14, 2014 at 12:26:47AM -0800, Christopher Heiny wrote:
> On 01/09/2014 11:44 PM, Dmitry Torokhov wrote:
> >
> >- dev_dbg(&client->dev, "writes 1 bytes: %02x\n", txbuf[0]);
> >+ retval = i2c_transfer(client->adapter, msgs, sizeof(msgs));
> >+ if (retval == sizeof(msgs))
>
> I think this should be:
> retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> if (retval == ARRAY_SIZE(msgs))
> At least, that change resolved some random misbehaviors, including
> kernel panics.
You are absolutely right, I just committed a fix for that.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: wacom - add support for DTU-1031
From: Dmitry Torokhov @ 2014-01-17 0:34 UTC (permalink / raw)
To: Ping Cheng; +Cc: linux-input, Ping Cheng
In-Reply-To: <1389907779-12125-1-git-send-email-pingc@wacom.com>
Hi Ping,
On Thu, Jan 16, 2014 at 01:29:39PM -0800, Ping Cheng wrote:
> Signed-off-by: Ping Cheng <pingc@wacom.com>
> ---
> drivers/input/tablet/wacom_wac.c | 80 +++++++++++++++++++++++++++++++++++++++-
> drivers/input/tablet/wacom_wac.h | 6 ++-
> 2 files changed, 84 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
> index 0bcc7a6..fed2f04 100644
> --- a/drivers/input/tablet/wacom_wac.c
> +++ b/drivers/input/tablet/wacom_wac.c
> @@ -210,6 +210,70 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)
> return 1;
> }
>
> +static int wacom_dtus_irq(struct wacom_wac *wacom)
> +{
> + char *data = wacom->data;
> + struct input_dev *input = wacom->input;
> + unsigned short prox, pressure = 0;
> + int retval = 0;
> +
> + if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) {
> + dev_dbg(input->dev.parent,
> + "%s: received unknown report #%d", __func__, data[0]);
> + goto exit;
> + }
> +
> + if (data[0] == WACOM_REPORT_DTUSPAD) {
> + input_report_key(input, BTN_0, (data[1] & 0x01));
> + input_report_key(input, BTN_1, (data[1] & 0x02));
> + input_report_key(input, BTN_2, (data[1] & 0x04));
> + input_report_key(input, BTN_3, (data[1] & 0x08));
> + if (data[1] & 0x0f) {
> + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
> + } else {
> + input_report_abs(input, ABS_MISC, 0);
> + }
> + /* serial number is required when expresskeys are
> + * reported through pen interface.
> + */
> + input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
> + retval = 1;
> + goto exit;
Let's not abuse gotos. This seems like perfect candidate for
"if/else if/else" construct.
> + }
> +
> + prox = data[1] & 0x80;
> + if (prox) {
> + switch ((data[1] >> 3) & 3) {
> + case 1: /* Rubber */
> + wacom->tool[0] = BTN_TOOL_RUBBER;
> + wacom->id[0] = ERASER_DEVICE_ID;
> + break;
> +
> + case 2: /* Pen */
> + wacom->tool[0] = BTN_TOOL_PEN;
> + wacom->id[0] = STYLUS_DEVICE_ID;
> + break;
> + }
> + }
> +
> + input_report_key(input, BTN_STYLUS, data[1] & 0x20);
> + input_report_key(input, BTN_STYLUS2, data[1] & 0x40);
> + input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[3]));
> + input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[5]));
I am pretty sure this is not aligned on word boundary so you need to use
get_unaligned_be16() here.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: wacom - Fix wacom->shared guards for dual input devices
From: Dmitry Torokhov @ 2014-01-17 0:28 UTC (permalink / raw)
To: Ping Cheng; +Cc: linux-input, Ping Cheng
In-Reply-To: <1389823457-3649-1-git-send-email-pingc@wacom.com>
On Wed, Jan 15, 2014 at 02:04:17PM -0800, Ping Cheng wrote:
> features->quirks can have multiple bits set. For dual input, we only
> need to check WACOM_QUIRK_MULTI_INPUT.
>
> Reviewed-by: Jason Gerecke <killertofu@gmail.com>
> Signed-off-by: Ping Cheng <pingc@wacom.com>
Applied, thank you.
> ---
> drivers/input/tablet/wacom_wac.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
> index 048e5b3..0bcc7a6 100644
> --- a/drivers/input/tablet/wacom_wac.c
> +++ b/drivers/input/tablet/wacom_wac.c
> @@ -331,7 +331,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
>
> /* Enter report */
> if ((data[1] & 0xfc) == 0xc0) {
> - if (features->quirks == WACOM_QUIRK_MULTI_INPUT)
> + if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
> wacom->shared->stylus_in_proximity = true;
>
> /* serial number of the tool */
> @@ -436,7 +436,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
>
> /* Exit report */
> if ((data[1] & 0xfe) == 0x80) {
> - if (features->quirks == WACOM_QUIRK_MULTI_INPUT)
> + if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
> wacom->shared->stylus_in_proximity = false;
>
> /*
> --
> 1.8.3.2
>
--
Dmitry
^ permalink raw reply
* Re: [PATCHv2 1/3] Input: edt_ft5x06: use devm_* functions where appropriate
From: Dmitry Torokhov @ 2014-01-17 0:28 UTC (permalink / raw)
To: Lothar Waßmann
Cc: linux-input, Simon Budig, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Thierry Reding,
Grant Likely, Jonathan Cameron, Shawn Guo, Silvio F,
Guennadi Liakhovetski, Jingoo Han, Fugang Duan, Sachin Kamat,
devicetree, linux-doc, linux-kernel
In-Reply-To: <1389859338-11685-2-git-send-email-LW@KARO-electronics.de>
On Thu, Jan 16, 2014 at 09:02:16AM +0100, Lothar Waßmann wrote:
> Simplify the error path and remove() function by using devm_*
> functions for requesting gpios and irq and allocating the input
> device.
>
> Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
Applied, thank you.
> ---
> drivers/input/touchscreen/edt-ft5x06.c | 62 ++++++++++---------------------
> 1 files changed, 20 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
> index af0d68b..acb6b9f 100644
> --- a/drivers/input/touchscreen/edt-ft5x06.c
> +++ b/drivers/input/touchscreen/edt-ft5x06.c
> @@ -623,8 +623,9 @@ static int edt_ft5x06_ts_reset(struct i2c_client *client,
>
> if (gpio_is_valid(reset_pin)) {
> /* this pulls reset down, enabling the low active reset */
> - error = gpio_request_one(reset_pin, GPIOF_OUT_INIT_LOW,
> - "edt-ft5x06 reset");
> + error = devm_gpio_request_one(&client->dev, 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",
> @@ -723,7 +724,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
> return error;
>
> if (gpio_is_valid(pdata->irq_pin)) {
> - error = gpio_request_one(pdata->irq_pin,
> + error = devm_gpio_request_one(&client->dev, pdata->irq_pin,
> GPIOF_IN, "edt-ft5x06 irq");
> if (error) {
> dev_err(&client->dev,
> @@ -734,11 +735,10 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
> }
>
> tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
> - input = input_allocate_device();
> - if (!tsdata || !input) {
> - dev_err(&client->dev, "failed to allocate driver data.\n");
> - error = -ENOMEM;
> - goto err_free_mem;
> + input = devm_input_allocate_device(&client->dev);
> + if (!input) {
> + dev_err(&client->dev, "failed to allocate input device.\n");
> + return -ENOMEM;
> }
>
> mutex_init(&tsdata->mutex);
> @@ -749,7 +749,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
> error = edt_ft5x06_ts_identify(client, tsdata->name, fw_version);
> if (error) {
> dev_err(&client->dev, "touchscreen probe failed\n");
> - goto err_free_mem;
> + return error;
> }
>
> edt_ft5x06_ts_get_defaults(tsdata, pdata);
> @@ -776,27 +776,30 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
> error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0);
> if (error) {
> dev_err(&client->dev, "Unable to init MT slots.\n");
> - goto err_free_mem;
> + return error;
> }
>
> input_set_drvdata(input, tsdata);
> i2c_set_clientdata(client, tsdata);
>
> - error = request_threaded_irq(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");
> - goto err_free_mem;
> + return error;
> }
>
> error = sysfs_create_group(&client->dev.kobj, &edt_ft5x06_attr_group);
> if (error)
> - goto err_free_irq;
> + return error;
>
> error = input_register_device(input);
> - if (error)
> - goto err_remove_attrs;
> + if (error) {
> + sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
> + return error;
> + }
>
> edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
> device_init_wakeup(&client->dev, 1);
> @@ -806,40 +809,15 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
> pdata->irq_pin, pdata->reset_pin);
>
> return 0;
> -
> -err_remove_attrs:
> - sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
> -err_free_irq:
> - free_irq(client->irq, tsdata);
> -err_free_mem:
> - input_free_device(input);
> - kfree(tsdata);
> -
> - if (gpio_is_valid(pdata->irq_pin))
> - gpio_free(pdata->irq_pin);
> -
> - return error;
> }
>
> static int edt_ft5x06_ts_remove(struct i2c_client *client)
> {
> - const struct edt_ft5x06_platform_data *pdata =
> - dev_get_platdata(&client->dev);
> struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
>
> edt_ft5x06_ts_teardown_debugfs(tsdata);
> sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
>
> - free_irq(client->irq, tsdata);
> - input_unregister_device(tsdata->input);
> -
> - if (gpio_is_valid(pdata->irq_pin))
> - gpio_free(pdata->irq_pin);
> - if (gpio_is_valid(pdata->reset_pin))
> - gpio_free(pdata->reset_pin);
> -
> - kfree(tsdata);
> -
> return 0;
> }
>
> --
> 1.7.2.5
>
--
Dmitry
--
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: [PATCHv2 3/3] Input: edt-ft5x06: Add DT support
From: Dmitry Torokhov @ 2014-01-17 0:26 UTC (permalink / raw)
To: Lothar Waßmann
Cc: linux-input, Simon Budig, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Thierry Reding,
Grant Likely, Jonathan Cameron, Shawn Guo, Silvio F,
Guennadi Liakhovetski, Jingoo Han, Fugang Duan, Sachin Kamat,
devicetree, linux-doc, linux-kernel
In-Reply-To: <1389859338-11685-4-git-send-email-LW@KARO-electronics.de>
Hi Lothar,
On Thu, Jan 16, 2014 at 09:02:18AM +0100, Lothar Waßmann wrote:
>
> Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
> ---
> .../bindings/input/touchscreen/edt-ft5x06.txt | 29 +++++
> drivers/input/touchscreen/edt-ft5x06.c | 121 +++++++++++++++++---
> 2 files changed, 132 insertions(+), 18 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..8d94cdc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
> @@ -0,0 +1,29 @@
> +* EDT FT5x06 Multiple Touch Controller
> +
> +Required properties:
> +- compatible: must be "edt,ft5x06"
> +- reg: i2c slave address
> +- interrupt-parent: the phandle for the interrupt controller
> +- interrupts: touch controller interrupt
> +
> +Optional properties:
> +- reset-gpios: the gpio pin to be used for resetting the controller
> +- wake-gpios: the gpio pin to be used for waking up the controller
> +
> + The following properties provide default values for the
> + corresponding parameters (see Documentation/input/edt-ft5x06.txt)
> +- edt,threshold: allows setting the "click"-threshold in the range from 20 to 80.
> +- edt,gain: sensitivity (0..31) (lower value -> higher sensitivity)
> +- edt,offset: edge compensation (0..31)
> +- edt,report-rate: report rate (3..14)
I wonder if we really need to have it in device tree? Can users needing
top tweak the settings do it via udev rules?
> +
> +Example:
> +
> + edt_ft5x06@38 {
> + compatible = "edt,ft5x06";
> + reg = <0x38>;
> + 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 acb6b9f..0467591 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>
>
> @@ -65,6 +66,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;
> @@ -617,25 +622,38 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
>
>
> 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,
> + 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);
> - mdelay(100);
> + mdelay(5);
> + gpio_set_value(tsdata->reset_pin, 1);
> + mdelay(300);
Hmm, this change seems unrelated to DT support.
Thanks.
--
Dmitry
--
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: hid-sensor-hub:Fix buggy report descriptors
From: Jiri Kosina @ 2014-01-16 21:53 UTC (permalink / raw)
To: Srinivas Pandruvada; +Cc: linux-input
In-Reply-To: <1389720620-17418-1-git-send-email-srinivas.pandruvada@linux.intel.com>
On Tue, 14 Jan 2014, Srinivas Pandruvada wrote:
> This addresses regression caused by commit id "751d17e23a9f7"
> iio: hid-sensors: Fix power and report state.
Applied, thanks Srinivas.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2 1/3] HID: sony: Add force-feedback support for the Dualshock 4
From: simon @ 2014-01-16 21:53 UTC (permalink / raw)
To: Jiri Kosina; +Cc: Frank Praznik, linux-input
In-Reply-To: <alpine.LNX.2.00.1401162246320.23018@pobox.suse.cz>
> On Sat, 11 Jan 2014, Frank Praznik wrote:
>
>> Adds the Dualshock 4 to the HID device list and enables force-feedback.
>>
>> Adds a Dualshock 4 specific worker function since the Dualshock 4 needs
>> a
>> different report than the Sixaxis.
>>
>> The right motor in the Dualshock 4 is variable so the full rumble value
>> is now passed to the worker function and clamped there if necessary.
>>
>> Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
>
> I have now applied the whole series, thanks Frank.
Thanks.
We are seeing problems with the way that DS4 interacts with Bluez (mostly
importantly how the PC and DS4 'pair'), but I believe that the kernel
stuff is OK.
Simon
^ permalink raw reply
* Re: [PATCH 1/5] HID: logitech-dj: Fix USB 3.0 issue
From: Jiri Kosina @ 2014-01-16 21:50 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Benjamin Tissoires, Nestor Lopez Casado, Andrew de los Reyes,
linux-input, linux-kernel
In-Reply-To: <1389219529-29671-2-git-send-email-benjamin.tissoires@redhat.com>
On Wed, 8 Jan 2014, Benjamin Tissoires wrote:
> From: Benjamin Tisssoires <benjamin.tissoires@redhat.com>
>
> This fix (not very clean though) should fix the long time USB3
> issue that was spotted last year. The rational has been given by
> Hans de Goede:
Man this is so ugly ... makes one wonder how come that other OSes don't
suffer from this. Are they really *that much* slower? :)
I have applied this (and just this) one for 3.14.
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2 1/3] HID: sony: Add force-feedback support for the Dualshock 4
From: Jiri Kosina @ 2014-01-16 21:46 UTC (permalink / raw)
To: Frank Praznik; +Cc: linux-input
In-Reply-To: <alpine.DEB.2.10.1401111429090.2563@franz-virtual-machine>
On Sat, 11 Jan 2014, Frank Praznik wrote:
> Adds the Dualshock 4 to the HID device list and enables force-feedback.
>
> Adds a Dualshock 4 specific worker function since the Dualshock 4 needs a
> different report than the Sixaxis.
>
> The right motor in the Dualshock 4 is variable so the full rumble value
> is now passed to the worker function and clamped there if necessary.
>
> Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
I have now applied the whole series, thanks Frank.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* [PATCH] Input: wacom - add support for DTU-1031
From: Ping Cheng @ 2014-01-16 21:29 UTC (permalink / raw)
To: linux-input; +Cc: dmitry.torokhov, Ping Cheng
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
drivers/input/tablet/wacom_wac.c | 80 +++++++++++++++++++++++++++++++++++++++-
drivers/input/tablet/wacom_wac.h | 6 ++-
2 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 0bcc7a6..fed2f04 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -210,6 +210,70 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)
return 1;
}
+static int wacom_dtus_irq(struct wacom_wac *wacom)
+{
+ char *data = wacom->data;
+ struct input_dev *input = wacom->input;
+ unsigned short prox, pressure = 0;
+ int retval = 0;
+
+ if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) {
+ dev_dbg(input->dev.parent,
+ "%s: received unknown report #%d", __func__, data[0]);
+ goto exit;
+ }
+
+ if (data[0] == WACOM_REPORT_DTUSPAD) {
+ input_report_key(input, BTN_0, (data[1] & 0x01));
+ input_report_key(input, BTN_1, (data[1] & 0x02));
+ input_report_key(input, BTN_2, (data[1] & 0x04));
+ input_report_key(input, BTN_3, (data[1] & 0x08));
+ if (data[1] & 0x0f) {
+ input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
+ } else {
+ input_report_abs(input, ABS_MISC, 0);
+ }
+ /* serial number is required when expresskeys are
+ * reported through pen interface.
+ */
+ input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
+ retval = 1;
+ goto exit;
+ }
+
+ prox = data[1] & 0x80;
+ if (prox) {
+ switch ((data[1] >> 3) & 3) {
+ case 1: /* Rubber */
+ wacom->tool[0] = BTN_TOOL_RUBBER;
+ wacom->id[0] = ERASER_DEVICE_ID;
+ break;
+
+ case 2: /* Pen */
+ wacom->tool[0] = BTN_TOOL_PEN;
+ wacom->id[0] = STYLUS_DEVICE_ID;
+ break;
+ }
+ }
+
+ input_report_key(input, BTN_STYLUS, data[1] & 0x20);
+ input_report_key(input, BTN_STYLUS2, data[1] & 0x40);
+ input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[3]));
+ input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[5]));
+ pressure = ((data[1] & 0x03) << 8) | (data[2] & 0xff);
+ input_report_abs(input, ABS_PRESSURE, pressure);
+ input_report_key(input, BTN_TOUCH, pressure > 10);
+
+ if (!prox) /* out-prox */
+ wacom->id[0] = 0;
+ input_report_key(input, wacom->tool[0], prox);
+ input_report_abs(input, ABS_MISC, wacom->id[0]);
+ input_event(input, EV_MSC, MSC_SERIAL, 1);
+ retval = 1;
+exit:
+ return retval;
+}
+
static int wacom_graphire_irq(struct wacom_wac *wacom)
{
struct wacom_features *features = &wacom->features;
@@ -1371,6 +1435,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
sync = wacom_dtu_irq(wacom_wac);
break;
+ case DTUS:
+ sync = wacom_dtus_irq(wacom_wac);
+ break;
+
case INTUOS:
case INTUOS3S:
case INTUOS3:
@@ -1562,7 +1630,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
wacom_abs_set_axis(input_dev, wacom_wac);
- switch (wacom_wac->features.type) {
+ switch (features->type) {
case WACOM_MO:
input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
/* fall through */
@@ -1773,8 +1841,14 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
/* fall through */
+ case DTUS:
case PL:
case DTU:
+ if (features->type == DTUS) {
+ input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
+ for (i = 0; i < 3; i++)
+ __set_bit(BTN_0 + i, input_dev->keybit);
+ }
__set_bit(BTN_TOOL_PEN, input_dev->keybit);
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
__set_bit(BTN_STYLUS, input_dev->keybit);
@@ -2096,6 +2170,9 @@ static const struct wacom_features wacom_features_0xCE =
static const struct wacom_features wacom_features_0xF0 =
{ "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511,
0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0xFB =
+ { "Wacom DTU1031", WACOM_PKGLEN_DTUS, 22096, 13960, 511,
+ 0, DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x57 =
{ "Wacom DTK2241", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047,
63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES};
@@ -2402,6 +2479,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0xF8) },
{ USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) },
{ USB_DEVICE_WACOM(0xFA) },
+ { USB_DEVICE_WACOM(0xFB) },
{ USB_DEVICE_WACOM(0x0307) },
{ USB_DEVICE_DETAILED(0x0309, USB_CLASS_HID, 0, 0) },
{ USB_DEVICE_LENOVO(0x6004) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 3600cf7..f69c0eb 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -12,7 +12,7 @@
#include <linux/types.h>
/* maximum packet length for USB devices */
-#define WACOM_PKGLEN_MAX 64
+#define WACOM_PKGLEN_MAX 68
#define WACOM_NAME_MAX 64
@@ -29,6 +29,7 @@
#define WACOM_PKGLEN_WIRELESS 32
#define WACOM_PKGLEN_MTOUCH 62
#define WACOM_PKGLEN_MTTPC 40
+#define WACOM_PKGLEN_DTUS 68
/* wacom data size per MT contact */
#define WACOM_BYTES_PER_MT_PACKET 11
@@ -47,11 +48,13 @@
#define WACOM_REPORT_INTUOSWRITE 6
#define WACOM_REPORT_INTUOSPAD 12
#define WACOM_REPORT_INTUOS5PAD 3
+#define WACOM_REPORT_DTUSPAD 21
#define WACOM_REPORT_TPC1FG 6
#define WACOM_REPORT_TPC2FG 13
#define WACOM_REPORT_TPCMT 13
#define WACOM_REPORT_TPCHID 15
#define WACOM_REPORT_TPCST 16
+#define WACOM_REPORT_DTUS 17
#define WACOM_REPORT_TPC1FGE 18
#define WACOM_REPORT_24HDT 1
#define WACOM_REPORT_WL 128
@@ -70,6 +73,7 @@ enum {
PTU,
PL,
DTU,
+ DTUS,
INTUOS,
INTUOS3S,
INTUOS3,
--
1.8.3.2
^ permalink raw reply related
* Re: Fwd: [PATCH] add support for ALPS v7 protocol device
From: Dylan Thurston @ 2014-01-16 13:38 UTC (permalink / raw)
To: Elaine Chen
Cc: Tommy Will, Dmitry Torokhov, Kevin Cernekee, david turvene,
Niels de Vos, Justin Clift, Qiting Chen, linux-input
In-Reply-To: <CAKvfdtLmBq8pLurFgFoYcis6bnfc4gX7fzCJ5o1fn570-_Vb=w@mail.gmail.com>
Yes.
--Dylan
On Thu, Jan 16, 2014 at 01:36:01PM +0800, Elaine Chen wrote:
> Do you mean that cursor jitters, moves away from target when hitting the button?
>
> 2014/1/16 Dylan Thurston <dpthurst@indiana.edu>:
> > Another small issue: it's a little difficult to click in the touchpad
> > area without moving the mouse. This can make it difficult to hit small
> > buttons.
> >
> > --Dylan
> >
> > On Wed, Jan 15, 2014 at 08:00:34AM -0500, Dylan Thurston wrote:
> >> One glitch: I see mouse jumping sometimes when dragging. This has
> >> happened a couple times when resizing windows with a right-click and
> >> drag.
> >>
> >> I'm using X.org from Debian unstable, in case that's relevant.
> >>
> >> --Dylan
> >>
> >> On Wed, Jan 15, 2014 at 12:16:50AM -0500, Dylan Thurston wrote:
> >> > This patch seems to work in the 3.13-rc8 kernel, at least on an
> >> > initial check. The problems with excess clicks while typing have
> >> > disappeared. I'll report back with any glitches I see.
> >> >
> >> > Thank you!
> >> >
> >> > --Dylan
> >> >
> >> > On Wed, Jan 15, 2014 at 11:15:02AM +0800, Elaine Chen wrote:
> >> > > Hi Dylan,
> >> > >
> >> > > Thank you! This patch is againt Dmitry Torokhov's input tree, based on
> >> > > the modification of:
> >> > > 2013-12-26 Input: ALPS - add support for "Dolphin" devices Yunkang Tang
> >> > > As linux-next-20140114 has already merged Dolphin support, the patch
> >> > > should be matched.
> >> > > As for the blank screen, I'll debug on my side. Sorry for that.
> >> > > What is the kernel version on your HP side? Is it 3.13-rc8?
> >> > >
> >> > > Yes, it is safe to copy both alps.c and alps.h from linux-next version
> >> > > to 3.13-rc8 kerenl.
> >> > >
> >> > >
> >> > >
> >> > > 2014/1/15 Dylan Thurston <dpthurst@indiana.edu>:
> >> > > > Thank you! Which versions does this apply against? It patched for me
> >> > > > with no fuzz against linux-next-20140114, but unfortunately X seems to
> >> > > > be broken for me on that version (blank screen). I get fuzz and
> >> > > > rejected patches when applying it to 3.13-rc8. Is it safe to just copy
> >> > > > over alps.c from the linux-next version?
> >> > > >
> >> > > > (Of course, it's possible that the blank screen is a side effect of
> >> > > > the correct recognition of the touchpad.)
> >> > > >
> >> > > > Thanks,
> >> > > > Dylan
> >> > > >
> >> > > > On Tue, Jan 14, 2014 at 02:11:59PM +0800, Tommy Will wrote:
> >> > > >> Hi Dylan,
> >> > > >>
> >> > > >> My colleague Elaine has prepared the patch for new ALPS touchpad that
> >> > > >> being used on your HP Revolve 810 G1 laptop.
> >> > > >> You can have a try~
> >> > > >>
> >> > > >> --
> >> > > >> Best Regards,
> >> > > >> Tommy
> >> > > >>
> >> > > >> ---------- Forwarded message ----------
> >> > > >> From: Elaine Chen <elaineee66@gmail.com>
> >> > > >> Date: 2014/1/14
> >> > > >> Subject: Re: [PATCH] add support for ALPS v7 protocol device
> >> > > >> To: Dmitry Torokhov <dmitry.torokhov@gmail.com>, cernekee@gmail.com,
> >> > > >> david turvene <dturvene@dahetral.com>
> >> > > >> 抄送: linux-input@vger.kernel.org, ndevos@redhat.com, jclift@redhat.com,
> >> > > >> Qiting Chen <qiting.chen@cn.alps.com>
> >> > > >>
> >> > > >>
> >> > > >> As far as I know, the ALPS v7 protocol device is used on following laptops:
> >> > > >>
> >> > > >> Lenovo S430/S435/S530, Lenovo Z410/Z510, HP Odie, HP Revolve 810 G1
> >> > > >>
> >> > > >> 2014/1/10 Qiting Chen <elaineee66@gmail.com>:
> >> > > >> > Here is the patch of supporting ALPS v7 protocol device.
> >> > > >> >
> >> > > >> > v7 device is a clickpad device.
> >> > > >> > Device info:
> >> > > >> > Device ID = 0x73, 0x03, 0x0a
> >> > > >> > Firmware ID = 0x88, 0xb*, 0x**
> >> > > >> >
> >> > > >> > Support function of v7 device:
> >> > > >> > - Cursor
> >> > > >> > - Tap, double tap, tap drag, 2finger tap
> >> > > >> > - Pan, pinch
> >> > > >> > - Button click: v7 device has one physical button under the touchpad. A Button Area covers the bottom of touchpad. Clicking on Button Area produces button acitivities.
> >> > > >> > Click touchpad with all fingers outside right Button Area --> left click
> >> > > >> > Click touchpad with at lease 1 finger inside right Button Area --> right click
> >> > > >> > - Resting finger function: Cursor and gestures won't be influenced with one finger placed still on Button Area.
> >> > > >> >
> >> > > >> > The resting finger process is in alps.c as it seems the latest xserver-xorg-input-synaptics(1.7.1) doesn't support that part.
> >> > > >> > We tried registering our device as a clickpad by:
> >> > > >> > set_bit(INPUT_PROP_BUTTONPAD, dev1->propbit)
> >> > > >> > But only button click can be correctly recognized. Yet a finger at Button Area won't be ignored while doing cursroing.
> >> > > >> >
> >> > > >> >
> >> > > >> > Signed-off-by: Qiting Chen <qiting.chen@cn.alps.com>
> >> > > >> > ---
> >> > > >> > drivers/input/mouse/alps.c | 478 ++++++++++++++++++++++++++++++++++++++++++---
> >> > > >> > drivers/input/mouse/alps.h | 127 ++++++++++--
> >> > > >> > 2 files changed, 554 insertions(+), 51 deletions(-)
> >> > > >> >
> >> > > >> > diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
> >> > > >> > index fb15c64..3e8e8f7 100644
> >> > > >> > --- a/drivers/input/mouse/alps.c
> >> > > >> > +++ b/drivers/input/mouse/alps.c
> >> > > >> > @@ -32,6 +32,11 @@
> >> > > >> > #define ALPS_REG_BASE_RUSHMORE 0xc2c0
> >> > > >> > #define ALPS_REG_BASE_PINNACLE 0x0000
> >> > > >> >
> >> > > >> > +#define LEFT_BUTTON_BIT 0x01
> >> > > >> > +#define RIGHT_BUTTON_BIT 0x02
> >> > > >> > +
> >> > > >> > +#define V7_LARGE_MOVEMENT 130
> >> > > >> > +
> >> > > >> > static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
> >> > > >> > { PSMOUSE_CMD_SETPOLL, 0x00 }, /* 0 */
> >> > > >> > { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */
> >> > > >> > @@ -99,6 +104,7 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
> >> > > >> > #define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */
> >> > > >> > #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with
> >> > > >> > 6-byte ALPS packet */
> >> > > >> > +#define ALPS_BTNLESS 0x100 /* ALPS ClickPad flag */
> >> > > >> >
> >> > > >> > static const struct alps_model_info alps_model_data[] = {
> >> > > >> > { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
> >> > > >> > @@ -140,6 +146,20 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
> >> > > >> > * isn't valid per PS/2 spec.
> >> > > >> > */
> >> > > >> >
> >> > > >> > +static unsigned int alps_pt_distance(struct alps_abs_data *pt0,
> >> > > >> > + struct alps_abs_data *pt1)
> >> > > >> > +{
> >> > > >> > + int vect_x, vect_y;
> >> > > >> > +
> >> > > >> > + if (!pt0 || !pt1)
> >> > > >> > + return 0;
> >> > > >> > +
> >> > > >> > + vect_x = pt0->x - pt1->x;
> >> > > >> > + vect_y = pt0->y - pt1->y;
> >> > > >> > +
> >> > > >> > + return int_sqrt(vect_x * vect_x + vect_y * vect_y);
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > /* Packet formats are described in Documentation/input/alps.txt */
> >> > > >> >
> >> > > >> > static bool alps_is_valid_first_byte(struct alps_data *priv,
> >> > > >> > @@ -320,8 +340,8 @@ static void alps_process_bitmap_dolphin(struct alps_data *priv,
> >> > > >> > end_bit = y_msb - 1;
> >> > > >> > box_middle_y = (priv->y_max * (start_bit + end_bit)) /
> >> > > >> > (2 * (priv->y_bits - 1));
> >> > > >> > - *x1 = fields->x;
> >> > > >> > - *y1 = fields->y;
> >> > > >> > + *x1 = fields->pt.x;
> >> > > >> > + *y1 = fields->pt.y;
> >> > > >> > *x2 = 2 * box_middle_x - *x1;
> >> > > >> > *y2 = 2 * box_middle_y - *y1;
> >> > > >> > }
> >> > > >> > @@ -461,6 +481,38 @@ static void alps_report_semi_mt_data(struct input_dev *dev, int num_fingers,
> >> > > >> > alps_set_slot(dev, 1, num_fingers == 2, x2, y2);
> >> > > >> > }
> >> > > >> >
> >> > > >> > +static void alps_report_coord_and_btn(struct psmouse *psmouse,
> >> > > >> > + struct alps_fields *f)
> >> > > >> > +{
> >> > > >> > + struct input_dev *dev;
> >> > > >> > +
> >> > > >> > + if (!psmouse || !f)
> >> > > >> > + return;
> >> > > >> > +
> >> > > >> > + dev = psmouse->dev;
> >> > > >> > +
> >> > > >> > + if (f->fingers) {
> >> > > >> > + input_report_key(dev, BTN_TOUCH, 1);
> >> > > >> > + alps_report_semi_mt_data(dev, f->fingers,
> >> > > >> > + f->pt_img[0].x, f->pt_img[0].y,
> >> > > >> > + f->pt_img[1].x, f->pt_img[1].y);
> >> > > >> > + input_mt_report_finger_count(dev, f->fingers);
> >> > > >> > +
> >> > > >> > + input_report_abs(dev, ABS_X, f->pt_img[0].x);
> >> > > >> > + input_report_abs(dev, ABS_Y, f->pt_img[0].y);
> >> > > >> > + input_report_abs(dev, ABS_PRESSURE, f->pt_img[0].z);
> >> > > >> > + } else {
> >> > > >> > + input_report_key(dev, BTN_TOUCH, 0);
> >> > > >> > + input_mt_report_finger_count(dev, 0);
> >> > > >> > + input_report_abs(dev, ABS_PRESSURE, 0);
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > + input_report_key(dev, BTN_LEFT, f->btn.left);
> >> > > >> > + input_report_key(dev, BTN_RIGHT, f->btn.right);
> >> > > >> > +
> >> > > >> > + input_sync(dev);
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
> >> > > >> > {
> >> > > >> > struct alps_data *priv = psmouse->private;
> >> > > >> > @@ -523,13 +575,13 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
> >> > > >> >
> >> > > >> > static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p)
> >> > > >> > {
> >> > > >> > - f->left = !!(p[3] & 0x01);
> >> > > >> > - f->right = !!(p[3] & 0x02);
> >> > > >> > - f->middle = !!(p[3] & 0x04);
> >> > > >> > + f->btn.left = !!(p[3] & 0x01);
> >> > > >> > + f->btn.right = !!(p[3] & 0x02);
> >> > > >> > + f->btn.middle = !!(p[3] & 0x04);
> >> > > >> >
> >> > > >> > - f->ts_left = !!(p[3] & 0x10);
> >> > > >> > - f->ts_right = !!(p[3] & 0x20);
> >> > > >> > - f->ts_middle = !!(p[3] & 0x40);
> >> > > >> > + f->btn.ts_left = !!(p[3] & 0x10);
> >> > > >> > + f->btn.ts_right = !!(p[3] & 0x20);
> >> > > >> > + f->btn.ts_middle = !!(p[3] & 0x40);
> >> > > >> > }
> >> > > >> >
> >> > > >> > static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p,
> >> > > >> > @@ -546,10 +598,10 @@ static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p,
> >> > > >> > ((p[2] & 0x7f) << 1) |
> >> > > >> > (p[4] & 0x01);
> >> > > >> >
> >> > > >> > - f->x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
> >> > > >> > + f->pt.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
> >> > > >> > ((p[0] & 0x30) >> 4);
> >> > > >> > - f->y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
> >> > > >> > - f->z = p[5] & 0x7f;
> >> > > >> > + f->pt.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
> >> > > >> > + f->pt.z = p[5] & 0x7f;
> >> > > >> >
> >> > > >> > alps_decode_buttons_v3(f, p);
> >> > > >> > }
> >> > > >> > @@ -573,9 +625,9 @@ static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p,
> >> > > >> > f->is_mp = !!(p[0] & 0x20);
> >> > > >> >
> >> > > >> > if (!f->is_mp) {
> >> > > >> > - f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
> >> > > >> > - f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
> >> > > >> > - f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
> >> > > >> > + f->pt.x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
> >> > > >> > + f->pt.y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
> >> > > >> > + f->pt.z = (p[0] & 4) ? 0 : p[5] & 0x7f;
> >> > > >> > alps_decode_buttons_v3(f, p);
> >> > > >> > } else {
> >> > > >> > f->fingers = ((p[0] & 0x6) >> 1 |
> >> > > >> > @@ -687,7 +739,7 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
> >> > > >> > * with x, y, and z all zero, so these seem to be flukes.
> >> > > >> > * Ignore them.
> >> > > >> > */
> >> > > >> > - if (f.x && f.y && !f.z)
> >> > > >> > + if (f.pt.x && f.pt.y && !f.pt.z)
> >> > > >> > return;
> >> > > >> >
> >> > > >> > /*
> >> > > >> > @@ -695,12 +747,12 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
> >> > > >> > * to rely on ST data.
> >> > > >> > */
> >> > > >> > if (!fingers) {
> >> > > >> > - x1 = f.x;
> >> > > >> > - y1 = f.y;
> >> > > >> > - fingers = f.z > 0 ? 1 : 0;
> >> > > >> > + x1 = f.pt.x;
> >> > > >> > + y1 = f.pt.y;
> >> > > >> > + fingers = f.pt.z > 0 ? 1 : 0;
> >> > > >> > }
> >> > > >> >
> >> > > >> > - if (f.z >= 64)
> >> > > >> > + if (f.pt.z >= 64)
> >> > > >> > input_report_key(dev, BTN_TOUCH, 1);
> >> > > >> > else
> >> > > >> > input_report_key(dev, BTN_TOUCH, 0);
> >> > > >> > @@ -709,22 +761,22 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
> >> > > >> >
> >> > > >> > input_mt_report_finger_count(dev, fingers);
> >> > > >> >
> >> > > >> > - input_report_key(dev, BTN_LEFT, f.left);
> >> > > >> > - input_report_key(dev, BTN_RIGHT, f.right);
> >> > > >> > - input_report_key(dev, BTN_MIDDLE, f.middle);
> >> > > >> > + input_report_key(dev, BTN_LEFT, f.btn.left);
> >> > > >> > + input_report_key(dev, BTN_RIGHT, f.btn.right);
> >> > > >> > + input_report_key(dev, BTN_MIDDLE, f.btn.middle);
> >> > > >> >
> >> > > >> > - if (f.z > 0) {
> >> > > >> > - input_report_abs(dev, ABS_X, f.x);
> >> > > >> > - input_report_abs(dev, ABS_Y, f.y);
> >> > > >> > + if (f.pt.z > 0) {
> >> > > >> > + input_report_abs(dev, ABS_X, f.pt.x);
> >> > > >> > + input_report_abs(dev, ABS_Y, f.pt.y);
> >> > > >> > }
> >> > > >> > - input_report_abs(dev, ABS_PRESSURE, f.z);
> >> > > >> > + input_report_abs(dev, ABS_PRESSURE, f.pt.z);
> >> > > >> >
> >> > > >> > input_sync(dev);
> >> > > >> >
> >> > > >> > if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) {
> >> > > >> > - input_report_key(dev2, BTN_LEFT, f.ts_left);
> >> > > >> > - input_report_key(dev2, BTN_RIGHT, f.ts_right);
> >> > > >> > - input_report_key(dev2, BTN_MIDDLE, f.ts_middle);
> >> > > >> > + input_report_key(dev2, BTN_LEFT, f.btn.ts_left);
> >> > > >> > + input_report_key(dev2, BTN_RIGHT, f.btn.ts_right);
> >> > > >> > + input_report_key(dev2, BTN_MIDDLE, f.btn.ts_middle);
> >> > > >> > input_sync(dev2);
> >> > > >> > }
> >> > > >> > }
> >> > > >> > @@ -916,6 +968,294 @@ static void alps_process_packet_v4(struct psmouse *psmouse)
> >> > > >> > input_sync(dev);
> >> > > >> > }
> >> > > >> >
> >> > > >> > +static bool alps_is_valid_package_v7(struct psmouse *psmouse)
> >> > > >> > +{
> >> > > >> > + if ((psmouse->pktcnt == 3) && ((psmouse->packet[2] & 0x40) != 0x40))
> >> > > >> > + return false;
> >> > > >> > + if ((psmouse->pktcnt == 4) && ((psmouse->packet[3] & 0x48) != 0x48))
> >> > > >> > + return false;
> >> > > >> > + if ((psmouse->pktcnt == 6) && ((psmouse->packet[5] & 0x40) != 0x0))
> >> > > >> > + return false;
> >> > > >> > + return true;
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static int alps_drop_unsupported_packet_v7(struct psmouse *psmouse)
> >> > > >> > +{
> >> > > >> > + struct alps_data *priv = psmouse->private;
> >> > > >> > + int drop = 1;
> >> > > >> > +
> >> > > >> > + if (priv->r.v7.pkt_id == V7_PACKET_ID_NEW ||
> >> > > >> > + priv->r.v7.pkt_id == V7_PACKET_ID_TWO ||
> >> > > >> > + priv->r.v7.pkt_id == V7_PACKET_ID_MULTI ||
> >> > > >> > + priv->r.v7.pkt_id == V7_PACKET_ID_IDLE)
> >> > > >> > + drop = 0;
> >> > > >> > +
> >> > > >> > + return drop;
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static unsigned char alps_get_packet_id_v7(char *byte)
> >> > > >> > +{
> >> > > >> > + unsigned char packet_id;
> >> > > >> > +
> >> > > >> > + if (byte[4] & 0x40)
> >> > > >> > + packet_id = V7_PACKET_ID_TWO;
> >> > > >> > + else if (byte[4] & 0x01)
> >> > > >> > + packet_id = V7_PACKET_ID_MULTI;
> >> > > >> > + else if ((byte[0] & 0x10) && !(byte[4] & 0x43))
> >> > > >> > + packet_id = V7_PACKET_ID_NEW;
> >> > > >> > + else
> >> > > >> > + packet_id = V7_PACKET_ID_IDLE;
> >> > > >> > +
> >> > > >> > + return packet_id;
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static void alps_get_finger_coordinate_v7(struct alps_abs_data *pt,
> >> > > >> > + unsigned char *pkt,
> >> > > >> > + unsigned char pkt_id)
> >> > > >> > +{
> >> > > >> > + if ((pkt_id == V7_PACKET_ID_TWO) ||
> >> > > >> > + (pkt_id == V7_PACKET_ID_MULTI) ||
> >> > > >> > + (pkt_id == V7_PACKET_ID_NEW)) {
> >> > > >> > + pt[0].x = ((pkt[2] & 0x80) << 4);
> >> > > >> > + pt[0].x |= ((pkt[2] & 0x3F) << 5);
> >> > > >> > + pt[0].x |= ((pkt[3] & 0x30) >> 1);
> >> > > >> > + pt[0].x |= (pkt[3] & 0x07);
> >> > > >> > + pt[0].y = (pkt[1] << 3) | (pkt[0] & 0x07);
> >> > > >> > +
> >> > > >> > + pt[1].x = ((pkt[3] & 0x80) << 4);
> >> > > >> > + pt[1].x |= ((pkt[4] & 0x80) << 3);
> >> > > >> > + pt[1].x |= ((pkt[4] & 0x3F) << 4);
> >> > > >> > + pt[1].y = ((pkt[5] & 0x80) << 3);
> >> > > >> > + pt[1].y |= ((pkt[5] & 0x3F) << 4);
> >> > > >> > +
> >> > > >> > + if (pkt_id == V7_PACKET_ID_TWO) {
> >> > > >> > + pt[1].x &= ~0x000F;
> >> > > >> > + pt[1].y |= 0x000F;
> >> > > >> > + } else if (pkt_id == V7_PACKET_ID_MULTI) {
> >> > > >> > + pt[1].x &= ~0x003F;
> >> > > >> > + pt[1].y &= ~0x0020;
> >> > > >> > + pt[1].y |= ((pkt[4] & 0x02) << 4);
> >> > > >> > + pt[1].y |= 0x001F;
> >> > > >> > + } else if (pkt_id == V7_PACKET_ID_NEW) {
> >> > > >> > + pt[1].x &= ~0x003F;
> >> > > >> > + pt[1].x |= (pkt[0] & 0x20);
> >> > > >> > + pt[1].y |= 0x000F;
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > + pt[0].y = 0x7FF - pt[0].y;
> >> > > >> > + pt[1].y = 0x7FF - pt[1].y;
> >> > > >> > +
> >> > > >> > + pt[0].z = (pt[0].x && pt[0].y) ? 62 : 0;
> >> > > >> > + pt[1].z = (pt[1].x && pt[1].y) ? 62 : 0;
> >> > > >> > + }
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static void alps_decode_packet_v7(struct alps_fields *f,
> >> > > >> > + unsigned char *p,
> >> > > >> > + struct psmouse *psmouse)
> >> > > >> > +{
> >> > > >> > + struct alps_data *priv = psmouse->private;
> >> > > >> > +
> >> > > >> > + priv->r.v7.pkt_id = alps_get_packet_id_v7(p);
> >> > > >> > +
> >> > > >> > + alps_get_finger_coordinate_v7(f->pt_img, p, priv->r.v7.pkt_id);
> >> > > >> > +
> >> > > >> > + priv->r.v7.rest_left = 0;
> >> > > >> > + priv->r.v7.rest_right = 0;
> >> > > >> > + priv->r.v7.additional_fingers = 0;
> >> > > >> > + priv->phy_btn = 0;
> >> > > >> > +
> >> > > >> > + if (priv->r.v7.pkt_id == V7_PACKET_ID_TWO ||
> >> > > >> > + priv->r.v7.pkt_id == V7_PACKET_ID_MULTI) {
> >> > > >> > + priv->r.v7.rest_left = (p[0] & 0x10) >> 4;
> >> > > >> > + priv->r.v7.rest_right = (p[0] & 0x20) >> 5;
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > + if (priv->r.v7.pkt_id == V7_PACKET_ID_MULTI)
> >> > > >> > + priv->r.v7.additional_fingers = p[5] & 0x03;
> >> > > >> > +
> >> > > >> > + priv->phy_btn = (p[0] & 0x80) >> 7;
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static void alps_set_each_pt_attr_v7(struct psmouse *psmouse,
> >> > > >> > + struct alps_abs_data *pt,
> >> > > >> > + struct alps_bl_pt_attr *pt_attr)
> >> > > >> > +{
> >> > > >> > + struct alps_data *priv = psmouse->private;
> >> > > >> > + unsigned int dist;
> >> > > >> > +
> >> > > >> > + if (!pt_attr->is_init_pt_got && pt->z != 0) {
> >> > > >> > + pt_attr->is_init_pt_got = 1;
> >> > > >> > + pt_attr->is_counted = 0;
> >> > > >> > + memcpy(&pt_attr->init_pt, pt, sizeof(pt_attr->init_pt));
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > + if (pt->z != 0) {
> >> > > >> > + if (pt->y < priv->resting_zone_y_min) {
> >> > > >> > + /* A finger is recognized as a non-resting finger
> >> > > >> > + if it's position is outside the resting finger zone.*/
> >> > > >> > + pt_attr->zone = ZONE_NORMAL;
> >> > > >> > + pt_attr->is_counted = 1;
> >> > > >> > + } else {
> >> > > >> > + /* A finger is recognized as a resting finger if it's
> >> > > >> > + position is inside the resting finger zone and there's
> >> > > >> > + no large movement from it's touch down position.*/
> >> > > >> > + pt_attr->zone = ZONE_RESTING;
> >> > > >> > +
> >> > > >> > + if (pt->x > priv->x_max / 2)
> >> > > >> > + pt_attr->zone |= ZONE_RIGHT_BTN;
> >> > > >> > + else
> >> > > >> > + pt_attr->zone |= ZONE_LEFT_BTN;
> >> > > >> > +
> >> > > >> > + /* A resting finger will turn to be a non-resting
> >> > > >> > + finger if it has made large movement from it's touch
> >> > > >> > + down position. A non-resting finger will never turn
> >> > > >> > + to a resting finger before it leaves the touchpad
> >> > > >> > + surface.*/
> >> > > >> > + if (pt_attr->is_init_pt_got) {
> >> > > >> > + dist = alps_pt_distance(pt, &pt_attr->init_pt);
> >> > > >> > +
> >> > > >> > + if (dist > V7_LARGE_MOVEMENT)
> >> > > >> > + pt_attr->is_counted = 1;
> >> > > >> > + }
> >> > > >> > + }
> >> > > >> > + }
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static void alps_set_pt_attr_v7(struct psmouse *psmouse,
> >> > > >> > + struct alps_fields *f)
> >> > > >> > +{
> >> > > >> > + struct alps_data *priv = psmouse->private;
> >> > > >> > + int i;
> >> > > >> > +
> >> > > >> > + switch (priv->r.v7.pkt_id) {
> >> > > >> > + case V7_PACKET_ID_TWO:
> >> > > >> > + case V7_PACKET_ID_MULTI:
> >> > > >> > + for (i = 0; i < V7_IMG_PT_NUM; i++)
> >> > > >> > + alps_set_each_pt_attr_v7(psmouse,
> >> > > >> > + &f->pt_img[i],
> >> > > >> > + &priv->pt_attr[i]);
> >> > > >> > + break;
> >> > > >> > + default:
> >> > > >> > + /*All finger attributes are cleared when packet ID is
> >> > > >> > + 'IDLE', 'New'or other unknown IDs. An 'IDLE' packet
> >> > > >> > + indicates that there's no finger and no button activity.
> >> > > >> > + A 'NEW' packet indicates the finger position in packet
> >> > > >> > + is not continues from previous packet. Such as the
> >> > > >> > + condition there's finger placed or lifted. In these cases,
> >> > > >> > + finger attributes will be reset.*/
> >> > > >> > + memset(priv->pt_attr, 0, sizeof(priv->pt_attr[0]) * 2);
> >> > > >> > + break;
> >> > > >> > + }
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static void alps_cal_output_finger_num_v7(struct psmouse *psmouse,
> >> > > >> > + struct alps_fields *f)
> >> > > >> > +{
> >> > > >> > + struct alps_data *priv = psmouse->private;
> >> > > >> > + unsigned int fn = 0;
> >> > > >> > + int i;
> >> > > >> > +
> >> > > >> > + switch (priv->r.v7.pkt_id) {
> >> > > >> > + case V7_PACKET_ID_IDLE:
> >> > > >> > + case V7_PACKET_ID_NEW:
> >> > > >> > + /*No finger is reported when packet ID is 'IDLE' or 'New'.
> >> > > >> > + An 'IDLE' packet indicates that there's no finger on touchpad.
> >> > > >> > + A 'NEW' packet indicates there's finger placed or lifted.
> >> > > >> > + Finger position of 'New' packet is not continues from the
> >> > > >> > + previous packet.*/
> >> > > >> > + fn = 0;
> >> > > >> > + break;
> >> > > >> > + case V7_PACKET_ID_TWO:
> >> > > >> > + if (f->pt_img[0].z == 0) {
> >> > > >> > + /*The first finger slot is zero when a non-resting
> >> > > >> > + finger lifted and remaining only one resting finger
> >> > > >> > + on touchpad. Hardware report the remaining resting
> >> > > >> > + finger in second slot. This resting is ignored*/
> >> > > >> > + fn = 0;
> >> > > >> > + } else if (f->pt_img[1].z == 0) {
> >> > > >> > + /* The second finger slot is zero if there's
> >> > > >> > + only one finger*/
> >> > > >> > + fn = 1;
> >> > > >> > + } else {
> >> > > >> > + /*All non-resting fingers will be counted to report*/
> >> > > >> > + fn = 0;
> >> > > >> > + for (i = 0; i < V7_IMG_PT_NUM; i++) {
> >> > > >> > + if (priv->pt_attr[i].is_counted)
> >> > > >> > + fn++;
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > + /*In the case that both fingers are
> >> > > >> > + resting fingers, report the first one*/
> >> > > >> > + if (!priv->pt_attr[0].is_counted &&
> >> > > >> > + !priv->pt_attr[1].is_counted) {
> >> > > >> > + fn = 1;
> >> > > >> > + }
> >> > > >> > + }
> >> > > >> > + break;
> >> > > >> > + case V7_PACKET_ID_MULTI:
> >> > > >> > + /*A packet ID 'MULTI' indicats that at least 3 non-resting
> >> > > >> > + finger exist.*/
> >> > > >> > + fn = 3 + priv->r.v7.additional_fingers;
> >> > > >> > + break;
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > + f->fingers = fn;
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static void alps_assign_buttons_v7(struct psmouse *psmouse,
> >> > > >> > + struct alps_fields *f)
> >> > > >> > +{
> >> > > >> > + struct alps_data *priv = psmouse->private;
> >> > > >> > +
> >> > > >> > + if (priv->phy_btn) {
> >> > > >> > + if (!priv->prev_phy_btn) {
> >> > > >> > + /* Report a right click as long as there's finger on
> >> > > >> > + right button zone. Othrewise, report a left click.*/
> >> > > >> > + if (priv->r.v7.rest_right ||
> >> > > >> > + priv->pt_attr[0].zone & ZONE_RIGHT_BTN ||
> >> > > >> > + priv->pt_attr[1].zone & ZONE_RIGHT_BTN) {
> >> > > >> > + f->btn.right = 1;
> >> > > >> > + priv->pressed_btn_bits |= RIGHT_BUTTON_BIT;
> >> > > >> > + } else {
> >> > > >> > + f->btn.left = 1;
> >> > > >> > + priv->pressed_btn_bits |= LEFT_BUTTON_BIT;
> >> > > >> > + }
> >> > > >> > + } else {
> >> > > >> > + if (priv->pressed_btn_bits & RIGHT_BUTTON_BIT)
> >> > > >> > + f->btn.right = 1;
> >> > > >> > + if (priv->pressed_btn_bits & LEFT_BUTTON_BIT)
> >> > > >> > + f->btn.left = 1;
> >> > > >> > + }
> >> > > >> > + } else {
> >> > > >> > + priv->pressed_btn_bits = 0;
> >> > > >> > + f->btn.right = 0;
> >> > > >> > + f->btn.left = 0;
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > + priv->prev_phy_btn = priv->phy_btn;
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > +static void alps_process_packet_v7(struct psmouse *psmouse)
> >> > > >> > +{
> >> > > >> > + struct alps_data *priv = psmouse->private;
> >> > > >> > + struct alps_fields f = {0};
> >> > > >> > + unsigned char *packet = psmouse->packet;
> >> > > >> > +
> >> > > >> > + priv->decode_fields(&f, packet, psmouse);
> >> > > >> > +
> >> > > >> > + if (alps_drop_unsupported_packet_v7(psmouse))
> >> > > >> > + return;
> >> > > >> > +
> >> > > >> > + alps_set_pt_attr_v7(psmouse, &f);
> >> > > >> > +
> >> > > >> > + alps_cal_output_finger_num_v7(psmouse, &f);
> >> > > >> > +
> >> > > >> > + alps_assign_buttons_v7(psmouse, &f);
> >> > > >> > +
> >> > > >> > + alps_report_coord_and_btn(psmouse, &f);
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
> >> > > >> > unsigned char packet[],
> >> > > >> > bool report_buttons)
> >> > > >> > @@ -1080,6 +1420,14 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
> >> > > >> > return PSMOUSE_BAD_DATA;
> >> > > >> > }
> >> > > >> >
> >> > > >> > + if ((priv->proto_version == ALPS_PROTO_V7 &&
> >> > > >> > + !alps_is_valid_package_v7(psmouse))) {
> >> > > >> > + psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
> >> > > >> > + psmouse->pktcnt - 1,
> >> > > >> > + psmouse->packet[psmouse->pktcnt - 1]);
> >> > > >> > + return PSMOUSE_BAD_DATA;
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > if (psmouse->pktcnt == psmouse->pktsize) {
> >> > > >> > priv->process_packet(psmouse);
> >> > > >> > return PSMOUSE_FULL_PACKET;
> >> > > >> > @@ -1192,6 +1540,22 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
> >> > > >> > return 0;
> >> > > >> > }
> >> > > >> >
> >> > > >> > +static int alps_check_valid_firmware_id(unsigned char id[])
> >> > > >> > +{
> >> > > >> > + int valid = 1;
> >> > > >> > +
> >> > > >> > + if (id[0] == 0x73)
> >> > > >> > + valid = 1;
> >> > > >> > + else if (id[0] == 0x88) {
> >> > > >> > + if ((id[1] == 0x07) ||
> >> > > >> > + (id[1] == 0x08) ||
> >> > > >> > + ((id[1] & 0xf0) == 0xB0))
> >> > > >> > + valid = 1;
> >> > > >> > + }
> >> > > >> > +
> >> > > >> > + return valid;
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > static int alps_enter_command_mode(struct psmouse *psmouse)
> >> > > >> > {
> >> > > >> > unsigned char param[4];
> >> > > >> > @@ -1201,8 +1565,7 @@ static int alps_enter_command_mode(struct psmouse *psmouse)
> >> > > >> > return -1;
> >> > > >> > }
> >> > > >> >
> >> > > >> > - if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
> >> > > >> > - param[0] != 0x73) {
> >> > > >> > + if (!alps_check_valid_firmware_id(param)) {
> >> > > >> > psmouse_dbg(psmouse,
> >> > > >> > "unknown response while entering command mode\n");
> >> > > >> > return -1;
> >> > > >> > @@ -1704,6 +2067,32 @@ error:
> >> > > >> > return ret;
> >> > > >> > }
> >> > > >> >
> >> > > >> > +static int alps_hw_init_v7(struct psmouse *psmouse)
> >> > > >> > +{
> >> > > >> > + struct ps2dev *ps2dev = &psmouse->ps2dev;
> >> > > >> > + int reg_val, ret = -1;
> >> > > >> > +
> >> > > >> > + if (alps_enter_command_mode(psmouse) ||
> >> > > >> > + alps_command_mode_read_reg(psmouse, 0xc2d9) == -1)
> >> > > >> > + goto error;
> >> > > >> > +
> >> > > >> > + if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64))
> >> > > >> > + goto error;
> >> > > >> > +
> >> > > >> > + reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4);
> >> > > >> > + if (reg_val == -1)
> >> > > >> > + goto error;
> >> > > >> > + if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02))
> >> > > >> > + goto error;
> >> > > >> > +
> >> > > >> > + alps_exit_command_mode(psmouse);
> >> > > >> > + return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
> >> > > >> > +
> >> > > >> > +error:
> >> > > >> > + alps_exit_command_mode(psmouse);
> >> > > >> > + return ret;
> >> > > >> > +}
> >> > > >> > +
> >> > > >> > /* Must be in command mode when calling this function */
> >> > > >> > static int alps_absolute_mode_v4(struct psmouse *psmouse)
> >> > > >> > {
> >> > > >> > @@ -1875,6 +2264,7 @@ static void alps_set_defaults(struct alps_data *priv)
> >> > > >> > priv->set_abs_params = alps_set_abs_params_st;
> >> > > >> > priv->x_max = 1023;
> >> > > >> > priv->y_max = 767;
> >> > > >> > + priv->slot_number = 1;
> >> > > >> > break;
> >> > > >> > case ALPS_PROTO_V3:
> >> > > >> > priv->hw_init = alps_hw_init_v3;
> >> > > >> > @@ -1883,6 +2273,7 @@ static void alps_set_defaults(struct alps_data *priv)
> >> > > >> > priv->decode_fields = alps_decode_pinnacle;
> >> > > >> > priv->nibble_commands = alps_v3_nibble_commands;
> >> > > >> > priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
> >> > > >> > + priv->slot_number = 2;
> >> > > >> > break;
> >> > > >> > case ALPS_PROTO_V4:
> >> > > >> > priv->hw_init = alps_hw_init_v4;
> >> > > >> > @@ -1890,6 +2281,7 @@ static void alps_set_defaults(struct alps_data *priv)
> >> > > >> > priv->set_abs_params = alps_set_abs_params_mt;
> >> > > >> > priv->nibble_commands = alps_v4_nibble_commands;
> >> > > >> > priv->addr_command = PSMOUSE_CMD_DISABLE;
> >> > > >> > + priv->slot_number = 2;
> >> > > >> > break;
> >> > > >> > case ALPS_PROTO_V5:
> >> > > >> > priv->hw_init = alps_hw_init_dolphin_v1;
> >> > > >> > @@ -1905,6 +2297,7 @@ static void alps_set_defaults(struct alps_data *priv)
> >> > > >> > priv->y_max = 660;
> >> > > >> > priv->x_bits = 23;
> >> > > >> > priv->y_bits = 12;
> >> > > >> > + priv->slot_number = 2;
> >> > > >> > break;
> >> > > >> > case ALPS_PROTO_V6:
> >> > > >> > priv->hw_init = alps_hw_init_v6;
> >> > > >> > @@ -1913,6 +2306,22 @@ static void alps_set_defaults(struct alps_data *priv)
> >> > > >> > priv->nibble_commands = alps_v6_nibble_commands;
> >> > > >> > priv->x_max = 2047;
> >> > > >> > priv->y_max = 1535;
> >> > > >> > + priv->slot_number = 2;
> >> > > >> > + break;
> >> > > >> > + case ALPS_PROTO_V7:
> >> > > >> > + priv->hw_init = alps_hw_init_v7;
> >> > > >> > + priv->process_packet = alps_process_packet_v7;
> >> > > >> > + priv->decode_fields = alps_decode_packet_v7;
> >> > > >> > + priv->set_abs_params = alps_set_abs_params_mt;
> >> > > >> > + priv->nibble_commands = alps_v3_nibble_commands;
> >> > > >> > + priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
> >> > > >> > + priv->x_max = 0xfff;
> >> > > >> > + priv->y_max = 0x7ff;
> >> > > >> > + priv->resting_zone_y_min = 0x654;
> >> > > >> > + priv->byte0 = 0x48;
> >> > > >> > + priv->mask0 = 0x48;
> >> > > >> > + priv->flags = 0;
> >> > > >> > + priv->slot_number = 2;
> >> > > >> > break;
> >> > > >> > }
> >> > > >> > }
> >> > > >> > @@ -1982,6 +2391,11 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
> >> > > >> > return -EIO;
> >> > > >> > else
> >> > > >> > return 0;
> >> > > >> > + } else if (ec[0] == 0x88 && (ec[1] & 0xf0) == 0xB0) {
> >> > > >> > + priv->proto_version = ALPS_PROTO_V7;
> >> > > >> > + alps_set_defaults(priv);
> >> > > >> > +
> >> > > >> > + return 0;
> >> > > >> > } else if (ec[0] == 0x88 && ec[1] == 0x08) {
> >> > > >> > priv->proto_version = ALPS_PROTO_V3;
> >> > > >> > alps_set_defaults(priv);
> >> > > >> > @@ -2045,7 +2459,7 @@ static void alps_set_abs_params_mt(struct alps_data *priv,
> >> > > >> > struct input_dev *dev1)
> >> > > >> > {
> >> > > >> > set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
> >> > > >> > - input_mt_init_slots(dev1, 2, 0);
> >> > > >> > + input_mt_init_slots(dev1, priv->slot_number, 0);
> >> > > >> > input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
> >> > > >> > input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
> >> > > >> >
> >> > > >> > diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
> >> > > >> > index 03f88b6..5d2f9ea 100644
> >> > > >> > --- a/drivers/input/mouse/alps.h
> >> > > >> > +++ b/drivers/input/mouse/alps.h
> >> > > >> > @@ -18,11 +18,36 @@
> >> > > >> > #define ALPS_PROTO_V4 4
> >> > > >> > #define ALPS_PROTO_V5 5
> >> > > >> > #define ALPS_PROTO_V6 6
> >> > > >> > +#define ALPS_PROTO_V7 7
> >> > > >> > +
> >> > > >> > +#define MAX_IMG_PT_NUM 5
> >> > > >> > +#define V7_IMG_PT_NUM 2
> >> > > >> > +
> >> > > >> > +#define ZONE_NORMAL 0x01
> >> > > >> > +#define ZONE_RESTING 0x02
> >> > > >> > +#define ZONE_LEFT_BTN 0x04
> >> > > >> > +#define ZONE_RIGHT_BTN 0x08
> >> > > >> >
> >> > > >> > #define DOLPHIN_COUNT_PER_ELECTRODE 64
> >> > > >> > #define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */
> >> > > >> > #define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */
> >> > > >> >
> >> > > >> > +/*
> >> > > >> > + * enum V7_PACKET_ID - defines the packet type for V7
> >> > > >> > + * V7_PACKET_ID_IDLE: There's no finger and no button activity.
> >> > > >> > + * V7_PACKET_ID_TWO: There's one or two non-resting fingers on touchpad
> >> > > >> > + * or there's button activities.
> >> > > >> > + * V7_PACKET_ID_MULTI: There are at least three non-resting fingers.
> >> > > >> > + * V7_PACKET_ID_NEW: The finger position in slot is not continues from
> >> > > >> > + * previous packet.
> >> > > >> > +*/
> >> > > >> > +enum V7_PACKET_ID {
> >> > > >> > + V7_PACKET_ID_IDLE,
> >> > > >> > + V7_PACKET_ID_TWO,
> >> > > >> > + V7_PACKET_ID_MULTI,
> >> > > >> > + V7_PACKET_ID_NEW,
> >> > > >> > +};
> >> > > >> > +
> >> > > >> > /**
> >> > > >> > * struct alps_model_info - touchpad ID table
> >> > > >> > * @signature: E7 response string to match.
> >> > > >> > @@ -66,15 +91,7 @@ struct alps_nibble_commands {
> >> > > >> > };
> >> > > >> >
> >> > > >> > /**
> >> > > >> > - * struct alps_fields - decoded version of the report packet
> >> > > >> > - * @x_map: Bitmap of active X positions for MT.
> >> > > >> > - * @y_map: Bitmap of active Y positions for MT.
> >> > > >> > - * @fingers: Number of fingers for MT.
> >> > > >> > - * @x: X position for ST.
> >> > > >> > - * @y: Y position for ST.
> >> > > >> > - * @z: Z position for ST.
> >> > > >> > - * @first_mp: Packet is the first of a multi-packet report.
> >> > > >> > - * @is_mp: Packet is part of a multi-packet report.
> >> > > >> > + * struct alps_btn - decoded version of the button status
> >> > > >> > * @left: Left touchpad button is active.
> >> > > >> > * @right: Right touchpad button is active.
> >> > > >> > * @middle: Middle touchpad button is active.
> >> > > >> > @@ -82,16 +99,7 @@ struct alps_nibble_commands {
> >> > > >> > * @ts_right: Right trackstick button is active.
> >> > > >> > * @ts_middle: Middle trackstick button is active.
> >> > > >> > */
> >> > > >> > -struct alps_fields {
> >> > > >> > - unsigned int x_map;
> >> > > >> > - unsigned int y_map;
> >> > > >> > - unsigned int fingers;
> >> > > >> > - unsigned int x;
> >> > > >> > - unsigned int y;
> >> > > >> > - unsigned int z;
> >> > > >> > - unsigned int first_mp:1;
> >> > > >> > - unsigned int is_mp:1;
> >> > > >> > -
> >> > > >> > +struct alps_btn {
> >> > > >> > unsigned int left:1;
> >> > > >> > unsigned int right:1;
> >> > > >> > unsigned int middle:1;
> >> > > >> > @@ -102,6 +110,69 @@ struct alps_fields {
> >> > > >> > };
> >> > > >> >
> >> > > >> > /**
> >> > > >> > + * struct alps_btn - decoded version of the X Y Z postion for ST.
> >> > > >> > + * @x: X position for ST.
> >> > > >> > + * @y: Y position for ST.
> >> > > >> > + * @z: Z position for ST.
> >> > > >> > + */
> >> > > >> > +struct alps_abs_data {
> >> > > >> > + unsigned int x;
> >> > > >> > + unsigned int y;
> >> > > >> > + unsigned int z;
> >> > > >> > +};
> >> > > >> > +
> >> > > >> > +/**
> >> > > >> > + * struct alps_fields - decoded version of the report packet
> >> > > >> > + * @fingers: Number of fingers for MT.
> >> > > >> > + * @pt: X Y Z postion for ST.
> >> > > >> > + * @pt: X Y Z postion for image MT.
> >> > > >> > + * @x_map: Bitmap of active X positions for MT.
> >> > > >> > + * @y_map: Bitmap of active Y positions for MT.
> >> > > >> > + * @first_mp: Packet is the first of a multi-packet report.
> >> > > >> > + * @is_mp: Packet is part of a multi-packet report.
> >> > > >> > + * @btn: Button activity status
> >> > > >> > + */
> >> > > >> > +struct alps_fields {
> >> > > >> > + unsigned int fingers;
> >> > > >> > + struct alps_abs_data pt;
> >> > > >> > + struct alps_abs_data pt_img[MAX_IMG_PT_NUM];
> >> > > >> > + unsigned int x_map;
> >> > > >> > + unsigned int y_map;
> >> > > >> > + unsigned int first_mp:1;
> >> > > >> > + unsigned int is_mp:1;
> >> > > >> > + struct alps_btn btn;
> >> > > >> > +};
> >> > > >> > +
> >> > > >> > +/**
> >> > > >> > + * struct v7_raw - data decoded from raw packet for V7.
> >> > > >> > + * @pkt_id: An id that specifies the type of packet.
> >> > > >> > + * @additional_fingers: Number of additional finger that is neighter included
> >> > > >> > + * in pt slot nor reflected in rest_left and rest_right flag of data packet.
> >> > > >> > + * @rest_left: There are fingers on left resting zone.
> >> > > >> > + * @rest_right: There are fingers on right resting zone.
> >> > > >> > + */
> >> > > >> > +struct v7_raw {
> >> > > >> > + unsigned char pkt_id;
> >> > > >> > + unsigned int additional_fingers;
> >> > > >> > + unsigned char rest_left;
> >> > > >> > + unsigned char rest_right;
> >> > > >> > +};
> >> > > >> > +
> >> > > >> > +/**
> >> > > >> > + * struct alps_bl_pt_attr - generic attributes of touch points for buttonless device
> >> > > >> > + * @zone: The part of touchpad that the touch point locates
> >> > > >> > + * @is_counted: The touch point is not a resting finger.
> >> > > >> > + * @is_init_pt_got: The touch down point is got.
> >> > > >> > + * @init_pt: The X Y Z position of the touch down point.
> >> > > >> > + */
> >> > > >> > +struct alps_bl_pt_attr {
> >> > > >> > + unsigned char zone;
> >> > > >> > + unsigned char is_counted;
> >> > > >> > + unsigned char is_init_pt_got;
> >> > > >> > + struct alps_abs_data init_pt;
> >> > > >> > +};
> >> > > >> > +
> >> > > >> > +/**
> >> > > >> > * struct alps_data - private data structure for the ALPS driver
> >> > > >> > * @dev2: "Relative" device used to report trackstick or mouse activity.
> >> > > >> > * @phys: Physical path for the relative device.
> >> > > >> > @@ -116,8 +187,10 @@ struct alps_fields {
> >> > > >> > * @flags: Additional device capabilities (passthrough port, trackstick, etc.).
> >> > > >> > * @x_max: Largest possible X position value.
> >> > > >> > * @y_max: Largest possible Y position value.
> >> > > >> > + * @resting_zone_y_min: Smallest Y postion value of the bottom resting zone.
> >> > > >> > * @x_bits: Number of X bits in the MT bitmap.
> >> > > >> > * @y_bits: Number of Y bits in the MT bitmap.
> >> > > >> > + * @img_fingers: Number of image fingers.
> >> > > >> > * @hw_init: Protocol-specific hardware init function.
> >> > > >> > * @process_packet: Protocol-specific function to process a report packet.
> >> > > >> > * @decode_fields: Protocol-specific function to read packet bitfields.
> >> > > >> > @@ -132,6 +205,11 @@ struct alps_fields {
> >> > > >> > * @fingers: Number of fingers from last MT report.
> >> > > >> > * @quirks: Bitmap of ALPS_QUIRK_*.
> >> > > >> > * @timer: Timer for flushing out the final report packet in the stream.
> >> > > >> > + * @v7: Data decoded from raw packet for V7
> >> > > >> > + * @phy_btn: Physical button is active.
> >> > > >> > + * @prev_phy_btn: Physical button of previous packet is active.
> >> > > >> > + * @pressed_btn_bits: Pressed positon of button zone
> >> > > >> > + * @pt_attr: Generic attributes of touch points for buttonless device.
> >> > > >> > */
> >> > > >> > struct alps_data {
> >> > > >> > struct input_dev *dev2;
> >> > > >> > @@ -145,8 +223,10 @@ struct alps_data {
> >> > > >> > unsigned char flags;
> >> > > >> > int x_max;
> >> > > >> > int y_max;
> >> > > >> > + int resting_zone_y_min;
> >> > > >> > int x_bits;
> >> > > >> > int y_bits;
> >> > > >> > + unsigned char slot_number;
> >> > > >> >
> >> > > >> > int (*hw_init)(struct psmouse *psmouse);
> >> > > >> > void (*process_packet)(struct psmouse *psmouse);
> >> > > >> > @@ -161,6 +241,15 @@ struct alps_data {
> >> > > >> > int fingers;
> >> > > >> > u8 quirks;
> >> > > >> > struct timer_list timer;
> >> > > >> > +
> >> > > >> > + /* these are used for buttonless touchpad*/
> >> > > >> > + union {
> >> > > >> > + struct v7_raw v7;
> >> > > >> > + } r;
> >> > > >> > + unsigned char phy_btn;
> >> > > >> > + unsigned char prev_phy_btn;
> >> > > >> > + unsigned char pressed_btn_bits;
> >> > > >> > + struct alps_bl_pt_attr pt_attr[MAX_IMG_PT_NUM];
> >> > > >> > };
> >> > > >> >
> >> > > >> > #define ALPS_QUIRK_TRACKSTICK_BUTTONS 1 /* trakcstick buttons in trackstick packet */
> >> > > >> > --
> >> > > >> > 1.8.3.2
> >> > > >> >
> >> > > >> --
> >> > > >> 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
> >> > > >>
> >> > >
> >> >
> >>
>
--
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
* [PATCHv2 3/3] Input: edt-ft5x06: Add DT support
From: Lothar Waßmann @ 2014-01-16 8:02 UTC (permalink / raw)
To: linux-input, Simon Budig, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Dmitry Torokhov,
Thierry Reding, Grant Likely, Jonathan Cameron, Shawn Guo,
Silvio F, Guennadi Liakhovetski, Jingoo Han, Fugang Duan,
Sachin Kamat, devicetree, linux-doc, linux-kernel
Cc: Lothar Waßmann
In-Reply-To: <1389859338-11685-1-git-send-email-LW@KARO-electronics.de>
Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
.../bindings/input/touchscreen/edt-ft5x06.txt | 29 +++++
drivers/input/touchscreen/edt-ft5x06.c | 121 +++++++++++++++++---
2 files changed, 132 insertions(+), 18 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..8d94cdc
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
@@ -0,0 +1,29 @@
+* EDT FT5x06 Multiple Touch Controller
+
+Required properties:
+- compatible: must be "edt,ft5x06"
+- reg: i2c slave address
+- interrupt-parent: the phandle for the interrupt controller
+- interrupts: touch controller interrupt
+
+Optional properties:
+- reset-gpios: the gpio pin to be used for resetting the controller
+- wake-gpios: the gpio pin to be used for waking up the controller
+
+ The following properties provide default values for the
+ corresponding parameters (see Documentation/input/edt-ft5x06.txt)
+- edt,threshold: allows setting the "click"-threshold in the range from 20 to 80.
+- edt,gain: sensitivity (0..31) (lower value -> higher sensitivity)
+- edt,offset: edge compensation (0..31)
+- edt,report-rate: report rate (3..14)
+
+Example:
+
+ edt_ft5x06@38 {
+ compatible = "edt,ft5x06";
+ reg = <0x38>;
+ 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 acb6b9f..0467591 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>
@@ -65,6 +66,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;
@@ -617,25 +622,38 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
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,
+ 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);
- mdelay(100);
+ mdelay(5);
+ gpio_set_value(tsdata->reset_pin, 1);
+ mdelay(300);
}
return 0;
@@ -675,6 +693,29 @@ 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, var, reg) { \
+ u32 val; \
+ if (of_property_read_u32(np, name, &val) == 0) { \
+ if (val >= edt_ft5x06_attr_##var.limit_low && \
+ val <= edt_ft5x06_attr_##var.limit_high) \
+ edt_ft5x06_register_write(tsdata, reg, val); \
+ else \
+ pr_err("edt_ft5x06: property %s (%u) is out of range: %u..%u", \
+ name, val, edt_ft5x06_attr_##var.limit_low, \
+ edt_ft5x06_attr_##var.limit_high); \
+ } \
+}
+
+static void edt_ft5x06_ts_get_dt_defaults(struct device_node *np,
+ struct edt_ft5x06_ts_data *tsdata)
+{
+ /* pick up defaults from the DT data */
+ EDT_GET_PROP("edt,threshold", threshold, WORK_REGISTER_THRESHOLD);
+ EDT_GET_PROP("edt,gain", gain, WORK_REGISTER_GAIN);
+ EDT_GET_PROP("edt,offset", offset, WORK_REGISTER_OFFSET);
+ EDT_GET_PROP("edt,report-rate", report_rate, WORK_REGISTER_REPORT_RATE);
+}
+
static void
edt_ft5x06_ts_get_defaults(struct edt_ft5x06_ts_data *tsdata,
const struct edt_ft5x06_platform_data *pdata)
@@ -702,6 +743,33 @@ 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;
+
+ if (!np)
+ return -ENODEV;
+
+ /*
+ * 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)
{
@@ -714,27 +782,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 = kzalloc(sizeof(*tsdata), GFP_KERNEL);
input = devm_input_allocate_device(&client->dev);
if (!input) {
dev_err(&client->dev, "failed to allocate input device.\n");
@@ -752,7 +833,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,
@@ -805,8 +890,8 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
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;
}
--
1.7.2.5
^ permalink raw reply related
* [PATCHv2 2/3] DT: Add vendor prefix for Emerging Display Technologies
From: Lothar Waßmann @ 2014-01-16 8:02 UTC (permalink / raw)
To: linux-input, Simon Budig, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Dmitry Torokhov,
Thierry Reding, Grant Likely, Jonathan Cameron, Shawn Guo,
Silvio F, Guennadi Liakhovetski, Jingoo Han, Fugang Duan,
Sachin Kamat, devicetree, linux-doc, linux-kernel
Cc: Lothar Waßmann
In-Reply-To: <1389859338-11685-1-git-send-email-LW@KARO-electronics.de>
Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
.../devicetree/bindings/vendor-prefixes.txt | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index b458760..49774c3 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -29,6 +29,7 @@ dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc.
denx Denx Software Engineering
dmo Data Modul AG
+edt Emerging Display Technologies
emmicro EM Microelectronic
epson Seiko Epson Corp.
est ESTeem Wireless Modems
--
1.7.2.5
^ permalink raw reply related
* [PATCHv2 1/3] Input: edt_ft5x06: use devm_* functions where appropriate
From: Lothar Waßmann @ 2014-01-16 8:02 UTC (permalink / raw)
To: linux-input, Simon Budig, Rob Herring, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Rob Landley, Dmitry Torokhov,
Thierry Reding, Grant Likely, Jonathan Cameron, Shawn Guo,
Silvio F, Guennadi Liakhovetski, Jingoo Han, Fugang Duan,
Sachin Kamat, devicetree, linux-doc, linux-kernel
Cc: Lothar Waßmann
In-Reply-To: <1389859338-11685-1-git-send-email-LW@KARO-electronics.de>
Simplify the error path and remove() function by using devm_*
functions for requesting gpios and irq and allocating the input
device.
Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
drivers/input/touchscreen/edt-ft5x06.c | 62 ++++++++++---------------------
1 files changed, 20 insertions(+), 42 deletions(-)
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index af0d68b..acb6b9f 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -623,8 +623,9 @@ static int edt_ft5x06_ts_reset(struct i2c_client *client,
if (gpio_is_valid(reset_pin)) {
/* this pulls reset down, enabling the low active reset */
- error = gpio_request_one(reset_pin, GPIOF_OUT_INIT_LOW,
- "edt-ft5x06 reset");
+ error = devm_gpio_request_one(&client->dev, 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",
@@ -723,7 +724,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
return error;
if (gpio_is_valid(pdata->irq_pin)) {
- error = gpio_request_one(pdata->irq_pin,
+ error = devm_gpio_request_one(&client->dev, pdata->irq_pin,
GPIOF_IN, "edt-ft5x06 irq");
if (error) {
dev_err(&client->dev,
@@ -734,11 +735,10 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
}
tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
- input = input_allocate_device();
- if (!tsdata || !input) {
- dev_err(&client->dev, "failed to allocate driver data.\n");
- error = -ENOMEM;
- goto err_free_mem;
+ input = devm_input_allocate_device(&client->dev);
+ if (!input) {
+ dev_err(&client->dev, "failed to allocate input device.\n");
+ return -ENOMEM;
}
mutex_init(&tsdata->mutex);
@@ -749,7 +749,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
error = edt_ft5x06_ts_identify(client, tsdata->name, fw_version);
if (error) {
dev_err(&client->dev, "touchscreen probe failed\n");
- goto err_free_mem;
+ return error;
}
edt_ft5x06_ts_get_defaults(tsdata, pdata);
@@ -776,27 +776,30 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0);
if (error) {
dev_err(&client->dev, "Unable to init MT slots.\n");
- goto err_free_mem;
+ return error;
}
input_set_drvdata(input, tsdata);
i2c_set_clientdata(client, tsdata);
- error = request_threaded_irq(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");
- goto err_free_mem;
+ return error;
}
error = sysfs_create_group(&client->dev.kobj, &edt_ft5x06_attr_group);
if (error)
- goto err_free_irq;
+ return error;
error = input_register_device(input);
- if (error)
- goto err_remove_attrs;
+ if (error) {
+ sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
+ return error;
+ }
edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
device_init_wakeup(&client->dev, 1);
@@ -806,40 +809,15 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
pdata->irq_pin, pdata->reset_pin);
return 0;
-
-err_remove_attrs:
- sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
-err_free_irq:
- free_irq(client->irq, tsdata);
-err_free_mem:
- input_free_device(input);
- kfree(tsdata);
-
- if (gpio_is_valid(pdata->irq_pin))
- gpio_free(pdata->irq_pin);
-
- return error;
}
static int edt_ft5x06_ts_remove(struct i2c_client *client)
{
- const struct edt_ft5x06_platform_data *pdata =
- dev_get_platdata(&client->dev);
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
edt_ft5x06_ts_teardown_debugfs(tsdata);
sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group);
- free_irq(client->irq, tsdata);
- input_unregister_device(tsdata->input);
-
- if (gpio_is_valid(pdata->irq_pin))
- gpio_free(pdata->irq_pin);
- if (gpio_is_valid(pdata->reset_pin))
- gpio_free(pdata->reset_pin);
-
- kfree(tsdata);
-
return 0;
}
--
1.7.2.5
^ permalink raw reply related
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