From patchwork Tue Dec 19 19:04:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roderick Colenbrander X-Patchwork-Id: 10123965 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 2F6086019C for ; Tue, 19 Dec 2017 19:04:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1F19D294EA for ; Tue, 19 Dec 2017 19:04:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1399B29508; Tue, 19 Dec 2017 19:04:52 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,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 27EEB294EA for ; Tue, 19 Dec 2017 19:04:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751487AbdLSTEt (ORCPT ); Tue, 19 Dec 2017 14:04:49 -0500 Received: from mail-qk0-f196.google.com ([209.85.220.196]:45683 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751291AbdLSTEs (ORCPT ); Tue, 19 Dec 2017 14:04:48 -0500 Received: by mail-qk0-f196.google.com with SMTP id o126so11357886qke.12 for ; Tue, 19 Dec 2017 11:04:47 -0800 (PST) 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; bh=7H+QzzuSexOkoGbh9qoXbuUIVoS7F2zu3U3FxUhqPlg=; b=ezUHTV8ayeWv5jkrt3EEuYQMwhInKWsg3Ut83y5ZuO95P/9wNCSsYHh/ocnaDwRxq6 bpjMWo/NcVMOpPuOa4Nrs8NMvj+KpZ2zybk5HOYJN2wcXYGbT7c8V84CmFdjR0YwCl0I pihfg65GVy2Qg6zZVP5n4goNVlL5gFPmshehXqIFmh6vuCKY3qtUL9QxwGQImsbLk36/ WHkP571IoHv4TSiNJEhwV0ubJUkIG0cam8JtNLs5BIfWosCCjk4H0BpoBbiAkfYe4fWx BV/yScO3qelU5LJ7PU50uA/G9pX3Bz/WtPeqfsRs0DE48VeKjVLL+lXV7PnJs0amahEj dztA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=7H+QzzuSexOkoGbh9qoXbuUIVoS7F2zu3U3FxUhqPlg=; b=MrqMw1UVMHQZVXrTVBNPYgWs3ZfH7A6+syrM6DBfl2R6gesg8QljPycZd9TLzNSUPY ElbhfGSgWYuH2931UlHJH/fjf1cG1xQwVcA7iE1cNT/Sg9BkPe1whFz9zc6khRu/sJ5d n6TbQapUE0CgDa59RcfJegSCQpHztFXPgat8If9GM8PhBstdJHYdFEfdIH9VN2ICA0wh zJ4gl1xJw1+OpnQLMS8EmG0jtTSJZHOkBKOnB4pzYEFTdECvnKJCSIX0Cp6ozaxpQUBc I5/qYSPcXjCYxA5lqAuh6xVjsWqm5AjJ27FIDLXsDO787r9ScTF/IdlmXTOUkHqHYa4C mdeg== X-Gm-Message-State: AKGB3mIFa+EDsi9N0uswet4BRf/A4SYg/S5/FnIin+bMGT4i7w4Gc0+G uhwYwMgZk+U0QTIdlMrWAOmZf/OX2Ec= X-Google-Smtp-Source: ACJfBosG7xx4x3xw6XvG9bRapomRyMiVH13DzERyi6+W/Art+ExclFyzITfxr3kJZfsjxDxcGA7yMg== X-Received: by 10.55.74.150 with SMTP id x144mr6476623qka.26.1513710287052; Tue, 19 Dec 2017 11:04:47 -0800 (PST) Received: from roderick.ad.gaikai.biz ([100.42.98.196]) by smtp.gmail.com with ESMTPSA id f142sm4544167qka.35.2017.12.19.11.04.45 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 19 Dec 2017 11:04:46 -0800 (PST) From: Roderick Colenbrander To: linux-input@vger.kernel.org Cc: Benjamin Tissoires , Jiri Kosina , Roderick Colenbrander Subject: [PATCH] HID: sony: Report DS4 version info through sysfs Date: Tue, 19 Dec 2017 11:04:43 -0800 Message-Id: <20171219190443.52950-1-roderick@gaikai.com> X-Mailer: git-send-email 2.13.6 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 Report DS4 firmware and hardware version through sysfs for both USB and Bluetooth. This information is important for userspace in particular for device specific quirks (e.g. in Bluetooth stacks). Signed-off-by: Roderick Colenbrander --- drivers/hid/hid-sony.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index b9dc3ac4d4aa..432d9a47cab0 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -473,6 +473,7 @@ struct motion_output_report_02 { #define DS4_FEATURE_REPORT_0x02_SIZE 37 #define DS4_FEATURE_REPORT_0x05_SIZE 41 #define DS4_FEATURE_REPORT_0x81_SIZE 7 +#define DS4_FEATURE_REPORT_0xA3_SIZE 49 #define DS4_INPUT_REPORT_0x11_SIZE 78 #define DS4_OUTPUT_REPORT_0x05_SIZE 32 #define DS4_OUTPUT_REPORT_0x11_SIZE 78 @@ -544,6 +545,8 @@ struct sony_sc { struct power_supply *battery; struct power_supply_desc battery_desc; int device_id; + unsigned fw_version; + unsigned hw_version; u8 *output_report_dmabuf; #ifdef CONFIG_SONY_FF @@ -627,6 +630,29 @@ static ssize_t ds4_store_poll_interval(struct device *dev, static DEVICE_ATTR(bt_poll_interval, 0644, ds4_show_poll_interval, ds4_store_poll_interval); +static ssize_t sony_show_firmware_version(struct device *dev, + struct device_attribute + *attr, char *buf) +{ + struct hid_device *hdev = to_hid_device(dev); + struct sony_sc *sc = hid_get_drvdata(hdev); + + return snprintf(buf, PAGE_SIZE, "0x%04x\n", sc->fw_version); +} + +static DEVICE_ATTR(firmware_version, 0444, sony_show_firmware_version, NULL); + +static ssize_t sony_show_hardware_version(struct device *dev, + struct device_attribute + *attr, char *buf) +{ + struct hid_device *hdev = to_hid_device(dev); + struct sony_sc *sc = hid_get_drvdata(hdev); + + return snprintf(buf, PAGE_SIZE, "0x%04x\n", sc->hw_version); +} + +static DEVICE_ATTR(hardware_version, 0444, sony_show_hardware_version, NULL); static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *rsize) @@ -1646,6 +1672,31 @@ static void dualshock4_calibration_work(struct work_struct *work) spin_unlock_irqrestore(&sc->lock, flags); } +static int dualshock4_get_version_info(struct sony_sc *sc) +{ + u8 *buf; + int ret; + + buf = kmalloc(DS4_FEATURE_REPORT_0xA3_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = hid_hw_raw_request(sc->hdev, 0xA3, buf, + DS4_FEATURE_REPORT_0xA3_SIZE, + HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + if (ret < 0) { + kfree(buf); + return ret; + } + + sc->hw_version = get_unaligned_le16(&buf[35]); + sc->fw_version = get_unaligned_le16(&buf[41]); + + kfree(buf); + return 0; +} + static void sixaxis_set_leds_from_id(struct sony_sc *sc) { static const u8 sixaxis_leds[10][4] = { @@ -2619,6 +2670,28 @@ static int sony_input_configured(struct hid_device *hdev, goto err_stop; } + ret = dualshock4_get_version_info(sc); + if (ret < 0) { + hid_err(sc->hdev, "Failed to get version data from Dualshock 4\n"); + goto err_stop; + } + + ret = device_create_file(&sc->hdev->dev, &dev_attr_firmware_version); + if (ret) { + /* Make zero for cleanup reasons of sysfs entries. */ + sc->fw_version = 0; + sc->hw_version = 0; + hid_err(sc->hdev, "can't create sysfs firmware_version attribute err: %d\n", ret); + goto err_stop; + } + + ret = device_create_file(&sc->hdev->dev, &dev_attr_hardware_version); + if (ret) { + sc->hw_version = 0; + hid_err(sc->hdev, "can't create sysfs hardware_version attribute err: %d\n", ret); + goto err_stop; + } + /* * The Dualshock 4 touchpad supports 2 touches and has a * resolution of 1920x942 (44.86 dots/mm). @@ -2695,6 +2768,10 @@ static int sony_input_configured(struct hid_device *hdev, */ if (sc->ds4_bt_poll_interval) device_remove_file(&sc->hdev->dev, &dev_attr_bt_poll_interval); + if (sc->fw_version) + device_remove_file(&sc->hdev->dev, &dev_attr_firmware_version); + if (sc->hw_version) + device_remove_file(&sc->hdev->dev, &dev_attr_hardware_version); if (sc->quirks & SONY_LED_SUPPORT) sony_leds_remove(sc); if (sc->quirks & SONY_BATTERY_SUPPORT) @@ -2796,6 +2873,12 @@ static void sony_remove(struct hid_device *hdev) if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) device_remove_file(&sc->hdev->dev, &dev_attr_bt_poll_interval); + if (sc->fw_version) + device_remove_file(&sc->hdev->dev, &dev_attr_firmware_version); + + if (sc->hw_version) + device_remove_file(&sc->hdev->dev, &dev_attr_hardware_version); + sony_cancel_work_sync(sc); kfree(sc->output_report_dmabuf);