From patchwork Fri Jan 17 19:46:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Praznik X-Patchwork-Id: 3507231 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id F2E25C02DC for ; Fri, 17 Jan 2014 19:46:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 23AAA2017D for ; Fri, 17 Jan 2014 19:46:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1984A2017B for ; Fri, 17 Jan 2014 19:46:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752819AbaAQTqc (ORCPT ); Fri, 17 Jan 2014 14:46:32 -0500 Received: from cdptpa-omtalb.mail.rr.com ([75.180.132.120]:38467 "EHLO cdptpa-omtalb.mail.rr.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752689AbaAQTqb (ORCPT ); Fri, 17 Jan 2014 14:46:31 -0500 X-Authority-Analysis: v=2.0 cv=dq5Z+ic4 c=1 sm=0 a=N8gH7sxzIWrJto1iYJUVbg==:17 a=pZ0UG8V60s8A:10 a=nFYK-c7lA4cA:10 a=05ChyHeVI94A:10 a=Cvmq5WjI5q8A:10 a=kj9zAlcOel0A:10 a=ayC55rCoAAAA:8 a=KGjhK52YXX0A:10 a=Idpf5PHPSZkA:10 a=SexWmEnxpWH5GS2CSNQA:9 a=CjuIK1q_8ugA:10 a=N8gH7sxzIWrJto1iYJUVbg==:117 X-Cloudmark-Score: 0 X-Authenticated-User: X-Originating-IP: 24.29.232.96 Received: from [24.29.232.96] ([24.29.232.96:1209] helo=franz-virtual-machine.local) by cdptpa-oedge03.mail.rr.com (envelope-from ) (ecelerity 2.2.3.46 r()) with ESMTP id 40/C6-21884-59889D25; Fri, 17 Jan 2014 19:46:30 +0000 Date: Fri, 17 Jan 2014 14:46:26 -0500 (EST) From: Frank Praznik X-X-Sender: franz@franz-virtual-machine To: linux-input@vger.kernel.org cc: Jiri Kosina , David Herrmann Subject: [PATCH v2] HID: sony: Cache the output report for the Dualshock 4 Message-ID: User-Agent: Alpine 2.10 (DEB 1266 2009-07-14) MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Retrieve and cache the output report for the Dualshock 4 in sony_probe() instead of repeatedly walking the report list in the worker function. Signed-off-by: Frank Praznik Reviewed-by: David Herrmann --- Apply against jikos/hid.git/for-3.14/sony drivers/hid/hid-sony.c | 55 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index edffe2c..277da77 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -298,6 +298,7 @@ static const unsigned int buzz_keymap[] = { struct sony_sc { struct hid_device *hdev; struct led_classdev *leds[MAX_LEDS]; + struct hid_report *output_report; unsigned long quirks; struct work_struct state_worker; @@ -743,26 +744,9 @@ static void dualshock4_state_worker(struct work_struct *work) { struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 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; - } + struct hid_report *report = sc->output_report; + __s32 *value = report->field[0]->value; - value = report->field[0]->value; value[0] = 0x03; #ifdef CONFIG_SONY_FF @@ -822,6 +806,33 @@ static void sony_destroy_ff(struct hid_device *hdev) } #endif +static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size) +{ + struct list_head *head, *list; + struct hid_report *report; + struct hid_device *hdev = sc->hdev; + + list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; + + list_for_each(head, list) { + report = list_entry(head, struct hid_report, list); + + if (report->id == req_id) { + if (report->size < req_size) { + hid_err(hdev, "Output report 0x%02x (%i bits) is smaller than requested size (%i bits)\n", + req_id, report->size, req_size); + return -EINVAL; + } + sc->output_report = report; + return 0; + } + } + + hid_err(hdev, "Unable to locate output report 0x%02x\n", req_id); + + return -EINVAL; +} + static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; @@ -866,7 +877,11 @@ 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_USB) { - ret = 0; + /* Report 5 (31 bytes) is used to send data to the controller via USB */ + ret = sony_set_output_report(sc, 0x05, 248); + if (ret < 0) + goto err_stop; + INIT_WORK(&sc->state_worker, dualshock4_state_worker); } else { ret = 0;