From patchwork Wed Oct 5 02:58:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roderick Colenbrander X-Patchwork-Id: 9362455 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 972C3607D8 for ; Wed, 5 Oct 2016 03:00:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C78D281B7 for ; Wed, 5 Oct 2016 03:00:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7B8AD28485; Wed, 5 Oct 2016 03:00:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D3782286A2 for ; Wed, 5 Oct 2016 03:00:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753103AbcJEDAb (ORCPT ); Tue, 4 Oct 2016 23:00:31 -0400 Received: from mail-it0-f42.google.com ([209.85.214.42]:36440 "EHLO mail-it0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754530AbcJEDA3 (ORCPT ); Tue, 4 Oct 2016 23:00:29 -0400 Received: by mail-it0-f42.google.com with SMTP id 188so83378708iti.1 for ; Tue, 04 Oct 2016 20:00:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gaikai-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=HJVOYk2qsDu3h9bVetCobq8rbp5ZVMF545g5PqgQ9vM=; b=tc8uhj2RI4QVpAGiWTL32Sib6RZ1mWRSkJiqAOhbJhz9RZfeMGJ5LjHiJRUDVbnNtB sDAPuuiIG9Ju8b6eDf9EVlprBBqiBAw1OSF/jvZEXcrVNfe5aMTjO2dCd4cQdzMcWb4a p055tjU+ZSERhF7jFZAEAn2b8EoUpNnhnsYV+qRhW7JSH6TVV8ouuA0QTF+nMHfUewb1 jXyPYYKw8g+87v0p3xJLRss98tmTHnOvBUotLRt20ccBonDv2fnmZWq/Yc+ys1j1tdpC ZYyno5wdnpITDEHS3UC9b7e1my7bEah9Vk59UW1H5BiF4YNJsl3JW+tAViK0JS/fBzoU tGmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=HJVOYk2qsDu3h9bVetCobq8rbp5ZVMF545g5PqgQ9vM=; b=ZDAjxZdA9sDcGRZhHOWrUOZlpU23gkJJ5Nli1AbRn57mXcgsaab84N8jKkslCtVMK6 pvF3HRL94WfdhQDymhx6/d4XsZlRqYzQWBY6Jba3ngToBYEZHqKb0R9yglsPm2PmDlr2 j/cmEhNpp6OY21V8vdhA1xN8OamrKzTLt0mMgG9f55Kq0fCoTI3oj8OGOWjLWb8MH7bE 57iSVRfjJ2rQXYKCUlbXgeiEn+q0qdKRjVlkHUwh8ZtZhayTSi2Dt1+NtkEn/EGdwk0b dCwWdcrj1opEsIpvjeeO0lhc/nDHgvv8zpvBAWgQXcSEHs21j4R/6A8Nrgk0lNXYINcX 7J8g== X-Gm-Message-State: AA6/9RlTfr0TDgvDIfPn5wCUTmFujZYvQrxok+gv97xR0UMQrX93OPTVQkDmq2gkekRZo/Fk X-Received: by 10.36.211.215 with SMTP id n206mr25379615itg.112.1475636428949; Tue, 04 Oct 2016 20:00:28 -0700 (PDT) Received: from konan1.dev.biz ([100.42.98.197]) by smtp.gmail.com with ESMTPSA id m206sm10901281ita.13.2016.10.04.20.00.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Oct 2016 20:00:28 -0700 (PDT) From: Roderick Colenbrander To: linux-input@vger.kernel.org Cc: Benjamin Tissoires , Jiri Kosina , Tim Bird , Roderick Colenbrander Subject: [PATCH 5/5] HID: sony: Handle multiple touch events input record Date: Tue, 4 Oct 2016 19:58:58 -0700 Message-Id: <1475636338-3779-6-git-send-email-roderick@gaikai.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1475636338-3779-1-git-send-email-roderick@gaikai.com> References: <1475636338-3779-1-git-send-email-roderick@gaikai.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Roderick Colenbrander Read the touch history field in the HID descriptor and use this value to determine how many touch events to read from the report. As part of this patch, we did a first attempt of making the offset calculation code less magical. Signed-off-by: Roderick Colenbrander --- drivers/hid/hid-sony.c | 76 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 24f7d19..2387aaf 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1030,6 +1030,12 @@ struct motion_output_report_02 { #define SIXAXIS_REPORT_0xF5_SIZE 8 #define MOTION_REPORT_0x02_SIZE 49 +/* Offsets relative to USB input report (0x1). Bluetooth (0x11) requires an + * additional +2. + */ +#define DS4_INPUT_REPORT_BATTERY_OFFSET 30 +#define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33 + static DEFINE_SPINLOCK(sony_dev_list_lock); static LIST_HEAD(sony_device_list); static DEFINE_IDA(sony_device_id_allocator); @@ -1226,19 +1232,17 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) struct hid_input, list); struct input_dev *input_dev = hidinput->input; unsigned long flags; - int n, offset; + int n, m, offset, num_touch_data, max_touch_data; u8 cable_state, battery_capacity, battery_charging; - /* - * Battery and touchpad data starts at byte 30 in the USB report and - * 32 in Bluetooth report. - */ - offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32; + /* When using Bluetooth the header is 2 bytes longer, so skip these. */ + int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 0 : 2; /* - * The lower 4 bits of byte 30 contain the battery level + * The lower 4 bits of byte 30 (or 32 for BT) contain the battery level * and the 5th bit contains the USB cable state. */ + offset = data_offset + DS4_INPUT_REPORT_BATTERY_OFFSET; cable_state = (rd[offset] >> 4) & 0x01; battery_capacity = rd[offset] & 0x0F; @@ -1265,30 +1269,50 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) sc->battery_charging = battery_charging; spin_unlock_irqrestore(&sc->lock, flags); - offset += 5; - /* - * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB - * and 37 on Bluetooth. - * The first 7 bits of the first byte is a counter and bit 8 is a touch - * indicator that is 0 when pressed and 1 when not pressed. - * The next 3 bytes are two 12 bit touch coordinates, X and Y. - * The data for the second touch is in the same format and immediatly - * follows the data for the first. + * The Dualshock 4 multi-touch trackpad data starts at offset 33 on USB + * and 35 on Bluetooth. + * The first byte indicates the number of touch data in the report. + * Trackpad data starts 2 bytes later (e.g. 35 for USB). */ - for (n = 0; n < 2; n++) { - u16 x, y; + offset = data_offset + DS4_INPUT_REPORT_TOUCHPAD_OFFSET; + max_touch_data = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 3 : 4; + if (rd[offset] > 0 && rd[offset] <= max_touch_data) + num_touch_data = rd[offset]; + else + num_touch_data = 1; + offset += 1; - x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); - y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); + for (m = 0; m < num_touch_data; m++) { + /* Skip past timestamp */ + offset += 1; - input_mt_slot(input_dev, n); - input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, - !(rd[offset] >> 7)); - input_report_abs(input_dev, ABS_MT_POSITION_X, x); - input_report_abs(input_dev, ABS_MT_POSITION_Y, y); + /* + * The first 7 bits of the first byte is a counter and bit 8 is + * a touch indicator that is 0 when pressed and 1 when not + * pressed. + * The next 3 bytes are two 12 bit touch coordinates, X and Y. + * The data for the second touch is in the same format and + * immediately follows the data for the first. + */ + for (n = 0; n < 2; n++) { + u16 x, y; + bool active; + + x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); + y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); + + active = !(rd[offset] >> 7); + input_mt_slot(input_dev, n); + input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, active); - offset += 4; + if (active) { + input_report_abs(input_dev, ABS_MT_POSITION_X, x); + input_report_abs(input_dev, ABS_MT_POSITION_Y, y); + } + + offset += 4; + } } }